phy_procedures_lte_ue.c 201 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * 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
 */
21 22 23

/*! \file phy_procedures_lte_ue.c
 * \brief Implementation of UE procedures from 36.213 LTE specifications
24
 * \author R. Knopp, F. Kaltenberger, N. Nikaein
25 26 27
 * \date 2011
 * \version 0.1
 * \company Eurecom
28
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
29 30 31 32
 * \note
 * \warning
 */

33 34
#define _GNU_SOURCE

35
#include "assertions.h"
36 37
#include "PHY/defs_UE.h"
#include "PHY/phy_extern_ue.h"
38 39
#include <sched.h>
#include "targets/RT/USER/lte-softmodem.h"
40

41 42
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
#include "SCHED_UE/sched_UE.h"
43 44 45
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"

Raymond Knopp's avatar
Raymond Knopp committed
46
//#define DEBUG_PHY_PROC
47 48 49 50 51

#ifndef PUCCH
#define PUCCH
#endif

52
#include "LAYER2/MAC/mac.h"
53 54 55
#include "UTIL/LOG/log.h"

#include "UTIL/LOG/vcd_signal_dumper.h"
56
#include "UTIL/OPT/opt.h"
57

58 59 60 61
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

62
#include "PHY/defs_UE.h"
63

64
#include "PHY/CODING/coding_extern.h"
65

66 67
#include "T.h"

68
#include "PHY/TOOLS/tools_defs.h"
69

70 71 72 73 74
#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

hbilel's avatar
hbilel committed
75
extern double cpuf;
76

77 78
void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
79

kaltenbe's avatar
kaltenbe committed
80
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
81
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
82 83
#endif

84

Raymond Knopp's avatar
Raymond Knopp committed
85
//#define UE_DEBUG_TRACE 1
86

87
void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid)
88
{
89
  unsigned int coded_bits_per_codeword;
90 91 92
  uint8_t nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;

  coded_bits_per_codeword = get_G(&ue->frame_parms,
93 94 95 96
                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Qm,
                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
97
                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
98
                                  proc->frame_rx,
99 100
          subframe,
          ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
101

102 103 104
  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
105
  /*
106 107 108 109
    write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
    write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
    write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
    write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
110
  */
111 112
  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_comp0[0],300*12,1,1);
  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->llr[0],coded_bits_per_codeword,1,0);
113

114 115
  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_mag0,300*12,1,1);
  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_magb0,300*12,1,1);
116 117
}

118
void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
119
{
120
  unsigned int coded_bits_per_codeword;
121
  uint8_t nsymb = ((ue->frame_parms.Ncp == 0) ? 14 : 12);
122

123 124 125
  coded_bits_per_codeword = get_G(&ue->frame_parms,
                                  ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
                                  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even,
126
                                  2,
127
                                  1,
128
                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
129
                                  proc->frame_rx,
130 131
          subframe,
          0);
132
  LOG_D(PHY,"[UE %d] Dumping dlsch_SI : ofdm_symbol_size %d, nsymb %d, nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
133
        ue->Mod_id,
134 135
  ue->frame_parms.ofdm_symbol_size,
  nsymb,
136 137 138
        ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
        ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs,
        ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
139
        ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
140
        coded_bits_per_codeword);
141

142
  write_output("rxsig0.m","rxs0", &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1);
143

144
  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
145 146
  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_SI[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_SI[0]->dl_ch_estimates_ext[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1);
147
  /*
148 149 150 151
    write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
    write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
    write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
    write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
152
  */
153 154
  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_SI[0]->rxdataF_comp0[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1);
  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_SI[0]->llr[0],coded_bits_per_codeword,1,0);
155

156 157
  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_SI[0]->dl_ch_mag0,300*nsymb,1,1);
  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_SI[0]->dl_ch_magb0,300*nsymb,1,1);
158
  sleep(1);
159 160 161
  exit(-1);
}

kaltenbe's avatar
kaltenbe committed
162
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
Raymond Knopp's avatar
 
Raymond Knopp committed
163 164
//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};
/*
165 166
  unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL)
  {
167

168
  int gain_dB = power_dBm - power_max_dBm;
Raymond Knopp's avatar
 
Raymond Knopp committed
169 170 171 172
  int amp_x_100;

  switch (N_RB_UL) {
  case 6:
173 174
  amp_x_100 = AMP;      // PRACH is 6 PRBS so no scale
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
175
  case 15:
176 177
  amp_x_100 = 158*AMP;  // 158 = 100*sqrt(15/6)
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
178
  case 25:
179 180
  amp_x_100 = 204*AMP;  // 204 = 100*sqrt(25/6)
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
181
  case 50:
182 183
  amp_x_100 = 286*AMP;  // 286 = 100*sqrt(50/6)
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
184
  case 75:
185 186
  amp_x_100 = 354*AMP;  // 354 = 100*sqrt(75/6)
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
187
  case 100:
188 189
  amp_x_100 = 408*AMP;  // 408 = 100*sqrt(100/6)
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
190
  default:
191 192 193
  LOG_E(PHY,"Unknown PRB size %d\n",N_RB_UL);
  mac_xface->macphy_exit("");
  break;
Raymond Knopp's avatar
 
Raymond Knopp committed
194
  }
195
  if (gain_dB < -30) {
196
  return(amp_x_100/3162);
197
  } else if (gain_dB>0)
198
  return(amp_x_100);
199
  else
200 201
  return(amp_x_100/gain_table[-gain_dB]);  // 245 corresponds to the factor sqrt(25/6)
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
202 203 204 205 206
*/

unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
{

207
  int gain_dB;
Raymond Knopp's avatar
 
Raymond Knopp committed
208 209
  double gain_lin;

210 211 212 213 214
  if (power_dBm<=power_max_dBm)
    gain_dB = power_dBm - power_max_dBm;
  else
    gain_dB = 0;

Raymond Knopp's avatar
 
Raymond Knopp committed
215
  gain_lin = pow(10,.1*gain_dB);
216 217
  AssertFatal((nb_rb >0) && (nb_rb <= N_RB_UL),"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL);
  return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)));
Raymond Knopp's avatar
 
Raymond Knopp committed
218 219
}

220 221
#endif

222
void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
223
{
224
  unsigned int coded_bits_per_codeword;
225
  uint8_t nsymb = ((ue->frame_parms.Ncp == 0) ? 14 : 12);
226

227 228 229
  coded_bits_per_codeword = get_G(&ue->frame_parms,
                                  ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
                                  ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even,
230
                                  2,
231
                                  1,
232
                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
233
                                  proc->frame_rx,
234 235
          subframe,
          0);
236
  LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
237 238 239 240
        ue->Mod_id,
        ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
        ue->dlsch_ra[eNB_id]->harq_processes[0]->mcs,
        ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
241
        ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
242
        coded_bits_per_codeword);
243

244
  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1);
245 246
  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_ra[0]->rxdataF_ext[0],2*12*ue->frame_parms.ofdm_symbol_size,1,1);
  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_ra[0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
247
  /*
248 249 250 251
    write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
    write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
    write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
    write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
252
  */
253 254
  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_ra[0]->rxdataF_comp0[0],300*nsymb,1,1);
  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_ra[0]->llr[0],coded_bits_per_codeword,1,0);
255

256 257
  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_ra[0]->dl_ch_mag0,300*nsymb,1,1);
  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1);
258
}
259

260
void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
261
{
262 263 264

  // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later
  // for more flexibility
265

266
  uint8_t i,j,k,s;
267
  PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
268

hbilel's avatar
hbilel committed
269
  //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2];
270
  for(int l=0; l<RX_NB_TH; l++) {
hbilel's avatar
hbilel committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
      for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
          for(j=0; j<2; j++) {
              //DL HARQ
              if(ue->dlsch[l][i][j]) {
                  for(k=0; k<NUMBER_OF_HARQ_PID_MAX && ue->dlsch[l][i][j]->harq_processes[k]; k++) {
                      ue->dlsch[l][i][j]->harq_processes[k]->status = SCH_IDLE;
                      for (s=0; s<10; s++) {
                          // reset ACK/NACK bit to DTX for all subframes s = 0..9
                          ue->dlsch[l][i][j]->harq_ack[s].ack = 2;
                          ue->dlsch[l][i][j]->harq_ack[s].send_harq_status = 0;
                          ue->dlsch[l][i][j]->harq_ack[s].vDAI_UL = 0xff;
                          ue->dlsch[l][i][j]->harq_ack[s].vDAI_DL = 0xff;
                      }
                  }
              }
286
          }
287

hbilel's avatar
hbilel committed
288 289 290 291 292 293
          //UL HARQ
          if(ue->ulsch[i]) {
              for(k=0; k<NUMBER_OF_HARQ_PID_MAX && ue->ulsch[i]->harq_processes[k]; k++) {
                  ue->ulsch[i]->harq_processes[k]->status = SCH_IDLE;
                  //Set NDIs for all UL HARQs to 0
                  //  ue->ulsch[i]->harq_processes[k]->Ndi = 0;
294

hbilel's avatar
hbilel committed
295 296
              }
          }
297

hbilel's avatar
hbilel committed
298 299
          // flush Msg3 buffer
          ue->ulsch_Msg3_active[i] = 0;
300

hbilel's avatar
hbilel committed
301
      }
302 303 304
  }
}

305 306
void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
307 308

  // if contention resolution fails, go back to PRACH
Raymond Knopp's avatar
 
Raymond Knopp committed
309
  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH;
hbilel's avatar
hbilel committed
310 311 312 313
  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0;
  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti = 0;
  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0;
  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti = 0;
314
  LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0, discard temporary C-RNTI and State RRC_IDLE\n",Mod_id);
315 316
}

317 318
void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
319 320 321

  int i;

322
  LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded. Set C-RNTI = Temporary C-RNTI\n",Mod_id);
323

hbilel's avatar
hbilel committed
324 325
  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0;
  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0;
326
  PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
327
  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH;
328

329
  for (i=0; i<8; i++) {
330
    if (PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]) {
331
      PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=SCH_IDLE;
hbilel's avatar
hbilel committed
332 333
      PHY_vars_UE_g[Mod_id][CC_id]->dlsch[0][eNB_index][0]->harq_processes[i]->round=0;
      PHY_vars_UE_g[Mod_id][CC_id]->dlsch[1][eNB_index][0]->harq_processes[i]->round=0;
334
      PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->subframe_scheduling_flag=0;
335
    }
336 337 338 339 340
  }


}

341 342
UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
343

Raymond Knopp's avatar
 
Raymond Knopp committed
344
  return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
345 346

}
347
void process_timing_advance_rar(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint16_t timing_advance) {
348

349
  ue->timing_advance = timing_advance*4;
350 351


352
#ifdef DEBUG_PHY_PROC
Cedric Roux's avatar
Cedric Roux committed
353 354 355
  /* TODO: fix this log, what is 'HW timing advance'? */
  /*LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->subframe_rx, ue->timing_advance);*/
  LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->subframe_rx, ue->timing_advance);
356 357 358 359
#endif

}

360
void process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance)
361
{
362

363
  //  uint32_t frame = PHY_vars_UE_g[Mod_id]->frame;
364

365
  // timing advance has Q1.5 format
366
  timing_advance = timing_advance - 31;
367

368 369
  PHY_vars_UE_g[Mod_id][CC_id]->timing_advance = PHY_vars_UE_g[Mod_id][CC_id]->timing_advance+timing_advance*4; //this is for 25RB only!!!

370

371
  LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
372

373 374 375

}

376
uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
377 378
{

379 380
  int subframe=proc->subframe_tx;

381
  LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Checking for SR TXOp (sr_ConfigIndex %d)\n",
382
        ue->Mod_id,ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,proc->frame_tx,subframe,
383
        ue->scheduling_request_config[eNB_id].sr_ConfigIndex);
384

385 386
  if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
    if ((subframe%5) == ue->scheduling_request_config[eNB_id].sr_ConfigIndex)
387
      return(1);
388 389
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 14) { // 10 ms SR period
    if (subframe==(ue->scheduling_request_config[eNB_id].sr_ConfigIndex-5))
390
      return(1);
391
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 34) { // 20 ms SR period
392
    if ((10*(proc->frame_tx&1)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-15))
393
      return(1);
394
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 74) { // 40 ms SR period
395
    if ((10*(proc->frame_tx&3)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-35))
396
      return(1);
397
  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 154) { // 80 ms SR period
398
    if ((10*(proc->frame_tx&7)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-75))
399 400 401 402 403 404
      return(1);
  }

  return(0);
}

405 406 407 408 409 410 411 412 413 414 415
uint8_t is_cqi_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
{
  int subframe = proc->subframe_tx;
  int frame    = proc->frame_tx;
  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;

  //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[eNB_id]->crnti,frame,subframe,
  //      cqirep->cqi_PMI_ConfigIndex,
  //      (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI));

416 417 418
  if (cqirep->cqi_PMI_ConfigIndex==-1)
    return(0);
  else if (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI)
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
    return(1);
  else
    return(0);
}
uint8_t is_ri_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
{


  int subframe = proc->subframe_tx;
  int frame    = proc->frame_tx;
  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;
  int log2Mri = cqirep->ri_ConfigIndex/161;
  int N_OFFSET_RI = cqirep->ri_ConfigIndex % 161;

  //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[eNB_id]->crnti,frame,subframe,
  //      cqirep->ri_ConfigIndex,
  //      (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0));
437 438 439
  if (cqirep->ri_ConfigIndex==-1)
    return(0);
  else if (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0)
440 441 442 443 444
    return(1);
  else
    return(0);
}

hbilel's avatar
hbilel committed
445 446 447 448 449 450 451 452
void compute_cqi_ri_resources(PHY_VARS_UE *ue,
                              LTE_UE_ULSCH_t *ulsch,
                              uint8_t eNB_id,
                              uint16_t rnti,
                              uint16_t p_rnti,
                              uint16_t cba_rnti,
                              uint8_t cqi_status,
                              uint8_t ri_status)
hbilel's avatar
hbilel committed
453
{
454 455
    //PHY_MEASUREMENTS *meas = &ue->measurements;
    //uint8_t transmission_mode = ue->transmission_mode[eNB_id];
hbilel's avatar
hbilel committed
456 457


458
    //LOG_I(PHY,"compute_cqi_ri_resources O_RI %d O %d uci format %d \n",ulsch->O_RI,ulsch->O,ulsch->uci_format);
hbilel's avatar
hbilel committed
459
    if (cqi_status == 1 || ri_status == 1)
hbilel's avatar
hbilel committed
460
    {
hbilel's avatar
hbilel committed
461
        ulsch->O = 4;
hbilel's avatar
hbilel committed
462 463 464
    }
}

465
void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS)
hbilel's avatar
hbilel committed
466
{
467

468 469 470 471 472 473 474 475
  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
  int frame_tx    = proc->frame_tx;
  int subframe_tx = proc->subframe_tx;
  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
  uint16_t srsPeriodicity;
  uint16_t srsOffset;
  uint8_t is_pucch2_subframe = 0;
  uint8_t is_sr_an_subframe  = 0;
hbilel's avatar
hbilel committed
476 477 478

  // check for SRS opportunity
  pSoundingrs_ul_config_dedicated->srsUeSubframe   = 0;
479
  pSoundingrs_ul_config_dedicated->srsCellSubframe = isSubframeSRS;
hbilel's avatar
hbilel committed
480

481
  if (isSubframeSRS) {
482
    LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup);
fnabet's avatar
fnabet committed
483 484
      if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup)
      {
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
          compute_srs_pos(frame_parms->frame_type, pSoundingrs_ul_config_dedicated->srs_ConfigIndex, &srsPeriodicity, &srsOffset);

          LOG_D(PHY," srsPeriodicity: %d srsOffset: %d isSubframeSRS %d \n",srsPeriodicity,srsOffset,isSubframeSRS);

          // transmit SRS if the four following constraints are respected:
          // - UE is configured to transmit SRS
          // - SRS are configured in current subframe
          // - UE is configured to send SRS in this subframe

          // 36.213 8.2
          // 1- A UE shall not transmit SRS whenever SRS and PUCCH format 2/2a/2b transmissions happen to coincide in the same subframe
          // 2- A UE shall not transmit SRS whenever SRS transmit
          //    on and PUCCH transmission carrying ACK/NACK and/or
          //    positive SR happen to coincide in the same subframe if the parameter
          //    Simultaneous-AN-and-SRS is FALSE

          // check PUCCH format 2/2a/2b transmissions
          is_pucch2_subframe = is_cqi_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0);
          is_pucch2_subframe = (is_ri_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0)) || is_pucch2_subframe;

          // check ACK/SR transmission
          if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == FALSE)
          {
              if(is_SR_TXOp(ue,proc,eNB_id))
              {
                  uint32_t SR_payload = 0;
                  if (ue->mac_enabled==1)
                  {
                      int Mod_id = ue->Mod_id;
                      int CC_id = ue->CC_id;
515
                      // Panos: Substitute call to ue_get_SR() with the filled ue_SR_config->SR_payload (0, or 1).
516 517 518 519
                      SR_payload = ue_get_SR(Mod_id,
					     CC_id,
					     frame_tx,
					     eNB_id,
520
					     ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,
521
					     subframe_tx); // subframe used for meas gap
522 523 524 525 526 527 528 529

                      if (SR_payload > 0)
                          is_sr_an_subframe = 1;
                  }
              }

              uint8_t pucch_ack_payload[2];
              if (get_ack(&ue->frame_parms,
530
                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
hbilel's avatar
hbilel committed
531
                      subframe_tx,proc->subframe_rx,pucch_ack_payload,0) > 0)
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
              {
                  is_sr_an_subframe = 1;
              }
          }

          // check SRS UE opportunity
          if( isSubframeSRS  &&
                  (((10*frame_tx+subframe_tx) % srsPeriodicity) == srsOffset)
          )
          {
              if ((is_pucch2_subframe == 0) && (is_sr_an_subframe == 0))
              {
                  pSoundingrs_ul_config_dedicated->srsUeSubframe = 1;
                  ue->ulsch[eNB_id]->srs_active   = 1;
                  ue->ulsch[eNB_id]->Nsymb_pusch  = 12-(frame_parms->Ncp<<1)- ue->ulsch[eNB_id]->srs_active;
              }
              else
              {
                  LOG_I(PHY,"DROP UE-SRS-TX for this subframe %d.%d: collision with PUCCH2 or SR/AN: PUCCH2-occasion: %d, SR-AN-occasion[simSRS-SR-AN %d]: %d  \n", frame_tx, subframe_tx, is_pucch2_subframe, frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, is_sr_an_subframe);
              }
          }
fnabet's avatar
fnabet committed
553
      }
fnabet's avatar
fnabet committed
554
      LOG_D(PHY," srsCellSubframe: %d, srsUeSubframe: %d, Nsymb-pusch: %d \n", pSoundingrs_ul_config_dedicated->srsCellSubframe, pSoundingrs_ul_config_dedicated->srsUeSubframe, ue->ulsch[eNB_id]->Nsymb_pusch);
hbilel's avatar
hbilel committed
555 556 557
  }
}

558

Raymond Knopp's avatar
Raymond Knopp committed
559 560 561 562 563 564 565 566 567 568 569 570
void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id)
{

  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;
  int cqi_PMI_ConfigIndex = cqirep->cqi_PMI_ConfigIndex;

  if (ue->frame_parms.frame_type == FDD) {
    if (cqi_PMI_ConfigIndex <= 1) {        // 2 ms CQI_PMI period
      cqirep->Npd = 2;
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex;
    } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period
      cqirep->Npd = 5;
571
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-2;
Raymond Knopp's avatar
Raymond Knopp committed
572 573
    } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
      cqirep->Npd = 10;
574
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-7;
Raymond Knopp's avatar
Raymond Knopp committed
575 576
    } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
      cqirep->Npd = 20;
577
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-17;
Raymond Knopp's avatar
Raymond Knopp committed
578 579
    } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
      cqirep->Npd = 40;
580
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-37;
Raymond Knopp's avatar
Raymond Knopp committed
581 582
    } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
      cqirep->Npd = 80;
583
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-77;
Raymond Knopp's avatar
Raymond Knopp committed
584 585
    } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
      cqirep->Npd = 160;
586
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-157;
Raymond Knopp's avatar
Raymond Knopp committed
587 588
    }
    else if (cqi_PMI_ConfigIndex > 317) {
589

Raymond Knopp's avatar
Raymond Knopp committed
590
      if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period
591
  cqirep->Npd = 32;
592
      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-318;
Raymond Knopp's avatar
Raymond Knopp committed
593 594
      }
      else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period
595 596
  cqirep->Npd = 64;
  cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
Raymond Knopp's avatar
Raymond Knopp committed
597 598
      }
      else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period
599 600 601
  cqirep->Npd = 128;
  cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
      }
Raymond Knopp's avatar
Raymond Knopp committed
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
    }
  }
  else { // TDD
   if (cqi_PMI_ConfigIndex == 0) {        // all UL subframes
     cqirep->Npd = 1;
     cqirep->N_OFFSET_CQI = 0;
   } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period
     cqirep->Npd = 5;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-1;
   } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
     cqirep->Npd = 10;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-6;
   } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
     cqirep->Npd = 20;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-16;
   } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
     cqirep->Npd = 40;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-36;
   } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
     cqirep->Npd = 80;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-76;
   } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
     cqirep->Npd = 160;
     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-156;
   }
  }
}

630 631 632 633 634
PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
                             lte_prefix_type_t cyclic_prefix_type,
                             uint8_t SR_payload,
                             uint8_t nb_cw,
                             uint8_t cqi_status,
hbilel's avatar
hbilel committed
635 636
                             uint8_t ri_status,
                             uint8_t bundling_flag)
637 638 639 640 641 642 643
{
  if((cqi_status == 0) && (ri_status==0))
  {
      // PUCCH Format 1 1a 1b
      // 1- SR only ==> PUCCH format 1
      // 2- 1bit Ack/Nack with/without SR  ==> PUCCH format 1a
      // 3- 2bits Ack/Nack with/without SR ==> PUCCH format 1b
hbilel's avatar
hbilel committed
644
      if((nb_cw == 1)&&(bundling_flag==bundling))
645 646 647
      {
          return pucch_format1a;
      }
hbilel's avatar
hbilel committed
648 649 650 651
      if((nb_cw == 1)&&(bundling_flag==multiplexing))
      {
          return pucch_format1b;
      }
652 653 654 655 656 657
      if(nb_cw == 2)
      {
          return pucch_format1b;
      }
      if(SR_payload == 1)
      {
gabrielC's avatar
gabrielC committed
658 659
          return pucch_format1;
          /*
660 661 662 663 664
          if (frame_type == FDD) {
              return pucch_format1;
          } else if (frame_type == TDD) {
              return pucch_format1b;
          } else {
665
              AssertFatal(1==0,"Unknown frame_type");
gabrielC's avatar
gabrielC committed
666
          }*/
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
      }
  }
  else
  {
      // PUCCH Format 2 2a 2b
      // 1- CQI only or RI only  ==> PUCCH format 2
      // 2- CQI or RI + 1bit Ack/Nack for normal CP  ==> PUCCH format 2a
      // 3- CQI or RI + 2bits Ack/Nack for normal CP ==> PUCCH format 2b
      // 4- CQI or RI + Ack/Nack for extended CP ==> PUCCH format 2
      if(nb_cw == 0)
      {
          return pucch_format2;
      }
      if(cyclic_prefix_type == NORMAL)
      {
          if(nb_cw == 1)
          {
              return pucch_format2a;
          }
          if(nb_cw == 2)
          {
              return pucch_format2b;
          }
      }
      else
      {
          return pucch_format2;
      }
  }
hbilel's avatar
hbilel committed
696
  return pucch_format1a;
697
}
698
uint16_t get_n1_pucch(PHY_VARS_UE *ue,
699
          UE_rxtx_proc_t *proc,
700
                      harq_status_t *harq_ack,
701 702 703 704
                      uint8_t eNB_id,
                      uint8_t *b,
                      uint8_t SR)
{
705

706
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
707
  uint8_t nCCE0,nCCE1,nCCE2,nCCE3,harq_ack1,harq_ack0,harq_ack3,harq_ack2;
708
  ANFBmode_t bundling_flag;
gabrielC's avatar
gabrielC committed
709
  uint16_t n1_pucch0=0,n1_pucch1=0,n1_pucch2=0,n1_pucch3=0,n1_pucch_inter;
710 711
  static uint8_t candidate_dl[9]; // which downlink(s) the current ACK/NACK is associating to
  uint8_t last_dl=0xff; // the last downlink with valid DL-DCI. for calculating the PUCCH resource index
712 713
  int sf;
  int M;
714
  uint8_t ack_counter=0;
715
  // clear this, important for case where n1_pucch selection is not used
716
  int subframe=proc->subframe_tx;
717

718
  ue->pucch_sel[subframe] = 0;
719 720 721

  if (frame_parms->frame_type == FDD ) { // FDD
    sf = (subframe<4)? subframe+6 : subframe-4;
722
    LOG_D(PHY,"n1_pucch_UE: subframe %d, nCCE %d\n",sf,ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[sf]);
723 724

    if (SR == 0)
725
      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[sf]);
726
    else
727
      return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
728
  } else {
729

730
    bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
731
#ifdef DEBUG_PHY_PROC
732 733

    if (bundling_flag==bundling) {
gabrielC's avatar
gabrielC committed
734
      LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR,
735
            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
736
    } else {
gabrielC's avatar
gabrielC committed
737
      LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR,
738
            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
739
    }
740

741
#endif
742

743 744 745 746 747
    switch (frame_parms->tdd_config) {
    case 1:  // DL:S:UL:UL:DL:DL:S:UL:UL:DL

      harq_ack0 = 2; // DTX
      M=1;
748

749
      // This is the offset for a particular subframe (2,3,4) => (0,2,4)
750 751 752
      if (subframe == 2) {  // ACK subframes 5,6
        candidate_dl[0] = 6;
        candidate_dl[1] = 5;
753 754
        M=2;
      } else if (subframe == 3) { // ACK subframe 9
755 756 757 758
        candidate_dl[0] = 9;
      } else if (subframe == 7) { // ACK subframes 0,1
        candidate_dl[0] = 1;
        candidate_dl[1] = 0;
759 760
        M=2;
      } else if (subframe == 8) { // ACK subframes 4
761
        candidate_dl[0] = 4;
762
      } else {
763
        LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal tx-subframe %d for tdd_config %d\n",
764
              ue->Mod_id,proc->frame_tx,subframe,frame_parms->tdd_config);
765
        return(0);
766 767
      }

768 769 770 771 772 773 774 775 776
      // checking which downlink candidate is the last downlink with valid DL-DCI
      int k;
      for (k=0;k<M;k++) {
        if (harq_ack[candidate_dl[k]].send_harq_status>0) {
          last_dl = candidate_dl[k];
          break;
        }
      }
      if (last_dl >= 10) {
777 778
        LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal rx-subframe %d (tx-subframe %d) for tdd_config %d\n",
              ue->Mod_id,proc->frame_tx,last_dl,subframe,frame_parms->tdd_config);
779 780 781 782 783 784 785
        return (0);
      }

      LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch0 from last_dl=%d\n",
          proc->frame_tx%1024,
          proc->subframe_tx,
          last_dl);
786 787

      // i=0
788
      nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[last_dl];
789
      n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
790

791
      harq_ack0 = b[0];
792 793

      if (harq_ack0!=2) {  // DTX
794 795 796 797
        if (frame_parms->frame_type == FDD ) {
          if (SR == 0) {  // last paragraph pg 68 from 36.213 (v8.6), m=0
            b[0]=(M==2) ? 1-harq_ack0 : harq_ack0;
            b[1]=harq_ack0;   // in case we use pucch format 1b (subframes 2,7)
798
          ue->pucch_sel[subframe] = 0;
799 800 801
            return(n1_pucch0);
          } else { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213)
            b[0]=harq_ack0;
802
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
803 804 805 806 807 808 809 810 811 812 813 814
          }
        } else {
          if (SR == 0) {
            b[0] = harq_ack0;
            b[1] = harq_ack0;
            ue->pucch_sel[subframe] = 0;
            return(n1_pucch0);
          } else {
            b[0] = harq_ack0;
            b[1] = harq_ack0;
            return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
          }
815
        }
816 817 818 819
      }


      break;
820

821 822 823 824 825 826 827
    case 3:  // DL:S:UL:UL:UL:DL:DL:DL:DL:DL
      // in this configuration we have M=2 from pg 68 of 36.213 (v8.6)
      // Note: this doesn't allow using subframe 1 for PDSCH transmission!!! (i.e. SF 1 cannot be acked in SF 2)
      // set ACK/NAKs to DTX
      harq_ack1 = 2; // DTX
      harq_ack0 = 2; // DTX
      // This is the offset for a particular subframe (2,3,4) => (0,2,4)
828
      last_dl = (subframe-2)<<1;
829
      // i=0
830
      nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[5+last_dl];
831
      n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
832
      // i=1
833
      nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(6+last_dl)%10];
834
      n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
835 836

      // set ACK/NAK to values if not DTX
837 838
      if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
        harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].ack;
839

840 841
      if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
        harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].ack;
842

843 844 845 846 847
      LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d\n",
                                      proc->frame_tx%1024,
                                      proc->subframe_tx,
                                      nCCE0,n1_pucch0,
                                      nCCE1,n1_pucch1);
848 849

      if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed
850 851 852 853 854 855 856 857 858

        if ((bundling_flag==bundling)&&(SR == 0)) {  // This is for bundling without SR,
          // n1_pucch index takes value of smallest element in set {0,1}
          // i.e. 0 if harq_ack0 is not DTX, otherwise 1
          b[0] = harq_ack1;

          if (harq_ack0!=2)
            b[0]=b[0]&harq_ack0;

859
          ue->pucch_sel[subframe] = 1;
860 861 862 863 864 865 866 867 868 869
          return(n1_pucch1);

        } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1
          if (harq_ack0 == 2)
            harq_ack0 = 0;

          b[1] = harq_ack0;
          b[0] = (harq_ack0!=harq_ack1)?0:1;

          if ((harq_ack0 == 1) && (harq_ack1 == 0)) {
870
            ue->pucch_sel[subframe] = 0;
871 872
            return(n1_pucch0);
          } else {
873
            ue->pucch_sel[subframe] = 1;
874 875 876 877 878 879 880 881 882
            return(n1_pucch1);
          }
        } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213)
          // this should be number of ACKs (including
          if (harq_ack0 == 2)
            harq_ack0 = 0;

          b[0]= harq_ack1 | harq_ack0;
          b[1]= harq_ack1 ^ harq_ack0;
883
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
884 885 886 887
        }
      } else if (harq_ack0!=2) { // n-7  // subframe 5,7,9 only is to be ACK/NAKed
        if ((bundling_flag==bundling)&&(SR == 0)) {  // last paragraph pg 68 from 36.213 (v8.6), m=0
          b[0]=harq_ack0;
888
          ue->pucch_sel[subframe] = 0;
889 890 891 892
          return(n1_pucch0);
        } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1 with i=1 set to DTX
          b[0] = harq_ack0;
          b[1] = 1-b[0];
893
          ue->pucch_sel[subframe] = 0;
894 895 896 897
          return(n1_pucch0);
        } else if (SR==1) { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213)
          b[0]=harq_ack0;
          b[1]=b[0];
898
          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
899
        }
900
      }
901

902 903
      break;

904 905 906 907 908 909 910 911 912 913 914 915
    case 4:  // DL:S:UL:UL:DL:DL:DL:DL:DL:DL
          // in this configuration we have M=4 from pg 68 of 36.213 (v8.6)
          // Note: this doesn't allow using subframe 1 for PDSCH transmission!!! (i.e. SF 1 cannot be acked in SF 2)
          // set ACK/NAKs to DTX
          harq_ack3 = 2; // DTX
          harq_ack2 = 2; // DTX
          harq_ack1 = 2; // DTX
          harq_ack0 = 2; // DTX
          // This is the offset for a particular subframe (2,3,4) => (0,2,4)
          //last_dl = (subframe-2)<<1;
          if (subframe == 2) {
          // i=0
916 917
          //nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[2+subframe];
          nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(8+subframe)%10];
918 919
          n1_pucch0 = 2*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
          // i=1
920
          nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[2+subframe];
921 922
          n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
          // i=2
923
          nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(8+subframe)%10];
924

925 926
          n1_pucch2 = 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
          // i=3
927
          //nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(9+subframe)%10];
928 929 930
          //n1_pucch3 = get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN;

          // set ACK/NAK to values if not DTX
931 932
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(8+subframe)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
            harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(8+subframe)%10].ack;
933

934 935
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[2+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
            harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[2+subframe].ack;
936

937 938
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[3+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
            harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[3+subframe].ack;
939

940 941
          //if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(9+subframe)%10].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
            //harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(9+subframe)%10].ack;
942 943 944 945 946 947 948 949
          //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d cce2=%d n1_pucch2=%d\n",
          //                      proc->frame_tx%1024,
          //                      proc->subframe_tx,
          //                      nCCE0,n1_pucch0,
          //                      nCCE1,n1_pucch1, nCCE2, n1_pucch2);
          }else if (subframe == 3) {
          // i=0

950
          nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[4+subframe];
951 952
          n1_pucch0 = 3*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
          // i=1
953
          nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[5+subframe];
954 955
          n1_pucch1 = 2*get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
          // i=2
956
          nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(6+subframe)];
957 958
          n1_pucch2 = get_Np(frame_parms->N_RB_DL,nCCE2,0) + 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
          // i=3
959
          nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(3+subframe)];
960 961 962
          n1_pucch3 = 3*get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN;

          // set ACK/NAK to values if not DTX
963 964
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
          harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].ack;
965

966 967
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
          harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].ack;
968

969 970
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
          harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].ack;
971

972 973
          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
          harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].ack;
974 975 976 977 978 979 980 981 982 983
          }

          //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d harq_ack0=%d cce1=%d n1_pucch1=%d harq_ack1=%d cce2=%d n1_pucch2=%d harq_ack2=%d cce3=%d n1_pucch3=%d harq_ack3=%d bundling_flag=%d\n",
          //                                proc->frame_tx%1024,
          //                                proc->subframe_tx,
          //                                nCCE0,n1_pucch0,harq_ack0,
          //                                nCCE1,n1_pucch1,harq_ack1, nCCE2, n1_pucch2, harq_ack2,
          //                                nCCE3, n1_pucch3, harq_ack3, bundling_flag);

          if ((bundling_flag==bundling)&&(SR == 0)) {  // This is for bundling without SR,
984 985 986 987 988 989 990 991
             b[0] = 1;
             ack_counter = 0;

             if ((harq_ack3!=2) ) {
                b[0] = b[0]&harq_ack3;
                n1_pucch_inter = n1_pucch3;
                ack_counter ++;
             }
992
             if ((harq_ack0!=2) ) {
993
                b[0] = b[0]&harq_ack0;
994
                n1_pucch_inter = n1_pucch0;
995
                ack_counter ++;
996 997 998 999
             }
             if ((harq_ack1!=2) ) {
                b[0] = b[0]&harq_ack1;
                n1_pucch_inter = n1_pucch1;
1000
                ack_counter ++;
1001 1002 1003 1004
             }
             if ((harq_ack2!=2) ) {
                b[0] = b[0]&harq_ack2;
                n1_pucch_inter = n1_pucch2;
1005
                ack_counter ++;
1006 1007
             }

1008 1009 1010 1011
             if (ack_counter == 0)
                 b[0] = 0;

             /*if (subframe == 3) {
1012 1013
                n1_pucch_inter = n1_pucch2;
             } else if (subframe == 2) {
1014 1015
                n1_pucch_inter = n1_pucch1;
             }*/
1016

gabrielC's avatar
gabrielC committed
1017
             //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch n1_pucch_inter=%d  b[0]=%d b[1]=%d \n",
1018 1019
             //                                           proc->frame_tx%1024,
             //                                           proc->subframe_tx,n1_pucch_inter,
gabrielC's avatar
gabrielC committed
1020
             //                                           b[0],b[1]);
1021 1022 1023 1024 1025

              return(n1_pucch_inter);

            } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1

hbilel's avatar
hbilel committed
1026 1027
             if (subframe == 3) {
                 LOG_I(PHY, "sbuframe=%d \n",subframe);
1028 1029
              if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
                b[0] = 1;
hbilel's avatar
hbilel committed
1030
                b[1] = 1;
1031 1032 1033 1034 1035 1036 1037
                return(n1_pucch1);
              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
                b[0] = 1;
                b[1] = 0;
                return(n1_pucch1);
              } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 0) && (harq_ack3 == 2)) {
                b[0] = 1;
hbilel's avatar
hbilel committed
1038
                b[1] = 1;
1039 1040
                return(n1_pucch2);
              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
hbilel's avatar
hbilel committed
1041 1042
                b[0] = 1;
                b[1] = 0;
1043 1044
                return(n1_pucch1);
              } else if ((harq_ack0 == 0) && (harq_ack1 == 2) && (harq_ack2 == 2) && (harq_ack3 == 2)) {
hbilel's avatar
hbilel committed
1045 1046
                b[0] = 1;
                b[1] = 0;
1047 1048
                return(n1_pucch0);
              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
hbilel's avatar
hbilel committed
1049 1050
                b[0] = 1;
                b[1] = 0;
1051 1052 1053 1054 1055 1056 1057
                return(n1_pucch1);
              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
                b[0] = 0;
                b[1] = 1;
                return(n1_pucch3);
              } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 0)) {
                b[0] = 1;
hbilel's avatar
hbilel committed
1058
                b[1] = 1;
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
                return(n1_pucch3);
              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
                b[0] = 0;
                b[1] = 1;
                return(n1_pucch2);
              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
                b[0] = 0;
                b[1] = 1;
                return(n1_pucch0);
              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
                b[0] = 0;
                b[1] = 1;
                return(n1_pucch0);
              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
                b[0] = 0;
                b[1] = 1;
                return(n1_pucch3);
              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 0) && (harq_ack2 == 2) && (harq_ack3 == 2)) {
                b[0] = 0;
                b[1] = 0;
                return(n1_pucch1);
              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
                b[0] = 1;
                b[1] = 0;
                return(n1_pucch2);
              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
                b[0] = 1;
                b[1] = 0;
                return(n1_pucch3);
              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
                b[0] = 0;
                b[1] = 1;
                return(n1_pucch1);
              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
                b[0] = 0;
                b[1] = 1;
                return(n1_pucch3);
              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
                b[0] = 0;
                b[1] = 0;
                return(n1_pucch2);
              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack3 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
                b[0] = 0;
                b[1] = 0;
                return(n1_pucch3);
                }
hbilel's avatar
hbilel committed
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
             } else if (subframe == 2) {
                if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1)) {
                 b[0] = 1;
                 b[1] = 1;
                 return(n1_pucch2);
               } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
                 b[0] = 1;
                 b[1] = 1;
                 return(n1_pucch1);
               } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) {
                 b[0] = 1;
                 b[1] = 1;
                 return(n1_pucch0);
               } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
                 b[0] = 0;
                 b[1] = 1;
                 return(n1_pucch0);
               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1)) {
                 b[0] = 1;
                 b[1] = 0;
                 return(n1_pucch2);
               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
                 b[1] = 0;
                 b[0] = 0;
                 return(n1_pucch1);
               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) {
                 b[0] = 0;
                 b[1] = 0;
                 return(n1_pucch2);
               } else if ((harq_ack0 == 2) && (harq_ack1 == 2) && (harq_ack2 == 0)) {
                 b[0] = 0;
                 b[1] = 1;
                 return(n1_pucch2);
               } else if ((harq_ack0 == 2) && (harq_ack1 == 0) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
                 b[0] = 1;
                 b[1] = 0;
                 return(n1_pucch1);
               } else if ((harq_ack0 == 0) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
                 b[0] = 1;
                 b[1] = 0;
                 return(n1_pucch0);
               }
1147

hbilel's avatar
hbilel committed
1148
             }
1149 1150
            } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213)
              // this should be number of ACKs (including
1151
              ack_counter = 0;
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
              if (harq_ack0==1)
                 ack_counter ++;
              if (harq_ack1==1)
                 ack_counter ++;
              if (harq_ack2==1)
                 ack_counter ++;
              if (harq_ack3==1)
                 ack_counter ++;

            switch (ack_counter) {
               case 0:
                 b[0] = 0;
                 b[1] = 0;
               break;

               case 1:
                 b[0] = 1;
                 b[1] = 1;
               break;

               case 2:
                 b[0] = 1;
                 b[1] = 0;
               break;

               case 3:
                 b[0] = 0;
                 b[1] = 1;
               break;

               case 4:
                 b[0] = 1;
                 b[1] = 1;
               break;
            }

            ack_counter = 0;
            return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
          }

          break;

1194
    }  // switch tdd_config
1195
  }
1196

Cedric Roux's avatar
Cedric Roux committed
1197
  LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, exit without proper return\n", ue->Mod_id, proc->frame_tx);
1198 1199 1200 1201
  return(-1);
}


hbilel's avatar
hbilel committed
1202
void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empty_subframe) {
1203

1204
  int aa;
1205
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
1206

1207 1208 1209 1210
  int nsymb;
  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  int ulsch_start;
1211
  int overflow=0;
1212
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1213
  int k,l;
1214
  int dummy_tx_buffer[frame_parms->samples_per_tti] __attribute__((aligned(16)));
1215 1216
#endif

1217
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN);
gabrielC's avatar
gabrielC committed
1218
#if UE_TIMING_TRACE
1219
  start_meas(&ue->ofdm_mod_stats);
gabrielC's avatar
gabrielC committed
1220
#endif
1221
  nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
1222

1223 1224
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case
  ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti-
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236
         ue->hw_timing_advance-
         ue->timing_advance-
         ue->N_TA_offset+5);
  //LOG_E(PHY,"ul-signal [subframe: %d, ulsch_start %d]\n",subframe_tx, ulsch_start);

  if(ulsch_start < 0)
      ulsch_start = ulsch_start + (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);

  if (ulsch_start > (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti))
      ulsch_start = ulsch_start % (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);

  //LOG_E(PHY,"ul-signal [subframe: %d, ulsch_start %d]\n",subframe_tx, ulsch_start);
1237 1238 1239
#else //this is the normal case
  ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance;
#endif //else EXMIMO
hbilel's avatar
hbilel committed
1240

1241
//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
hbilel's avatar
hbilel committed
1242 1243 1244 1245 1246 1247
  if (empty_subframe)
  {
//#if 1
      overflow = ulsch_start - 9*frame_parms->samples_per_tti;
      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {

1248
          if (overflow > 0)
1249 1250 1251 1252 1253 1254 1255 1256
     {
       memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow));
       memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
     }
     else
     {
       memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti);
     }
hbilel's avatar
hbilel committed
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
      }
/*#else
      overflow = ulsch_start - 9*frame_parms->samples_per_tti;
      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
          for (k=ulsch_start; k<cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti); k++) {
              ((short*)ue->common_vars.txdata[aa])[2*k] = 0;
              ((short*)ue->common_vars.txdata[aa])[2*k+1] = 0;
          }

          for (k=0; k<overflow; k++) {
              ((short*)ue->common_vars.txdata[aa])[2*k] = 0;
              ((short*)ue->common_vars.txdata[aa])[2*k+1] = 0;
          }
      }
#endif*/
      return;
  }
1274
//#endif
hbilel's avatar
hbilel committed
1275

1276
//  if ((frame_tx%100) == 0)
1277
    LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n",
1278 1279 1280 1281 1282 1283 1284 1285
    ue->Mod_id,frame_tx,subframe_tx,
    ulsch_start,
    ue->rx_offset,
    ue->hw_timing_advance,
    ue->timing_advance,
    ue->N_TA_offset);


1286 1287 1288 1289
  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
    if (frame_parms->Ncp == 1)
      PHY_ofdm_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1290
       dummy_tx_buffer,
1291
#else
1292
       &ue->common_vars.txdata[aa][ulsch_start],
1293
#endif
1294 1295 1296 1297
       frame_parms->ofdm_symbol_size,
       nsymb,
       frame_parms->nb_prefix_samples,
       CYCLIC_PREFIX);
1298
    else {
1299 1300
      normal_prefix_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1301
			dummy_tx_buffer,
1302
#else
1303
			&ue->common_vars.txdata[aa][ulsch_start],
1304
#endif
1305 1306
			nsymb>>1,
			&ue->frame_parms);
1307

1308 1309 1310 1311 1312 1313 1314 1315 1316
      normal_prefix_mod(&ue->common_vars.txdataF[aa][((subframe_tx*nsymb)+(nsymb>>1))*frame_parms->ofdm_symbol_size],
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
			dummy_tx_buffer+(frame_parms->samples_per_tti>>1),
#else
			&ue->common_vars.txdata[aa][ulsch_start+(frame_parms->samples_per_tti>>1)],
#endif
			nsymb>>1,
			&ue->frame_parms);
      }
1317

1318 1319 1320 1321 1322 1323 1324
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
    apply_7_5_kHz(ue,dummy_tx_buffer,0);
    apply_7_5_kHz(ue,dummy_tx_buffer,1);
#else
    apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],0);
    apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],1);
#endif
1325 1326


1327 1328
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
    overflow = ulsch_start - 9*frame_parms->samples_per_tti;
1329 1330


1331
    for (k=ulsch_start,l=0; k<cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti); k++,l++) {
1332 1333
      ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l];
      ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1];
1334
    }
1335

1336
    for (k=0; k<overflow; k++,l++) {
1337 1338
      ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l];
      ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1];
1339 1340 1341 1342 1343
    }
#if defined(EXMIMO)
    // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on
    for (k=ulsch_start - (frame_parms->samples_per_tti>>1) ; k<ulsch_start ; k++) {
      if (k<0)
1344
  ue->common_vars.txdata[aa][k+frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
1345
      else if (k>(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
1346
  ue->common_vars.txdata[aa][k-frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
1347
      else
1348
  ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE;
1349
    }
1350
#endif
1351
#endif
1352 1353 1354 1355 1356 1357 1358 1359 1360
    /*
    only for debug
    LOG_I(PHY,"ul-signal [subframe: %d, ulsch_start %d, TA: %d, rxOffset: %d, timing_advance: %d, hw_timing_advance: %d]\n",subframe_tx, ulsch_start, ue->N_TA_offset, ue->rx_offset, ue->timing_advance, ue->hw_timing_advance);
    if( (crash == 1) && (subframe_tx == 0) )
    {
      LOG_E(PHY,"***** DUMP TX Signal [ulsch_start %d] *****\n",ulsch_start);
      write_output("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_tti,1,1);
    }
    */
1361

1362
  } //nb_antennas_tx
1363

gabrielC's avatar
gabrielC committed
1364 1365 1366
#if UE_TIMING_TRACE
      stop_meas(&ue->ofdm_mod_stats);
#endif
1367

1368
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT);
1369

1370
}
1371

1372
void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) {
1373

1374 1375 1376 1377
  int frame_tx = proc->frame_tx;
  int subframe_tx = proc->subframe_tx;
  int prach_power;
  PRACH_RESOURCES_t prach_resources_local;
1378

1379 1380
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);

1381
  ue->generate_prach=0;
1382

1383 1384 1385 1386 1387
  if (ue->mac_enabled==0){
    ue->prach_resources[eNB_id] = &prach_resources_local;
    prach_resources_local.ra_RNTI = 0xbeef;
    prach_resources_local.ra_PreambleIndex = 0;
  }
1388

1389 1390 1391
  if (ue->mac_enabled==1){
    // ask L2 for RACH transport
    if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
1392
      //LOG_D(PHY,"Getting PRACH resources\n");
1393

1394 1395 1396 1397 1398
      ue->prach_resources[eNB_id] = ue_get_rach(ue->Mod_id,
						ue->CC_id,
						frame_tx,
						eNB_id,
						subframe_tx);
1399
      LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
1400 1401
    }
  }
1402

1403
  if (ue->prach_resources[eNB_id]!=NULL) {
1404

1405 1406 1407 1408 1409
    ue->generate_prach=1;
    ue->prach_cnt=0;
#ifdef SMBV
    ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
#endif
1410 1411 1412 1413 1414 1415 1416
    LOG_I(PHY,"mode %d\n",mode);
    
    if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
      ue->tx_power_dBm[subframe_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id);
    }
    else {
      ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
1417
      ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
1418 1419
    }
    
1420
    LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : Generating PRACH, preamble %d,PL %d,  P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432
	  ue->Mod_id,
	  frame_tx,
	  subframe_tx,
	  ue->prach_resources[eNB_id]->ra_PreambleIndex,
	  get_PL(ue->Mod_id,ue->CC_id,eNB_id),
	  ue->tx_power_dBm[subframe_tx],
	  ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
	  ue->prach_resources[eNB_id]->ra_TDD_map_index,
	  ue->prach_resources[eNB_id]->ra_RNTI);
    
    ue->tx_total_RE[subframe_tx] = 96;
    
1433
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1434 1435 1436 1437
    ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
					     ue->tx_power_max_dBm,
					     ue->frame_parms.N_RB_UL,
					     6);
1438

1439
#else
1440
    ue->prach_vars[eNB_id]->amp = AMP;
1441
#endif
1442

1443 1444
    if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : PRACH TX power %d dBm, amp %d\n",
1445
	    ue->Mod_id,
1446 1447
	    proc->frame_rx,
	    proc->subframe_tx,
1448
	    ue->tx_power_dBm[subframe_tx],
1449 1450 1451
	    ue->prach_vars[eNB_id]->amp);
    
    
1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462
    //      start_meas(&ue->tx_prach);
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
    prach_power = generate_prach(ue,eNB_id,subframe_tx,frame_tx);
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
    //      stop_meas(&ue->tx_prach);
    LOG_D(PHY,"[UE  %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
	  ue->Mod_id,
	  get_PL(ue->Mod_id,ue->CC_id,eNB_id),
	  ue->tx_power_dBm[subframe_tx],
	  dB_fixed(prach_power),
	  ue->prach_vars[eNB_id]->amp);
1463

Raymond Knopp's avatar
Raymond Knopp committed
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481
    if (ue->mac_enabled==1){
      Msg1_transmitted(ue->Mod_id,
		       ue->CC_id,
		       frame_tx,
		       eNB_id);
    }
    
    LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, subframe %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
	  ue->Mod_id,frame_tx,subframe_tx,eNB_id,
	  ue->prach_resources[eNB_id]->ra_PreambleIndex,
	  ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id),
	  get_PL(ue->Mod_id,ue->CC_id,eNB_id));
    
    
    
    // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
    if (mode == calib_prach_tx)
      ue->prach_resources[eNB_id]=NULL;
1482

Raymond Knopp's avatar
Raymond Knopp committed
1483 1484
    LOG_D(PHY,"[UE %d] frame %d subframe %d : generate_prach %d, prach_cnt %d\n",
	  ue->Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt);
1485

Raymond Knopp's avatar
Raymond Knopp committed
1486
    ue->prach_cnt++;
1487

Raymond Knopp's avatar
Raymond Knopp committed
1488 1489 1490
    if (ue->prach_cnt==3)
      ue->generate_prach=0;
  }
1491
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
1492
}
1493

1494
void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
1495

1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506
  int harq_pid;
  int frame_tx=proc->frame_tx;
  int subframe_tx=proc->subframe_tx;
  int Mod_id = ue->Mod_id;
  int CC_id = ue->CC_id;
  uint8_t Msg3_flag=0;
  uint16_t first_rb, nb_rb;
  unsigned int input_buffer_length;
  int i;
  int aa;
  int tx_amp;
1507
  uint8_t ulsch_input_buffer[5477] __attribute__ ((aligned(32)));
1508
  uint8_t access_mode;
1509
  uint8_t Nbundled=0;
hbilel's avatar
hbilel committed
1510
  uint8_t NbundledCw1=0;
hbilel's avatar
hbilel committed
1511 1512
  uint8_t ack_status_cw0=0;
  uint8_t ack_status_cw1=0;
hbilel's avatar
hbilel committed
1513 1514
  uint8_t cqi_status = 0;
  uint8_t ri_status  = 0;
1515 1516
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_IN);

1517 1518
  // get harq_pid from subframe relationship
  harq_pid = subframe2harq_pid(&ue->frame_parms,
1519 1520 1521
             frame_tx,
             subframe_tx);

1522 1523 1524
  LOG_D(PHY,"Frame %d, Subframe %d : ue_uespec_procedures, harq_pid %d => subframe_scheduling %d\n",
	frame_tx,subframe_tx,harq_pid,
	ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag);
1525

1526
  if (ue->mac_enabled == 1) {
1527 1528 1529
    if ((ue->ulsch_Msg3_active[eNB_id] == 1)       &&
	(ue->ulsch_Msg3_frame[eNB_id] == frame_tx) &&
	(ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3
1530

1531
      ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
1532

1533
      if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0)
1534 1535 1536
	generate_ue_ulsch_params_from_rar(ue,
					  proc,
					  eNB_id);
1537

1538 1539
      ue->ulsch[eNB_id]->power_offset = 14;
      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d: Setting Msg3_flag in subframe %d, for harq_pid %d\n",
1540 1541 1542 1543
      Mod_id,
      frame_tx,
      subframe_tx,
      harq_pid);
1544 1545
      Msg3_flag = 1;
    } else {
1546

1547
      
1548
      AssertFatal(harq_pid!=255,"[UE%d] Frame %d subframe %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, exiting\n",
1549
	      Mod_id,frame_tx, subframe_tx);
1550 1551 1552
      Msg3_flag=0;
    }
  }
1553

1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592
  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {

    uint8_t isBad = 0;
    if (ue->frame_parms.N_RB_UL <= ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb) {
      LOG_D(PHY,"Invalid PUSCH first_RB=%d for N_RB_UL=%d\n",
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
          ue->frame_parms.N_RB_UL);
      isBad = 1;
    }
    if (ue->frame_parms.N_RB_UL < ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb) {
      LOG_D(PHY,"Invalid PUSCH num_RB=%d for N_RB_UL=%d\n",
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
          ue->frame_parms.N_RB_UL);
      isBad = 1;
    }
    if (0 > ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb) {
      LOG_D(PHY,"Invalid PUSCH first_RB=%d\n",
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb);
      isBad = 1;
    }
    if (0 >= ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb) {
      LOG_D(PHY,"Invalid PUSCH num_RB=%d\n",
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb);
      isBad = 1;
    }
    if (ue->frame_parms.N_RB_UL < (ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb)) {
      LOG_D(PHY,"Invalid PUSCH num_RB=%d + first_RB=%d for N_RB_UL=%d\n",
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
          ue->frame_parms.N_RB_UL);
      isBad = 1;
    }
    if ((0 > ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx) ||
        (3 < ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx)) {
      LOG_D(PHY,"Invalid PUSCH RV index=%d\n", ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx);
      isBad = 1;
    }

    if (isBad) {
hbilel's avatar
hbilel committed
1593
      LOG_I(PHY,"Skip PUSCH generation!\n");
1594 1595 1596
      ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
    }
  }
1597
  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
1598

1599
    ue->generate_ul_signal[eNB_id] = 1;
1600

1601
    // deactivate service request
1602
    // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
1603
    LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit);
1604
    if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1))
1605
    {
1606
      //        LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n");
1607 1608 1609
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->round  = 0;
    }
1610

hbilel's avatar
hbilel committed
1611
    ack_status_cw0 = reset_ack(&ue->frame_parms,
1612
            ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
hbilel's avatar
hbilel committed
1613
            subframe_tx,
hbilel's avatar
hbilel committed
1614 1615 1616 1617
            proc->subframe_rx,
            ue->ulsch[eNB_id]->o_ACK,
            &Nbundled,
            0);
hbilel's avatar
hbilel committed
1618
    ack_status_cw1 = reset_ack(&ue->frame_parms,
1619
            ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack,
hbilel's avatar
hbilel committed
1620
            subframe_tx,
hbilel's avatar
hbilel committed
1621 1622 1623 1624 1625
            proc->subframe_rx,
            ue->ulsch[eNB_id]->o_ACK,
            &NbundledCw1,
            1);

1626
    //Nbundled = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack;
hbilel's avatar
hbilel committed
1627
    //ue->ulsch[eNB_id]->bundling = Nbundled;
hbilel's avatar
hbilel committed
1628

1629 1630
    first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
    nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
1631

1632

hbilel's avatar
hbilel committed
1633 1634 1635 1636 1637 1638
    // check Periodic CQI/RI reporting
    cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
        (is_cqi_TXOp(ue,proc,eNB_id)==1));

    ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
             (is_ri_TXOp(ue,proc,eNB_id)==1));
1639

hbilel's avatar
hbilel committed
1640 1641 1642
    // compute CQI/RI resources
    compute_cqi_ri_resources(ue, ue->ulsch[eNB_id], eNB_id, ue->ulsch[eNB_id]->rnti, P_RNTI, CBA_RNTI, cqi_status, ri_status);

hbilel's avatar
hbilel committed
1643
    if (ack_status_cw0 > 0) {
1644 1645 1646

      // check if we received a PDSCH at subframe_tx - 4
      // ==> send ACK/NACK on PUSCH
1647 1648 1649 1650 1651
      if (ue->frame_parms.frame_type == FDD)
      {
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1;
      }

1652 1653 1654 1655 1656

#if T_TRACER
    if(ue->ulsch[eNB_id]->o_ACK[0])
    {
    	LOG_I(PHY,"PUSCH ACK\n");
Cedric Roux's avatar
Cedric Roux committed
1657
        T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
1658
                      T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
1659 1660 1661 1662
    }
    else
    {
    	LOG_I(PHY,"PUSCH NACK\n");
Cedric Roux's avatar
Cedric Roux committed
1663
        T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
1664
                      T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
1665 1666
    }
#endif
gabrielC's avatar
gabrielC committed
1667 1668
#ifdef UE_DEBUG_TRACE
      LOG_I(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n",
1669 1670
        Mod_id,
        ue->ulsch[eNB_id]->rnti,
1671
        frame_tx%1024,subframe_tx,
1672 1673
        ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
        ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
gabrielC's avatar
gabrielC committed
1674
#endif
1675 1676
    }

1677

gabrielC's avatar
gabrielC committed
1678
#ifdef UE_DEBUG_TRACE
1679
        LOG_D(PHY,
hbilel's avatar
hbilel committed
1680
              "[UE  %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, "
1681
              "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, ack_status_cw0 %d ack_status_cw1 %d bundling %d, Nbundled %d, CQI %d, RI %d\n",
1682
          Mod_id,harq_pid,frame_tx%1024,subframe_tx,
1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694
          first_rb,nb_rb,
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs,
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
          (ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift+
           ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2+
           ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1])%12,
          ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2,
          ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1],
          ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
          ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK,
1695 1696 1697 1698 1699
          ack_status_cw0,
          ack_status_cw1,
          ue->ulsch[eNB_id]->bundling, Nbundled,
          cqi_status,
          ri_status);
1700
#endif
1701 1702 1703 1704 1705





1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721
    if (Msg3_flag == 1) {
      LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d Generating (RRCConnectionRequest) Msg3 (nb_rb %d, first_rb %d, round %d, rvidx %d) Msg3: %x.%x.%x|%x.%x.%x.%x.%x.%x\n",Mod_id,frame_tx,
	    subframe_tx,
	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
	    ue->prach_resources[eNB_id]->Msg3[0],
	    ue->prach_resources[eNB_id]->Msg3[1],
	    ue->prach_resources[eNB_id]->Msg3[2],
	    ue->prach_resources[eNB_id]->Msg3[3],
	    ue->prach_resources[eNB_id]->Msg3[4],
	    ue->prach_resources[eNB_id]->Msg3[5],
	    ue->prach_resources[eNB_id]->Msg3[6],
	    ue->prach_resources[eNB_id]->Msg3[7],
	    ue->prach_resources[eNB_id]->Msg3[8]);
gabrielC's avatar
gabrielC committed
1722
#if UE_TIMING_TRACE
1723
      start_meas(&ue->ulsch_encoding_stats);
gabrielC's avatar
gabrielC committed
1724
#endif
1725
      
1726 1727 1728 1729 1730 1731 1732
      AssertFatal(ulsch_encoding(ue->prach_resources[eNB_id]->Msg3,
				 ue,
				 harq_pid,
				 eNB_id,
				 proc->subframe_rx,
				 ue->transmission_mode[eNB_id],0,0)==0,
		  "ulsch_coding.c: FATAL ERROR: returning\n");
1733
      
gabrielC's avatar
gabrielC committed
1734
#if UE_TIMING_TRACE
1735 1736
      stop_meas(&ue->phy_proc_tx);
      printf("------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0));
gabrielC's avatar
gabrielC committed
1737
#endif
1738

gabrielC's avatar
gabrielC committed
1739
#if UE_TIMING_TRACE
1740
      stop_meas(&ue->ulsch_encoding_stats);
gabrielC's avatar
gabrielC committed
1741
#endif
1742
      if (ue->mac_enabled == 1) {
1743

1744
	// signal MAC that Msg3 was sent
1745 1746 1747 1748
	Msg3_transmitted(Mod_id,
			 CC_id,
			 frame_tx,
			 eNB_id);
1749
      }
1750
      LOG_I(PHY,"Done Msg3 encoding\n");
1751
    } // Msg3_flag==1
1752
    else {// Msg3_flag==0
1753
      input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
1754

1755
      if (ue->mac_enabled==1) {
1756

1757 1758 1759 1760
	//  LOG_D(PHY,"[UE  %d] ULSCH : Searching for MAC SDUs\n",Mod_id);
	if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) {
	  //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) {
	  access_mode=SCHEDULED_ACCESS;
1761

1762 1763 1764 1765 1766 1767 1768 1769
	  ue_get_sdu(Mod_id,
		     CC_id,
		     frame_tx,
		     subframe_tx,
		     eNB_id,
		     ulsch_input_buffer,
		     input_buffer_length,
		     &access_mode);
1770 1771
	}
	
1772 1773 1774
      

	
1775 1776
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_ULSCH
1777 1778 1779 1780 1781 1782
	LOG_D(PHY,"[UE] Frame %d, subframe %d : ULSCH SDU (TX harq_pid %d)  (%d bytes) : \n",frame_tx,subframe_tx,harq_pid, ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3);
	
	for (i=0; i<ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; i++)
	  LOG_T(PHY,"%x.",ulsch_input_buffer[i]);
	
	LOG_T(PHY,"\n");
1783 1784
#endif
#endif
1785 1786 1787 1788 1789 1790 1791 1792 1793
      }
      else {
	unsigned int taus(void);
	
	for (i=0; i<input_buffer_length; i++)
	  ulsch_input_buffer[i]= (uint8_t)(taus()&0xff);
	
      }
      
gabrielC's avatar
gabrielC committed
1794
#if UE_TIMING_TRACE
1795
      start_meas(&ue->ulsch_encoding_stats);
gabrielC's avatar
gabrielC committed
1796
#endif
1797
      if (abstraction_flag==0) {
1798
	
1799 1800 1801 1802
	if (ulsch_encoding(ulsch_input_buffer,
			   ue,
			   harq_pid,
			   eNB_id,
hbilel's avatar
hbilel committed
1803
			   proc->subframe_rx,
1804 1805
			   ue->transmission_mode[eNB_id],0,
			   Nbundled)!=0) {
1806 1807
	  LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
	  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
gabrielC's avatar
gabrielC committed
1808
#if UE_TIMING_TRACE
1809
	  stop_meas(&ue->phy_proc_tx);
gabrielC's avatar
gabrielC committed
1810
#endif
1811
	  return;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1812
	}
1813 1814
      }
      
gabrielC's avatar
gabrielC committed
1815
#if UE_TIMING_TRACE
1816
      stop_meas(&ue->ulsch_encoding_stats);
gabrielC's avatar
gabrielC committed
1817
#endif
1818
    }
1819
    
1820 1821
    if (abstraction_flag == 0) {
      if (ue->mac_enabled==1) {
1822 1823
	pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag);
	ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH;
1824 1825
      }
      else {
1826
	ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
1827
      }
1828
      ue->tx_total_RE[subframe_tx] = nb_rb*12;
1829
      
kaltenbe's avatar
kaltenbe committed
1830
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
1831
      tx_amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
1832 1833 1834
			  ue->tx_power_max_dBm,
			  ue->frame_parms.N_RB_UL,
			  nb_rb);
1835
#else
1836
    tx_amp = AMP;
1837
#endif
Cedric Roux's avatar
Cedric Roux committed
1838 1839

    T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
1840
      T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb));
1841

gabrielC's avatar
gabrielC committed
1842
#ifdef UE_DEBUG_TRACE
1843
    LOG_D(PHY,"[UE  %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
1844
	  Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp);
gabrielC's avatar
gabrielC committed
1845 1846
#endif
#if UE_TIMING_TRACE
1847
    
1848
    start_meas(&ue->ulsch_modulation_stats);
1849
#endif
1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864
    ulsch_modulation(ue->common_vars.txdataF,
		     tx_amp,
		     frame_tx,
		     subframe_tx,
		     &ue->frame_parms,
		     ue->ulsch[eNB_id]);
    for (aa=0; aa<1/*frame_parms->nb_antennas_tx*/; aa++)
      generate_drs_pusch(ue,
			 proc,
			 eNB_id,
			 tx_amp,
			 subframe_tx,
			 first_rb,
			 nb_rb,
			 aa);
gabrielC's avatar
gabrielC committed
1865
#if UE_TIMING_TRACE
1866
    stop_meas(&ue->ulsch_modulation_stats);
gabrielC's avatar
gabrielC committed
1867
#endif
1868

1869
    }
1870
    
1871 1872 1873 1874 1875
    if (abstraction_flag==1) {
      // clear SR
      ue->sr[subframe_tx]=0;
    }
  } // subframe_scheduling_flag==1
1876 1877 1878

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_OUT);

1879
}
1880

hbilel's avatar
hbilel committed
1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907
void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag)
{

  //LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
  //int8_t  frame_tx    = proc->frame_tx;
  int8_t  subframe_tx = proc->subframe_tx;
  int16_t tx_amp;
  int16_t Po_SRS;
  uint8_t nb_rb_srs;

  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
  uint8_t isSrsTxOccasion = pSoundingrs_ul_config_dedicated->srsUeSubframe;

  if(isSrsTxOccasion)
  {
    ue->generate_ul_signal[eNB_id] = 1;
    if (ue->mac_enabled==1)
    {
      srs_power_cntl(ue,proc,eNB_id, (uint8_t*)(&nb_rb_srs), abstraction_flag);
      Po_SRS = ue->ulsch[eNB_id]->Po_SRS;
    }
    else
    {
      Po_SRS = ue->tx_power_max_dBm;
    }

#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
fnabet's avatar
fnabet committed
1908 1909
    if (ue->mac_enabled==1)
    {
hbilel's avatar
hbilel committed
1910 1911 1912 1913
    tx_amp = get_tx_amp(Po_SRS,
                        ue->tx_power_max_dBm,
                        ue->frame_parms.N_RB_UL,
                        nb_rb_srs);
fnabet's avatar
fnabet committed
1914 1915 1916 1917 1918
    }
    else
    {
        tx_amp = AMP;
    }
hbilel's avatar
hbilel committed
1919 1920 1921
#else
      tx_amp = AMP;
#endif
fnabet's avatar
fnabet committed
1922
    LOG_D(PHY,"SRS PROC; TX_MAX_POWER %d, Po_SRS %d, NB_RB_UL %d, NB_RB_SRS %d TX_AMPL %d\n",ue->tx_power_max_dBm,
hbilel's avatar
hbilel committed
1923 1924 1925 1926 1927
            Po_SRS,
            ue->frame_parms.N_RB_UL,
            nb_rb_srs,
            tx_amp);

1928 1929
    uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12;
    uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((subframe_tx*nsymb)+(nsymb-1));
1930 1931 1932 1933 1934
    generate_srs(&ue->frame_parms,
     &ue->soundingrs_ul_config_dedicated[eNB_id],
     &ue->common_vars.txdataF[eNB_id][symbol_offset],
     tx_amp,
     subframe_tx);
hbilel's avatar
hbilel committed
1935 1936
  }
}
1937

Raymond Knopp's avatar
Raymond Knopp committed
1938 1939 1940 1941 1942
int16_t get_pucch2_cqi(PHY_VARS_UE *ue,int eNB_id,int *len) {

  if ((ue->transmission_mode[eNB_id]<4)||
      (ue->transmission_mode[eNB_id]==7)) { // Mode 1-0 feedback
    // 4-bit CQI message
1943 1944 1945 1946
          /*LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id],
                          ue->measurements.wideband_cqi_avg[eNB_id],
                          sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
                                    ue->transmission_mode[eNB_id]));*/
Raymond Knopp's avatar
Raymond Knopp committed
1947 1948
    *len=4;
    return(sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
1949
        ue->transmission_mode[eNB_id]));
Raymond Knopp's avatar
Raymond Knopp committed
1950 1951
  }
  else { // Mode 1-1 feedback, later
1952
          //LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]);
Raymond Knopp's avatar
Raymond Knopp committed
1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965
    *len=0;
    // 2-antenna ports RI=1, 6 bits (2 PMI, 4 CQI)

    // 2-antenna ports RI=2, 8 bits (1 PMI, 7 CQI/DIFF CQI)
    return(0);
  }
}


int16_t get_pucch2_ri(PHY_VARS_UE *ue,int eNB_id) {

  return(1);
}
1966

1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990

void get_pucch_param(PHY_VARS_UE    *ue,
                     UE_rxtx_proc_t *proc,
                     uint8_t        *ack_payload,
                     PUCCH_FMT_t    format,
                     uint8_t        eNB_id,
                     uint8_t        SR,
                     uint8_t        cqi_report,
                     uint16_t       *pucch_resource,
                     uint8_t        *pucch_payload,
                     uint16_t       *plength)
{

    switch (format) {
    case pucch_format1:
    {
        pucch_resource[0] = ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex;
        pucch_payload[0]  = 0; // payload is ignored in case of format1
        pucch_payload[1]  = 0; // payload is ignored in case of format1
    }
    break;

    case pucch_format1a:
    case pucch_format1b:
1991 1992 1993
    case pucch_format1b_csA2:
    case pucch_format1b_csA3:
    case pucch_format1b_csA4:
1994 1995 1996
    {
        pucch_resource[0] = get_n1_pucch(ue,
                                         proc,
1997
                                         ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
1998 1999 2000 2001
                                         eNB_id,
                                         ack_payload,
                                         SR);
        pucch_payload[0]  = ack_payload[0];
hbilel's avatar
hbilel committed
2002 2003
        pucch_payload[1]  = ack_payload[1];
        //pucch_payload[1]  = 1;
2004 2005 2006 2007 2008 2009 2010 2011
    }
    break;

    case pucch_format2:
    {
        pucch_resource[0]    = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex;
        if(cqi_report)
        {
hbilel's avatar
hbilel committed
2012
            pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,(int*)plength);
2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025
        }
        else
        {
            *plength = 1;
            pucch_payload[0] = get_pucch2_ri(ue,eNB_id);
        }
    }
    break;

    case pucch_format2a:
    case pucch_format2b:
        LOG_E(PHY,"NO Resource available for PUCCH 2a/2b \n");
    break;
2026 2027 2028 2029

    case pucch_format3:
      fprintf(stderr, "PUCCH format 3 not handled\n");
      abort();
2030 2031 2032
    }
}

2033
void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
2034 2035


2036 2037
  uint8_t  pucch_ack_payload[2];
  uint16_t pucch_resource;
2038 2039
  ANFBmode_t bundling_flag;
  PUCCH_FMT_t format;
Raymond Knopp's avatar
Raymond Knopp committed
2040

2041 2042 2043
  uint8_t  SR_payload;
  uint8_t  pucch_payload[2];
  uint16_t len;
Raymond Knopp's avatar
Raymond Knopp committed
2044

2045 2046 2047 2048 2049 2050
  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
  int frame_tx=proc->frame_tx;
  int subframe_tx=proc->subframe_tx;
  int Mod_id = ue->Mod_id;
  int CC_id = ue->CC_id;
  int tx_amp;
2051
  int16_t Po_PUCCH;
2052 2053 2054 2055 2056
  uint8_t ack_status_cw0=0;
  uint8_t ack_status_cw1=0;
  uint8_t nb_cw=0;
  uint8_t cqi_status=0;
  uint8_t ri_status=0;
2057

2058
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN);
2059

hbilel's avatar
hbilel committed
2060
  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
2061 2062 2063 2064 2065 2066

  // 36.213 8.2
  /*if ackNackSRS_SimultaneousTransmission ==  TRUE and in the cell specific SRS subframes UE shall transmit
    ACK/NACK and SR using the shortened PUCCH format. This shortened PUCCH format shall be used in a cell
    specific SRS subframe even if the UE does not transmit SRS in that subframe
  */
2067 2068 2069 2070 2071 2072 2073 2074

  int harq_pid = subframe2harq_pid(&ue->frame_parms,
                                   frame_tx,
                                   subframe_tx);

  if(ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag)
  {
      LOG_D(PHY,"PUSCH is programmed on this subframe [pid %d] AbsSuframe %d.%d ==> Skip PUCCH transmission \n",harq_pid,frame_tx,subframe_tx);
2075
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);
2076 2077 2078
      return;
  }

fnabet's avatar
fnabet committed
2079
  uint8_t isShortenPucch = (pSoundingrs_ul_config_dedicated->srsCellSubframe && frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission);
hbilel's avatar
hbilel committed
2080

2081
  bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
2082

2083 2084 2085 2086
  if ((frame_parms->frame_type==FDD) ||
      (bundling_flag==bundling)    ||
      ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe_tx!=2)||(subframe_tx!=7)))) {
    format = pucch_format1a;
2087
    //    LOG_D(PHY,"[UE] PUCCH 1a\n");
2088 2089
  } else {
    format = pucch_format1b;
2090
    //    LOG_D(PHY,"[UE] PUCCH 1b\n");
2091
  }
2092

2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103
  // Part - I
  // Collect feedback that should be transmitted at this subframe
  // - SR
  // - ACK/NACK
  // - CQI
  // - RI

  SR_payload = 0;
  if (is_SR_TXOp(ue,proc,eNB_id)==1)
  {
      if (ue->mac_enabled==1) {
2104 2105 2106 2107 2108 2109
	SR_payload = ue_get_SR(Mod_id,
			       CC_id,
			       frame_tx,
			       eNB_id,
			       ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,
			       subframe_tx); // subframe used for meas gap
2110 2111 2112 2113
      }
      else {
          SR_payload = 1;
      }
2114
  }
Raymond Knopp's avatar
Raymond Knopp committed
2115

2116
  ack_status_cw0 = get_ack(&ue->frame_parms,
2117
                       ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
2118
                       subframe_tx,
hbilel's avatar
hbilel committed
2119
                       proc->subframe_rx,
2120 2121
                       pucch_ack_payload,
                       0);
2122

2123
  ack_status_cw1 = get_ack(&ue->frame_parms,
2124
                       ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack,
2125
                       subframe_tx,
hbilel's avatar
hbilel committed
2126
                       proc->subframe_rx,
2127 2128
                       pucch_ack_payload,
                       1);
Raymond Knopp's avatar
Raymond Knopp committed
2129

gabrielC's avatar
gabrielC committed
2130
  nb_cw = ( (ack_status_cw0 != 0) ? 1:0) + ( (ack_status_cw1 != 0) ? 1:0);
Raymond Knopp's avatar
Raymond Knopp committed
2131

2132 2133
  cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
      (is_cqi_TXOp(ue,proc,eNB_id)==1));
Raymond Knopp's avatar
Raymond Knopp committed
2134

2135 2136
  ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
           (is_ri_TXOp(ue,proc,eNB_id)==1));
Raymond Knopp's avatar
Raymond Knopp committed
2137

2138 2139
  // Part - II
  // if nothing to report ==> exit function
hbilel's avatar
hbilel committed
2140
  if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0) )
2141
  {
2142
      LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n",
2143
            frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status);
2144 2145
      return;
  }
Raymond Knopp's avatar
Raymond Knopp committed
2146

2147 2148 2149 2150 2151 2152 2153
  // Part - III
  // Decide which PUCCH format should be used if needed
  format = get_pucch_format(frame_parms->frame_type,
                            frame_parms->Ncp,
                            SR_payload,
                            nb_cw,
                            cqi_status,
hbilel's avatar
hbilel committed
2154 2155
                            ri_status,
                            bundling_flag);
2156 2157 2158 2159 2160 2161 2162 2163 2164
  // Determine PUCCH resources and payload: mandatory for pucch encoding
  get_pucch_param(ue,
                  proc,
                  pucch_ack_payload,
                  format,
                  eNB_id,
                  SR_payload,
                  cqi_status,
                  &pucch_resource,
hbilel's avatar
hbilel committed
2165
                  (uint8_t *)&pucch_payload,
2166 2167 2168
                  &len);


2169 2170
  LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d (%d %d) AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n",
	frame_tx%1024, subframe_tx, SR_payload, nb_cw, ack_status_cw0, ack_status_cw1, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]);
2171 2172 2173 2174 2175 2176 2177 2178 2179 2180

  // Part - IV
  // Generate PUCCH signal
  ue->generate_ul_signal[eNB_id] = 1;

  switch (format) {
  case pucch_format1:
  case pucch_format1a:
  case pucch_format1b:
  {
Raymond Knopp's avatar
Raymond Knopp committed
2181
      if (ue->mac_enabled == 1) {
2182
          Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
Raymond Knopp's avatar
Raymond Knopp committed
2183 2184
      }
      else {
2185
          Po_PUCCH = ue->tx_power_max_dBm;
Raymond Knopp's avatar
Raymond Knopp committed
2186 2187 2188
      }
      ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
      ue->tx_total_RE[subframe_tx] = 12;
2189

Raymond Knopp's avatar
Raymond Knopp committed
2190
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
2191 2192 2193 2194
      tx_amp = get_tx_amp(Po_PUCCH,
              ue->tx_power_max_dBm,
              ue->frame_parms.N_RB_UL,
              1);
Raymond Knopp's avatar
Raymond Knopp committed
2195 2196
#else
      tx_amp = AMP;
2197 2198
#endif
#if T_TRACER
Cedric Roux's avatar
Cedric Roux committed
2199
      T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
2200
              T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
Raymond Knopp's avatar
Raymond Knopp committed
2201
#endif
gabrielC's avatar
gabrielC committed
2202 2203

#ifdef UE_DEBUG_TRACE
2204
      if(format == pucch_format1)
2205 2206 2207 2208 2209 2210 2211 2212 2213
	{
          LOG_D(PHY,"[UE  %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
		Mod_id,
		ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
		frame_tx%1024, subframe_tx,
		frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
		isShortenPucch,
		ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
		Po_PUCCH);
2214 2215 2216 2217
      }
      else
      {
          if (SR_payload>0) {
2218
              LOG_D(PHY,"[UE  %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n",
2219
                      Mod_id,
2220
                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
2221 2222 2223 2224 2225 2226 2227 2228 2229 2230
                      frame_tx % 1024, subframe_tx,
                      (format == pucch_format1a? "1a": (
                              format == pucch_format1b? "1b" : "??")),
                              pucch_ack_payload[0],pucch_ack_payload[1],
                              frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
                              isShortenPucch,
                              pucch_resource,
                              Po_PUCCH,
                              tx_amp);
          } else {
2231
              LOG_D(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
2232
                      Mod_id,
2233
                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
2234 2235 2236 2237 2238 2239 2240 2241 2242 2243
                      frame_tx%1024, subframe_tx,ue->rx_offset_diff,
                      (format == pucch_format1a? "1a": (
                              format == pucch_format1b? "1b" : "??")),
                              frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
                              isShortenPucch,
                              pucch_resource,pucch_payload[0],pucch_payload[1],SR_payload,
                              Po_PUCCH,
                              tx_amp);
          }
      }
gabrielC's avatar
gabrielC committed
2244
#endif
2245

2246 2247 2248
#if T_TRACER
      if(pucch_payload[0])
      {
Cedric Roux's avatar
Cedric Roux committed
2249
          T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
2250
                  T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
2251 2252 2253
      }
      else
      {
Cedric Roux's avatar
Cedric Roux committed
2254
          T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
2255
                  T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
2256 2257
      }
#endif
2258

2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269
      generate_pucch1x(ue->common_vars.txdataF,
		       &ue->frame_parms,
		       ue->ncs_cell,
		       format,
		       &ue->pucch_config_dedicated[eNB_id],
		       pucch_resource,
		       isShortenPucch,  // shortened format
		       pucch_payload,
		       tx_amp,
		       subframe_tx);
      
2270 2271
  }
  break;
2272

Raymond Knopp's avatar
Raymond Knopp committed
2273

2274 2275
  case pucch_format2:
  {
Raymond Knopp's avatar
Raymond Knopp committed
2276
      if (ue->mac_enabled == 1) {
2277
          Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
Raymond Knopp's avatar
Raymond Knopp committed
2278 2279
      }
      else {
2280
          Po_PUCCH = ue->tx_power_max_dBm;
Raymond Knopp's avatar
Raymond Knopp committed
2281 2282 2283
      }
      ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
      ue->tx_total_RE[subframe_tx] = 12;
2284

Raymond Knopp's avatar
Raymond Knopp committed
2285 2286
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
      tx_amp =  get_tx_amp(Po_PUCCH,
2287 2288 2289
              ue->tx_power_max_dBm,
              ue->frame_parms.N_RB_UL,
              1);
Raymond Knopp's avatar
Raymond Knopp committed
2290 2291 2292
#else
      tx_amp = AMP;
#endif
2293
#if T_TRACER
Cedric Roux's avatar
Cedric Roux committed
2294
      T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
2295
              T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
2296
#endif
gabrielC's avatar
gabrielC committed
2297
#ifdef UE_DEBUG_TRACE
2298
      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n",
2299
              Mod_id,
2300
              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
2301 2302 2303 2304
              frame_tx%1024, subframe_tx,
              Po_PUCCH,
              isShortenPucch,
              tx_amp);
gabrielC's avatar
gabrielC committed
2305
#endif
Raymond Knopp's avatar
Raymond Knopp committed
2306
      generate_pucch2x(ue->common_vars.txdataF,
2307 2308 2309 2310 2311 2312 2313 2314 2315 2316
              &ue->frame_parms,
              ue->ncs_cell,
              format,
              &ue->pucch_config_dedicated[eNB_id],
              pucch_resource,
              pucch_payload,
              len,          // A
              0,            // B2 not needed
              tx_amp,
              subframe_tx,
2317
              ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti);
2318 2319 2320 2321
  }
  break;

  case pucch_format2a:
gabrielC's avatar
gabrielC committed
2322
      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n",
2323
              Mod_id,
2324
              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
2325 2326 2327
              frame_tx%1024, subframe_tx);
      break;
  case pucch_format2b:
gabrielC's avatar
gabrielC committed
2328
      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n",
2329
              Mod_id,
2330
              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
2331 2332 2333 2334
              frame_tx%1024, subframe_tx);
      break;
  default:
      break;
Raymond Knopp's avatar
Raymond Knopp committed
2335
  }
2336 2337 2338

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);

2339
}
2340

2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361
void phy_procedures_UE_SL_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc) {

  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  SLSS_t *slss;
  SLDCH_t *sldch;
  SLSCH_t *slsch;

  LOG_D(PHY,"****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);

  // check for SLBCH/SLSS
  if ((slss = ue_get_slss(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slss(ue,slss,frame_tx,subframe_tx);

  // check for SLDCH
  if ((sldch = ue_get_sldch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_sldch(ue,sldch,frame_tx,subframe_tx);

  // check for SLSCH
  if ((slsch = ue_get_slsch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slsch(ue,slsch,frame_tx,subframe_tx);

}

2362
void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) {
2363

2364

2365
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
2366
  //int32_t ulsch_start=0;
2367 2368 2369
  int subframe_tx = proc->subframe_tx;
  int frame_tx = proc->frame_tx;
  unsigned int aa;
2370
  uint8_t isSubframeSRS;
2371

2372 2373
  uint8_t next1_thread_id = ue->current_thread_id[proc->subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[proc->subframe_rx]+1);
  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
2374

2375
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
2376

2377
  LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);
2378
#if T_TRACER
hbilel's avatar
hbilel committed
2379
  T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx));
2380
#endif
2381

2382
  ue->generate_ul_signal[eNB_id] = 0;
gabrielC's avatar
gabrielC committed
2383
#if UE_TIMING_TRACE
2384
  start_meas(&ue->phy_proc_tx);
gabrielC's avatar
gabrielC committed
2385
#endif
2386

2387
  ue->tx_power_dBm[subframe_tx]=-127;
2388

2389
      
2390 2391 2392 2393
  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
    memset(&ue->common_vars.txdataF[aa][subframe_tx*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti],
	   0,
	   frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t));
2394
  }
2395
  
2396 2397
      
  if (ue->UE_mode[eNB_id] != PRACH) {
fnabet's avatar
fnabet committed
2398
    // check cell srs subframe and ue srs subframe. This has an impact on pusch encoding
2399 2400 2401
    isSubframeSRS = is_srs_occasion_common(&ue->frame_parms,proc->frame_tx,proc->subframe_tx);

    ue_compute_srs_occasion(ue,proc,eNB_id,isSubframeSRS);
2402

2403
    ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
2404

2405 2406
    LOG_D(PHY,"ULPOWERS After ulsch_uespec_procedures : ue->tx_power_dBm[%d]=%d, NPRB %d\n",
	  subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_total_RE[subframe_tx]);
2407
  }
2408

hbilel's avatar
hbilel committed
2409 2410 2411 2412 2413
  if (ue->UE_mode[eNB_id] == PUSCH) {
      // check if we need to use PUCCH 1a/1b
      ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
      // check if we need to use SRS
      ue_srs_procedures(ue,proc,eNB_id,abstraction_flag);
2414
  } // UE_mode==PUSCH
2415

2416 2417
	
  	
2418

2419
  	
2420 2421
  ulsch_common_procedures(ue,proc, (ue->generate_ul_signal[eNB_id] == 0));
        
2422 2423
  if ((ue->UE_mode[eNB_id] == PRACH) && 
      (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
2424

2425
    // check if we have PRACH opportunity
2426

2427
    if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) {
2428

2429
      ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
2430
    }
2431 2432 2433 2434
  } // mode is PRACH
  else {
    ue->generate_prach=0;
  }
2435

2436
  // reset DL ACK/NACK status
hbilel's avatar
hbilel committed
2437
  uint8_t N_bundled = 0;
2438
  if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0] != NULL)
hbilel's avatar
hbilel committed
2439
  {
2440
    reset_ack(&ue->frame_parms,
2441
               ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
2442
               subframe_tx,
hbilel's avatar
hbilel committed
2443 2444 2445 2446
               proc->subframe_rx,
               ue->ulsch[eNB_id]->o_ACK,
               &N_bundled,
               0);
hbilel's avatar
hbilel committed
2447
    reset_ack(&ue->frame_parms,
2448
               ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack,
2449
               subframe_tx,
hbilel's avatar
hbilel committed
2450 2451 2452 2453
               proc->subframe_rx,
               ue->ulsch[eNB_id]->o_ACK,
               &N_bundled,
               0);
hbilel's avatar
hbilel committed
2454
    reset_ack(&ue->frame_parms,
2455
               ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack,
hbilel's avatar
hbilel committed
2456
               subframe_tx,
hbilel's avatar
hbilel committed
2457 2458 2459 2460
               proc->subframe_rx,
               ue->ulsch[eNB_id]->o_ACK,
               &N_bundled,
               0);
hbilel's avatar
hbilel committed
2461
  }
2462

2463
  if (ue->dlsch_SI[eNB_id] != NULL)
2464
    reset_ack(&ue->frame_parms,
2465 2466
             ue->dlsch_SI[eNB_id]->harq_ack,
             subframe_tx,
hbilel's avatar
hbilel committed
2467 2468 2469 2470
             proc->subframe_rx,
             ue->ulsch[eNB_id]->o_ACK,
             &N_bundled,
             0);
2471

2472

2473 2474
  LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);

2475
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
gabrielC's avatar
gabrielC committed
2476
#if UE_TIMING_TRACE
2477
  stop_meas(&ue->phy_proc_tx);
gabrielC's avatar
gabrielC committed
2478
#endif
2479 2480
}

2481
void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag)
2482
{
2483
  int aa;//i,aa;
2484
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
2485

2486
  
2487
  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
2488
#if defined(EXMIMO) //this is the EXPRESS MIMO case
2489 2490 2491 2492 2493
    int i;
    // set the whole tx buffer to RX
    for (i=0; i<LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; i++)
      ue->common_vars.txdata[aa][i] = 0x00010001;
    
2494
#else //this is the normal case
2495 2496
    memset(&ue->common_vars.txdata[aa][0],0,
	   (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t));
2497
#endif //else EXMIMO
2498
    
2499
  }
2500
  
2501 2502
}

2503 2504 2505
void ue_measurement_procedures(
    uint16_t l,    // symbol index of each slot [0..6]
    PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,
2506
    uint16_t slot, // slot index of each radio frame [0..19]
2507
    uint8_t abstraction_flag,runmode_t mode)
2508
{
2509

hbilel's avatar
hbilel committed
2510
  //LOG_I(PHY,"ue_measurement_procedures l %d Ncp %d\n",l,ue->frame_parms.Ncp);
hbilel's avatar
hbilel committed
2511

2512
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
Raymond Knopp's avatar
 
Raymond Knopp committed
2513

2514
  int subframe_rx = proc->subframe_rx;
2515

2516
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);
2517 2518

  if (l==0) {
2519
    // UE measurements on symbol 0
2520

2521
    LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata);
2522
      LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata);
2523

2524
      lte_ue_measurements(ue,
2525 2526 2527 2528 2529 2530
			  (subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME),
			  (subframe_rx == 1) ? 1 : 0,
			  0,
			  0,
			  subframe_rx);
      
2531
#if T_TRACER
2532
      if(slot == 0)
Cedric Roux's avatar
Cedric Roux committed
2533
	T(T_UE_PHY_MEAS, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx),
2534 2535 2536 2537 2538 2539 2540
	  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));
2541
#endif
2542 2543
  }

2544
  if (l==(6-ue->frame_parms.Ncp)) {
2545

2546
    // make sure we have signal from PSS/SSS for N0 measurement
2547
         // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n");
2548

2549
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN);
2550
    ue_rrc_measurements(ue,
2551 2552
      slot,
      abstraction_flag);
2553
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT);
2554

2555
  }
2556

2557 2558
  // accumulate and filter timing offset estimation every subframe (instead of every frame)
  if (( (slot%2) == 0) && (l==(4-frame_parms->Ncp))) {
2559

2560
    // AGC
Raymond Knopp's avatar
 
Raymond Knopp committed
2561

2562
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
Raymond Knopp's avatar
 
Raymond Knopp committed
2563

2564
#ifndef OAI_USRP
kaltenbe's avatar
kaltenbe committed
2565 2566
#ifndef OAI_BLADERF
#ifndef OAI_LMSSDR
2567
    phy_adjust_gain (ue,dB_fixed(ue->measurements.rssi),0);
kaltenbe's avatar
kaltenbe committed
2568 2569
#endif
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
2570
#endif
2571

2572
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
2573

2574
    eNB_id = 0;
2575

2576
    
2577 2578 2579 2580 2581 2582 2583 2584
    if (ue->no_timing_correction==0)
      lte_adjust_synch(&ue->frame_parms,
		       ue,
		       eNB_id,
		       subframe_rx,
		       0,
		       16384);
 
2585
  }
2586

2587
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
2588 2589 2590 2591
}



2592
void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t abstraction_flag)
2593
{
2594 2595 2596

  //  int i;
  int pbch_tx_ant=0;
2597 2598 2599 2600
  uint8_t pbch_phase;
  uint16_t frame_tx;
  static uint8_t first_run = 1;
  uint8_t pbch_trials = 0;
2601

2602
  DevAssert(ue);
2603 2604 2605

  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
2606

2607
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
2608

Raymond Knopp's avatar
 
Raymond Knopp committed
2609
  pbch_phase=(frame_rx%4);
2610

2611 2612
  if (pbch_phase>=4)
    pbch_phase=0;
2613 2614 2615

  for (pbch_trials=0; pbch_trials<4; pbch_trials++) {
    //for (pbch_phase=0;pbch_phase<4;pbch_phase++) {
2616
    //LOG_I(PHY,"[UE  %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id);
2617

2618 2619 2620 2621 2622 2623 2624 2625
    pbch_tx_ant = rx_pbch(&ue->common_vars,
			  ue->pbch_vars[eNB_id],
			  &ue->frame_parms,
			  eNB_id,
			  ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI,
			  ue->high_speed_flag,
			  pbch_phase);
    
2626 2627 2628
    if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) {
      break;
    }
2629

2630
    pbch_phase++;
2631

2632 2633 2634 2635 2636 2637 2638 2639
    if (pbch_phase>=4)
      pbch_phase=0;
  }



  if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) {

2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650
    if (opt_enabled) {
      static uint8_t dummy[3];
      dummy[0] = ue->pbch_vars[eNB_id]->decoded_output[2];
      dummy[1] = ue->pbch_vars[eNB_id]->decoded_output[1];
      dummy[2] = ue->pbch_vars[eNB_id]->decoded_output[0];
      trace_pdu(1, dummy, 3, ue->Mod_id, 0, 0,
          frame_rx, subframe_rx, 0, 0);
      LOG_D(OPT,"[UE %d][PBCH] Frame %d trace pdu for PBCH\n",
          ue->Mod_id, subframe_rx);
    }

2651
    if (pbch_tx_ant>2) {
2652
      LOG_W(PHY,"[openair][SCHED][SYNCH] PBCH decoding: pbch_tx_ant>2 not supported\n");
2653
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
2654 2655 2656 2657
      return;
    }


2658 2659 2660
    ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0;
    frame_tx = (((int)(ue->pbch_vars[eNB_id]->decoded_output[2]&0x03))<<8);
    frame_tx += ((int)(ue->pbch_vars[eNB_id]->decoded_output[1]&0xfc));
2661 2662
    frame_tx += pbch_phase;

2663
    if (ue->mac_enabled==1) {
2664

2665 2666
      dl_phy_sync_success(ue->Mod_id,frame_rx,eNB_id,
			  ue->UE_mode[eNB_id]==NOT_SYNCHED ? 1 : 0);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
2667
    }
2668

2669 2670
    if (first_run) {
      first_run = 0;
2671 2672 2673

      proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
      proc->frame_tx = proc->frame_rx;
2674

2675 2676 2677 2678
      for(int th_id=0; th_id<RX_NB_TH; th_id++)
      {
        ue->proc.proc_rxtx[th_id].frame_rx = proc->frame_rx;
        ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_tx;
2679 2680 2681 2682 2683 2684 2685 2686 2687 2688

        printf("[UE %d] frame %d, subframe %d: Adjusting frame counter (PBCH ant_tx=%d, frame_tx=%d, phase %d, rx_offset %d) => new frame %d\n",
 	    ue->Mod_id,
 	    ue->proc.proc_rxtx[th_id].frame_rx,
 	    subframe_rx,
 	    pbch_tx_ant,
 	    frame_tx,
 	    pbch_phase,
 	    ue->rx_offset,
 	    proc->frame_rx);
2689
      }
2690

2691

2692
      frame_rx = proc->frame_rx;
2693

2694
    } else if (((frame_tx & 0x03FF) != (proc->frame_rx & 0x03FF))) {
2695
      //(pbch_tx_ant != ue->frame_parms.nb_antennas_tx)) {
Cedric Roux's avatar
Cedric Roux committed
2696
      LOG_D(PHY,"[UE %d] frame %d, subframe %d: Re-adjusting frame counter (PBCH ant_tx=%d, frame_rx=%d, frame%%1024=%d, phase %d).\n",
2697 2698 2699 2700 2701 2702 2703
      ue->Mod_id,
      proc->frame_rx,
      subframe_rx,
      pbch_tx_ant,
      frame_tx,
      frame_rx & 0x03FF,
      pbch_phase);
2704 2705 2706 2707 2708


      proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
      proc->frame_tx = proc->frame_rx;
      frame_rx = proc->frame_rx;
2709 2710 2711 2712 2713 2714
      
      for(int th_id=0; th_id<RX_NB_TH; th_id++)
      {
        ue->proc.proc_rxtx[th_id].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
        ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_rx;
      }
2715

2716
    }
2717

2718
#ifdef DEBUG_PHY_PROC
2719

2720
    LOG_D(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): nb_antenna_ports_eNB %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
2721 2722 2723
	  ue->Mod_id,
	  frame_rx,
	  subframe_rx,
2724
	  ue->frame_parms.nb_antenna_ports_eNB,
2725 2726 2727 2728 2729
	  pbch_tx_ant,
	  frame_tx,
	  ue->frame_parms.N_RB_DL,
	  ue->frame_parms.phich_config_common.phich_duration,
	  ue->frame_parms.phich_config_common.phich_resource);
2730
#endif
2731

2732
  } else { 
2733

2734
    /*
2735
    LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n",
2736
    ue->Mod_id,frame_rx, subframe_rx);
2737

2738 2739 2740 2741 2742
    LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset);


    write_output("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_tti,1,1);

2743 2744
    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);
2745

2746
    write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1);
2747 2748 2749 2750 2751
    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);
    */
2752

2753 2754
    ue->pbch_vars[eNB_id]->pdu_errors_conseq++;
    ue->pbch_vars[eNB_id]->pdu_errors++;
2755

2756
		// Panos: Substitute call to rrc_out_of_sync_ind() with fill_bch_incication(sync=0).
2757 2758 2759
    if (ue->mac_enabled == 1) rrc_out_of_sync_ind(ue->Mod_id,frame_rx,eNB_id);
    else AssertFatal(ue->pbch_vars[eNB_id]->pdu_errors_conseq<100,
		     "More that 100 consecutive PBCH errors! Exiting!\n");
2760
  }
2761
  
2762

Raymond Knopp's avatar
 
Raymond Knopp committed
2763
  if (frame_rx % 100 == 0) {
2764 2765
    ue->pbch_vars[eNB_id]->pdu_fer = ue->pbch_vars[eNB_id]->pdu_errors - ue->pbch_vars[eNB_id]->pdu_errors_last;
    ue->pbch_vars[eNB_id]->pdu_errors_last = ue->pbch_vars[eNB_id]->pdu_errors;
2766
  }
2767 2768

#ifdef DEBUG_PHY_PROC
2769
  LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
2770 2771 2772
  ue->Mod_id,frame_rx, subframe_rx,
  ue->pbch_vars[eNB_id]->pdu_errors,
  ue->pbch_vars[eNB_id]->pdu_errors_conseq);
2773
#endif
2774
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
2775 2776
}

2777 2778


2779
int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t abstraction_flag)
2780
{
2781 2782

  unsigned int dci_cnt=0, i;
2783

2784 2785
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
2786
  DCI_ALLOC_t dci_alloc_rx[8];
Raymond Knopp's avatar
 
Raymond Knopp committed
2787

2788 2789
  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
2790

2791
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN);
gabrielC's avatar
gabrielC committed
2792
#if UE_TIMING_TRACE
2793
  start_meas(&ue->dlsch_rx_pdcch_stats);
gabrielC's avatar
gabrielC committed
2794
#endif
2795

2796 2797 2798 2799 2800
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
  rx_pdcch(ue,
	   proc->frame_rx,
	   subframe_rx,
	   eNB_id,
2801
	   ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI,
2802
	   ue->high_speed_flag);
2803 2804 2805
  
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN);
2806 2807
  
  
2808 2809 2810 2811 2812
  /*printf("Decode SIB frame param aggregation + DCI %d %d, num_pdcch_symbols %d\n",
	 ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel,
	 ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat,
	 ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
  */
2813 2814
  //agregation level == FF means no configuration on
  if(ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel == 0xFF || ue->decode_SIB)
2815
    {
2816 2817 2818 2819 2820 2821
      // search all possible dcis
      dci_cnt = dci_decoding_procedure(ue,
				       dci_alloc_rx,
				       (ue->UE_mode[eNB_id] < PUSCH)? 1 : 0,  // if we're in PUSCH don't listen to common search space,
				       // later when we need paging or RA during connection, update this ...
				       eNB_id,subframe_rx);
2822
    }
2823
  else
2824
    {
2825 2826 2827 2828 2829 2830 2831 2832
      // search only preconfigured dcis
      // search C RNTI dci
      dci_cnt = dci_CRNTI_decoding_procedure(ue,
					     dci_alloc_rx,
					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat,
					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel,
					     eNB_id,
					     subframe_rx);
2833
    }
2834
  
2835 2836 2837 2838 2839 2840 2841 2842
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
  //LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d PHICH RX\n",ue->Mod_id,frame_rx,subframe_rx);
  
  if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_IN);
    rx_phich(ue,proc,
	     subframe_rx,eNB_id);
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT);
2843
  }
2844
  
2845 2846 2847
  uint8_t *nCCE_current = &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx];
  uint8_t *nCCE_dest = &ue->pdcch_vars[next1_thread_id][eNB_id]->nCCE[subframe_rx];
  uint8_t *nCCE_dest1 = &ue->pdcch_vars[next2_thread_id][eNB_id]->nCCE[subframe_rx];
2848
  memcpy(nCCE_dest, nCCE_current, sizeof(uint8_t));
2849
  memcpy(nCCE_dest1, nCCE_current, sizeof(uint8_t));
2850

2851
  LOG_D(PHY,"current_thread %d next1_thread %d next2_thread %d \n", ue->current_thread_id[subframe_rx], next1_thread_id, next2_thread_id);
2852

2853
  LOG_D(PHY,"[UE  %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n",
hbilel's avatar
hbilel committed
2854 2855 2856
       ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],
       dci_cnt,
       dci_alloc_rx[0].rnti,
2857
       ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
hbilel's avatar
hbilel committed
2858
       dci_alloc_rx[0].format );
2859

2860
  ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dci_received += dci_cnt;
2861

2862 2863 2864
  for (i=0; i<dci_cnt; i++) {


2865

2866
    if ((ue->UE_mode[eNB_id]>PRACH) &&
2867
	(dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) &&
2868 2869
	(dci_alloc_rx[i].format != format0)) {
      
2870
      LOG_D(PHY,"[UE  %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
2871
	    ue->Mod_id,dci_alloc_rx[i].rnti,
2872
	    frame_rx%1024,subframe_rx,
2873
	    dci_alloc_rx[i].format,
2874 2875
	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx],
2876
	    get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
2877
      
2878
      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2879
      
2880
      if ((ue->UE_mode[eNB_id] > PRACH) &&
2881 2882
	  (generate_ue_dlsch_params_from_dci(frame_rx,
					     subframe_rx,
2883
					     (void *)&dci_alloc_rx[i].dci_pdu,
2884
					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
2885
					     dci_alloc_rx[i].format,
2886 2887 2888
					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
					     ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
					     ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id],
2889 2890
					     &ue->frame_parms,
					     ue->pdsch_config_dedicated,
2891 2892
					     SI_RNTI,
					     0,
2893
					     P_RNTI,
2894
					     ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
2895
					     ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti: 0)==0)) {
2896 2897 2898 2899 2900 2901 2902 2903
	
	// update TPC for PUCCH
	if((dci_alloc_rx[i].format == format1)   ||
	   (dci_alloc_rx[i].format == format1A) ||
	   (dci_alloc_rx[i].format == format1B) ||
	   (dci_alloc_rx[i].format == format2)  ||
	   (dci_alloc_rx[i].format == format2A) ||
	   (dci_alloc_rx[i].format == format2B))
hbilel's avatar
hbilel committed
2904
          {
2905 2906
            //ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->g_pucch += ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
            int32_t delta_pucch = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
2907
            for(int th_id=0; th_id<RX_NB_TH; th_id++)
2908
	      {
2909
                ue->dlsch[th_id][eNB_id][0]->g_pucch += delta_pucch;
2910
	      }
2911
            LOG_D(PHY,"update TPC for PUCCH %d.%d / pid %d delta_PUCCH %d g_pucch %d %d \n",frame_rx, subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid,
2912 2913 2914 2915 2916
		  delta_pucch,
		  ue->dlsch[0][eNB_id][0]->g_pucch,
		  ue->dlsch[1][eNB_id][0]->g_pucch
		  //ue->dlsch[2][eNB_id][0]->g_pucch
		  );
hbilel's avatar
hbilel committed
2917
          }
2918
	
2919
	ue->dlsch_received[eNB_id]++;
2920
	
2921
#ifdef DEBUG_PHY_PROC
2922 2923
	LOG_D(PHY,"[UE  %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format);
	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2924
	LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active);
2925
#endif
2926
	
2927 2928
	// we received a CRNTI, so we're in PUSCH
	if (ue->UE_mode[eNB_id] != PUSCH) {
2929
#ifdef DEBUG_PHY_PROC
2930
	  LOG_D(PHY,"[UE  %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti);
2931
#endif
2932
	  
2933 2934
	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
	  ue->UE_mode[eNB_id] = PUSCH;
2935 2936
	}
      } else {
2937 2938
	  LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Problem in DCI!\n",ue->Mod_id,frame_rx,subframe_rx);
	  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
2939
	}
2940
    }
2941 2942 2943
      
      else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
	       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
2944

2945

2946
#ifdef DEBUG_PHY_PROC
2947
	LOG_D(PHY,"[UE  %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
2948
#endif
2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967
	
	if (generate_ue_dlsch_params_from_dci(frame_rx,
					      subframe_rx,
					      (void *)&dci_alloc_rx[i].dci_pdu,
					      SI_RNTI,
					      dci_alloc_rx[i].format,
					      ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
					      ue->pdsch_vars_SI[eNB_id],
					      &ue->dlsch_SI[eNB_id],
					      &ue->frame_parms,
					      ue->pdsch_config_dedicated,
					      SI_RNTI,
					      0,
					      P_RNTI,
					      ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
					      0)==0) {
	  
	  ue->dlsch_SI_received[eNB_id]++;
	  
2968
	  LOG_D(PHY,"[UE  %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C");
2969 2970 2971
	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
	
	}
2972
      }
2973

2974
    else if ((dci_alloc_rx[i].rnti == P_RNTI) &&
2975
       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
2976 2977

#ifdef DEBUG_PHY_PROC
2978
      LOG_D(PHY,"[UE  %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
2979 2980 2981 2982 2983 2984
#endif


      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
					    (void *)&dci_alloc_rx[i].dci_pdu,
2985
					    P_RNTI,
2986
					    dci_alloc_rx[i].format,
2987
					    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
2988
					    ue->pdsch_vars_p[eNB_id],
2989 2990 2991 2992 2993
					    &ue->dlsch_SI[eNB_id],
					    &ue->frame_parms,
					    ue->pdsch_config_dedicated,
					    SI_RNTI,
					    0,
2994
					    P_RNTI,
2995 2996
					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                                            0)==0) {
2997 2998 2999 3000

	ue->dlsch_p_received[eNB_id]++;
	LOG_D(PHY,"[UE  %d] Frame %d, subframe %d : Generate UE DLSCH P_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C");
	//dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
3001
	
3002 3003 3004
      }
    }

3005
    else if ((ue->prach_resources[eNB_id]) &&
3006 3007
       (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) &&
       (dci_alloc_rx[i].format == format1A)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
3008

3009
#ifdef DEBUG_PHY_PROC
3010
      LOG_D(PHY,"[UE  %d][RAPROC] subframe %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,i);
3011 3012 3013
#endif


3014 3015
      if (generate_ue_dlsch_params_from_dci(frame_rx,
					    subframe_rx,
3016 3017 3018
					    (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
					    ue->prach_resources[eNB_id]->ra_RNTI,
					    format1A,
3019
					    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
3020
					    ue->pdsch_vars_ra[eNB_id],
3021 3022 3023 3024 3025
					    &ue->dlsch_ra[eNB_id],
					    &ue->frame_parms,
					    ue->pdsch_config_dedicated,
					    SI_RNTI,
					    ue->prach_resources[eNB_id]->ra_RNTI,
3026
					    P_RNTI,
3027 3028
					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                                            0)==0) {
3029
	
3030
  ue->dlsch_ra_received[eNB_id]++;
3031

3032
#ifdef DEBUG_PHY_PROC
3033 3034
  LOG_D(PHY,"[UE  %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n",
        ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]);
3035
#endif
3036
      }
3037
    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) &&
3038
	       (dci_alloc_rx[i].format == format0)) {
3039

3040
#ifdef DEBUG_PHY_PROC
3041
      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n",
3042
      ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
3043 3044
#endif

3045 3046
      ue->ulsch_no_allocation_counter[eNB_id] = 0;
      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
3047
      
3048
      if ((ue->UE_mode[eNB_id] > PRACH) &&
3049
	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
3050
					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
3051 3052
					     subframe_rx,
					     format0,
3053
					     ue,
3054
					     proc,
3055 3056 3057 3058 3059 3060
					     SI_RNTI,
					     0,
					     P_RNTI,
					     CBA_RNTI,
					     eNB_id,
					     0)==0)) {
3061 3062
#if T_TRACER
    LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
3063 3064 3065 3066
    uint8_t harq_pid = subframe2harq_pid(frame_parms,
                                 pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,proc->subframe_rx),
                                 pdcch_alloc2ul_subframe(frame_parms,proc->subframe_rx));

Cedric Roux's avatar
Cedric Roux committed
3067
    T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx),
3068 3069 3070 3071 3072 3073
      T_INT(dci_alloc_rx[i].rnti), T_INT(harq_pid),
      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs),
      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round),
      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb),
      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb),
      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS));
3074
#endif
3075
#ifdef DEBUG_PHY_PROC
3076
      LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
3077 3078
#endif

3079
      }
3080
    } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) &&
3081
         (dci_alloc_rx[i].format == format0)) {
3082
      // UE could belong to more than one CBA group
3083
      // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups]
3084
#ifdef DEBUG_PHY_PROC
3085
      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n",
3086
      ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
3087
      /*
3088 3089
  if (((frame_rx%100) == 0) || (frame_rx < 20))
  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
3090
      */
3091 3092
#endif

3093 3094
      ue->ulsch_no_allocation_counter[eNB_id] = 0;
      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
3095

3096
      if ((ue->UE_mode[eNB_id] > PRACH) &&
3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108
    (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
               ue->ulsch[eNB_id]->cba_rnti[0],
               subframe_rx,
               format0,
               ue,
               proc,
               SI_RNTI,
               0,
               P_RNTI,
               CBA_RNTI,
               eNB_id,
               0)==0)) {
3109

3110
#ifdef DEBUG_PHY_PROC
3111
  LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
3112
#endif
3113
  ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++;
3114 3115 3116
      }
    }

3117 3118
    else {
#ifdef DEBUG_PHY_PROC
3119
      LOG_D(PHY,"[UE  %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti,
3120
	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
3121 3122
	    ue->ulsch[eNB_id]->cba_rnti[0],
	    dci_alloc_rx[i].format);
3123

3124
      //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
3125 3126
#endif
    }
3127

3128
  }
gabrielC's avatar
gabrielC committed
3129
#if UE_TIMING_TRACE
3130
  stop_meas(&ue->dlsch_rx_pdcch_stats);
gabrielC's avatar
gabrielC committed
3131
#endif
3132
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
3133 3134 3135
  return(0);
}

3136

3137
void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abstraction_flag) {
3138

3139
  int subframe_rx = proc->subframe_rx;
3140
  int frame_rx = proc->frame_rx;
3141
  int pmch_mcs=-1;
3142
#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
3143
  int CC_id = ue->CC_id;
Cedric Roux's avatar
Cedric Roux committed
3144
#endif
3145 3146 3147 3148
  uint8_t sync_area=255;
  uint8_t mcch_active;
  int l;
  int ret=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
3149

3150
  if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) {
3151
    // LOG_D(PHY,"ue calling pmch subframe ..\n ");
3152

3153
    LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n",
3154
    ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx);
3155
#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
3156

3157 3158 3159 3160 3161 3162 3163
    pmch_mcs = ue_query_mch(ue->Mod_id,
			    CC_id,
			    frame_rx,
			    subframe_rx,
			    eNB_id,
			    &sync_area,
			    &mcch_active);
3164 3165 3166
    
#else
    pmch_mcs=-1;
3167
#endif
3168

3169 3170 3171
    if (pmch_mcs>=0) {
      LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Programming PMCH demodulation for mcs %d\n",ue->Mod_id,frame_rx,subframe_rx,pmch_mcs);
      fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0);
3172

3173
      
3174
      for (l=2; l<12; l++) {
3175
	
3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186
	slot_fep_mbsfn(ue,
		       l,
		       subframe_rx,
		       0,0);//ue->rx_offset,0);
      }
      
      for (l=2; l<12; l++) {
	rx_pmch(ue,
		0,
		subframe_rx,
		l);
3187 3188
      }
      
3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212
      
      ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms,
						     ue->dlsch_MCH[0]->harq_processes[0]->nb_rb,
						     ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
						     ue->dlsch_MCH[0]->harq_processes[0]->Qm,
						     1,
						     2,
						     frame_rx,
						     subframe_rx,
						     0);
      
      dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0],
			 ue->dlsch_MCH[0]->harq_processes[0]->G,
			 ue->pdsch_vars_MCH[0]->llr[0],0,subframe_rx<<1);
      
      ret = dlsch_decoding(ue,
			   ue->pdsch_vars_MCH[0]->llr[0],
			   &ue->frame_parms,
			   ue->dlsch_MCH[0],
			   ue->dlsch_MCH[0]->harq_processes[0],
			   frame_rx,
			   subframe_rx,
			   0,
			   0,1);
3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224
      if (mcch_active == 1)
	ue->dlsch_mcch_trials[sync_area][0]++;
      else
	ue->dlsch_mtch_trials[sync_area][0]++;
      
      if (ret == (1+ue->dlsch_MCH[0]->max_turbo_iterations)) {
	if (mcch_active == 1)
	  ue->dlsch_mcch_errors[sync_area][0]++;
	else
	  ue->dlsch_mtch_errors[sync_area][0]++;
	
	LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
Cedric Roux's avatar
Cedric Roux committed
3225 3226
	      ue->Mod_id,
              frame_rx,subframe_rx,
3227 3228 3229 3230 3231 3232
	      ue->dlsch_mcch_errors[sync_area][0],
	      ue->dlsch_mtch_errors[sync_area][0],
	      ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
	      ue->dlsch_MCH[0]->max_turbo_iterations,
	      ue->dlsch_MCH[0]->harq_processes[0]->G);
	dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
3233
#ifdef DEBUG_DLSCH
3234 3235 3236
	
	for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) {
	  LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]);
3237
	}
3238 3239
	
	LOG_T(PHY,"\n");
3240
#endif
3241
	
3242
	
3243 3244
	//	if (subframe_rx==9)
	//  mac_xface->macphy_exit("Why are we exiting here?");
3245
      } else { // decoding successful
3246
#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
3247 3248
	
	if (mcch_active == 1) {
3249 3250 3251 3252 3253 3254 3255
	  ue_send_mch_sdu(ue->Mod_id,
			  CC_id,
			  frame_rx,
			  ue->dlsch_MCH[0]->harq_processes[0]->b,
			  ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
			  eNB_id,// not relevant in eMBMS context
			  sync_area);
3256 3257 3258 3259 3260 3261 3262 3263
	  ue->dlsch_mcch_received[sync_area][0]++;
	  
	  
	  if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) {
	    ue->dlsch_mch_received_sf[subframe_rx%5][0]=0;
	  } else {
	    ue->dlsch_mch_received[0]+=1;
	    ue->dlsch_mch_received_sf[subframe_rx][0]=1;
3264
	  }
3265 3266 3267
	  
	  
	}
3268

3269
#endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
3270 3271 3272 3273
      } // decoding sucessful
    } // pmch_mcs>=0
  } // is_pmch_subframe=true
}
3274

3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316
void copy_harq_proc_struct(LTE_DL_UE_HARQ_t *harq_processes_dest, LTE_DL_UE_HARQ_t *current_harq_processes)
{
      harq_processes_dest->B              = current_harq_processes->B              ;
      harq_processes_dest->C              = current_harq_processes->C              ;
      harq_processes_dest->Cminus         = current_harq_processes->Cminus         ;
      harq_processes_dest->Cplus          = current_harq_processes->Cplus          ;
      harq_processes_dest->DCINdi         = current_harq_processes->DCINdi         ;
      harq_processes_dest->F              = current_harq_processes->F              ;
      harq_processes_dest->G              = current_harq_processes->G              ;
      harq_processes_dest->Kminus         = current_harq_processes->Kminus         ;
      harq_processes_dest->Kplus          = current_harq_processes->Kplus          ;
      harq_processes_dest->Nl             = current_harq_processes->Nl             ;
      harq_processes_dest->Qm             = current_harq_processes->Qm             ;
      harq_processes_dest->TBS            = current_harq_processes->TBS            ;
      harq_processes_dest->b              = current_harq_processes->b              ;
      harq_processes_dest->codeword       = current_harq_processes->codeword       ;
      harq_processes_dest->delta_PUCCH    = current_harq_processes->delta_PUCCH    ;
      harq_processes_dest->dl_power_off   = current_harq_processes->dl_power_off   ;
      harq_processes_dest->first_tx       = current_harq_processes->first_tx       ;
      harq_processes_dest->mcs            = current_harq_processes->mcs            ;
      harq_processes_dest->mimo_mode      = current_harq_processes->mimo_mode      ;
      harq_processes_dest->nb_rb          = current_harq_processes->nb_rb          ;
      harq_processes_dest->pmi_alloc      = current_harq_processes->pmi_alloc      ;
      harq_processes_dest->rb_alloc_even[0]  = current_harq_processes->rb_alloc_even[0] ;
      harq_processes_dest->rb_alloc_even[1]  = current_harq_processes->rb_alloc_even[1] ;
      harq_processes_dest->rb_alloc_even[2]  = current_harq_processes->rb_alloc_even[2] ;
      harq_processes_dest->rb_alloc_even[3]  = current_harq_processes->rb_alloc_even[3] ;
      harq_processes_dest->rb_alloc_odd[0]  = current_harq_processes->rb_alloc_odd[0]  ;
      harq_processes_dest->rb_alloc_odd[1]  = current_harq_processes->rb_alloc_odd[1]  ;
      harq_processes_dest->rb_alloc_odd[2]  = current_harq_processes->rb_alloc_odd[2]  ;
      harq_processes_dest->rb_alloc_odd[3]  = current_harq_processes->rb_alloc_odd[3]  ;
      harq_processes_dest->round          = current_harq_processes->round          ;
      harq_processes_dest->rvidx          = current_harq_processes->rvidx          ;
      harq_processes_dest->status         = current_harq_processes->status         ;
      harq_processes_dest->vrb_type       = current_harq_processes->vrb_type       ;
}

void copy_ack_struct(harq_status_t *harq_ack_dest, harq_status_t *current_harq_ack)
{
    memcpy(harq_ack_dest, current_harq_ack, sizeof(harq_status_t));
}

3317
void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, LTE_UE_DLSCH_t *dlsch0, LTE_UE_DLSCH_t *dlsch1, int s0, int s1, int abstraction_flag) {
3318

3319 3320 3321 3322 3323
  int subframe_rx = proc->subframe_rx;
  int m;
  int harq_pid;
  int i_mod,eNB_id_i,dual_stream_UE;
  int first_symbol_flag=0;
3324

3325 3326
  if (dlsch0->active == 0)
    return;
3327

3328
  for (m=s0;m<=s1;m++) {
3329

3330 3331
    if (dlsch0 && (!dlsch1))  {
      harq_pid = dlsch0->current_harq_pid;
hbilel's avatar
hbilel committed
3332
      LOG_D(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d Symbol %d\n",ue->Mod_id,subframe_rx,harq_pid,m);
3333

3334 3335 3336 3337 3338 3339 3340
      if ((pdsch==PDSCH) &&
          (ue->transmission_mode[eNB_id] == 5) &&
          (dlsch0->harq_processes[harq_pid]->dl_power_off==0) &&
          (ue->use_ia_receiver ==1)) {
        dual_stream_UE = 1;
        eNB_id_i = ue->n_connected_eNB;
        i_mod =  dlsch0->harq_processes[harq_pid]->Qm;
3341

hbilel's avatar
hbilel committed
3342 3343 3344 3345 3346 3347 3348 3349
      }
      else if((pdsch==PDSCH) && (ue->transmission_mode[eNB_id]==3))
      {
          dual_stream_UE = rx_IC_dual_stream;
          eNB_id_i       = eNB_id;
          i_mod          = 0;
      }
      else {
3350 3351 3352
        dual_stream_UE = 0;
        eNB_id_i = eNB_id+1;
        i_mod = 0;
3353
      }
3354

3355 3356 3357
      //TM7 UE specific channel estimation here!!!
      if (ue->transmission_mode[eNB_id]==7) {
        if (ue->frame_parms.Ncp==0) {
Xiwen JIANG's avatar
Xiwen JIANG committed
3358
          if ((m==3) || (m==6) || (m==9) || (m==12))
3359 3360
            //LOG_D(PHY,"[UE %d] dlsch->active in subframe %d => %d, l=%d\n",phy_vars_ue->Mod_id,subframe_rx,phy_vars_ue->dlsch_ue[eNB_id][0]->active, l);
            lte_dl_bf_channel_estimation(ue,eNB_id,0,subframe_rx*2+(m>6?1:0),5,m);
3361
        } else {
3362
          LOG_E(PHY,"[UE %d]Beamforming channel estimation not supported yet for TM7 extented CP.\n",ue->Mod_id);
3363
        }
3364
      }
3365

3366
      if ((m==s0) && (m<4))
3367
          first_symbol_flag = 1;
3368
      else
3369
          first_symbol_flag = 0;
gabrielC's avatar
gabrielC committed
3370
#if UE_TIMING_TRACE
3371 3372 3373
      uint8_t slot = 0;
      if(m >= ue->frame_parms.symbols_per_tti>>1)
        slot = 1;
tct-labo4's avatar
tct-labo4 committed
3374
      start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]);
gabrielC's avatar
gabrielC committed
3375
#endif
3376 3377 3378 3379 3380
      // process DLSCH received in first slot
      rx_pdsch(ue,
	       pdsch,
	       eNB_id,
	       eNB_id_i,
3381
	       proc->frame_rx,
3382 3383 3384 3385 3386 3387
	       subframe_rx,  // subframe,
	       m,
	       first_symbol_flag,
	       dual_stream_UE,
	       i_mod,
	       dlsch0->current_harq_pid);
gabrielC's avatar
gabrielC committed
3388
#if UE_TIMING_TRACE
tct-labo4's avatar
tct-labo4 committed
3389
      stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]);
3390
#if DISABLE_LOG_X
tct-labo4's avatar
tct-labo4 committed
3391
    printf("[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0));
3392
#else
tct-labo4's avatar
tct-labo4 committed
3393
    LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0));
gabrielC's avatar
gabrielC committed
3394
#endif
3395 3396
#endif

3397

3398 3399 3400 3401
      if(first_symbol_flag)
      {
          proc->first_symbol_available = 1;
      }
3402
    } // CRNTI active
3403
  }
3404
}
3405

3406
void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
3407

3408 3409 3410 3411 3412 3413
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
  int timing_advance;
  LTE_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[eNB_id];
  int harq_pid = 0;
  uint8_t *rar;
3414 3415
  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
3416

3417
  LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Received RAR  mode %d\n",
3418 3419 3420 3421 3422
  ue->Mod_id,
  frame_rx,
  subframe_rx, ue->UE_mode[eNB_id]);


3423
  if (ue->mac_enabled == 1) {
3424 3425
    if ((ue->UE_mode[eNB_id] != PUSCH) &&
  (ue->prach_resources[eNB_id]->Msg3!=NULL)) {
3426 3427 3428 3429 3430
      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n",
	    ue->Mod_id,frame_rx,
	    subframe_rx,
	    ue->prach_resources[eNB_id]->ra_PreambleIndex);
      
3431
      // Panos: Substitute call to ue_process_rar() with call to fill_dlsch_rar_indication()
3432 3433 3434 3435 3436
      timing_advance = ue_process_rar(ue->Mod_id,
				      ue->CC_id,
				      frame_rx,
				      ue->prach_resources[eNB_id]->ra_RNTI,
				      dlsch0->harq_processes[0]->b,
3437
				      &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
3438 3439 3440
				      ue->prach_resources[eNB_id]->ra_PreambleIndex,
				      dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
      
3441 3442
      ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
      ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
3443

3444 3445
      
      if (timing_advance!=0xffff) {
3446

3447
              LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n",
3448 3449 3450
              ue->Mod_id,
              frame_rx,
              subframe_rx,
3451
              ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
3452
              timing_advance);
3453

3454
	      // remember this c-rnti is still a tc-rnti
3455
	      
3456
	      ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti_is_temporary = 1;
3457
	      
3458 3459
	      //timing_advance = 0;
	      process_timing_advance_rar(ue,proc,timing_advance);
3460
	      
3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484
	      if (mode!=debug_prach) {
		ue->ulsch_Msg3_active[eNB_id]=1;
		get_Msg3_alloc(&ue->frame_parms,
			       subframe_rx,
			       frame_rx,
			       &ue->ulsch_Msg3_frame[eNB_id],
			       &ue->ulsch_Msg3_subframe[eNB_id]);
		
		LOG_D(PHY,"[UE  %d][RAPROC] Got Msg3_alloc Frame %d subframe %d: Msg3_frame %d, Msg3_subframe %d\n",
		      ue->Mod_id,
		      frame_rx,
		      subframe_rx,
		      ue->ulsch_Msg3_frame[eNB_id],
		      ue->ulsch_Msg3_subframe[eNB_id]);
		harq_pid = subframe2harq_pid(&ue->frame_parms,
					     ue->ulsch_Msg3_frame[eNB_id],
					     ue->ulsch_Msg3_subframe[eNB_id]);
		ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
		
		ue->UE_mode[eNB_id] = RA_RESPONSE;
		//      ue->Msg3_timer[eNB_id] = 10;
		ue->ulsch[eNB_id]->power_offset = 6;
		ue->ulsch_no_allocation_counter[eNB_id] = 0;
	      }
3485 3486 3487 3488
      } else { // PRACH preamble doesn't match RAR
	LOG_W(PHY,"[UE  %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n",
	      ue->Mod_id,
	      ue->prach_resources[eNB_id]->ra_PreambleIndex);
3489
      }
3490 3491 3492 3493 3494 3495 3496 3497 3498
    } // mode != PUSCH
  }
  else {
    rar = dlsch0->harq_processes[0]->b+1;
    timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
    process_timing_advance_rar(ue,proc,timing_advance);
  }
  
}
3499

3500 3501 3502 3503 3504 3505 3506 3507 3508
void ue_dlsch_procedures(PHY_VARS_UE *ue,
       UE_rxtx_proc_t *proc,
       int eNB_id,
       PDSCH_t pdsch,
       LTE_UE_DLSCH_t *dlsch0,
       LTE_UE_DLSCH_t *dlsch1,
       int *dlsch_errors,
       runmode_t mode,
       int abstraction_flag) {
3509

3510 3511 3512
  int harq_pid;
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
hbilel's avatar
hbilel committed
3513
  int ret=0, ret1=0;
3514 3515
  int CC_id = ue->CC_id;
  LTE_UE_PDSCH *pdsch_vars;
hbilel's avatar
hbilel committed
3516 3517 3518 3519 3520
  uint8_t is_cw0_active = 0;
  uint8_t is_cw1_active = 0;

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

hbilel's avatar
hbilel committed
3522 3523 3524 3525 3526 3527 3528 3529
  harq_pid = dlsch0->current_harq_pid;
  is_cw0_active = dlsch0->harq_processes[harq_pid]->status;

  if(dlsch1)
    is_cw1_active = dlsch1->harq_processes[harq_pid]->status;

  LOG_D(PHY,"AbsSubframe %d.%d Start Turbo Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, subframe_rx, harq_pid, is_cw0_active);
  LOG_D(PHY,"AbsSubframe %d.%d Start Turbo Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, subframe_rx, harq_pid, is_cw1_active);
3530

hbilel's avatar
hbilel committed
3531 3532 3533 3534 3535 3536 3537 3538 3539 3540
  if(is_cw0_active && is_cw1_active)
  {
      dlsch0->Kmimo = 2;
      dlsch1->Kmimo = 2;
  }
  else
  {
      dlsch0->Kmimo = 1;
  }
  if (1) {
3541 3542 3543 3544 3545 3546 3547
    switch (pdsch) {
    case SI_PDSCH:
      pdsch_vars = ue->pdsch_vars_SI[eNB_id];
      break;
    case RA_PDSCH:
      pdsch_vars = ue->pdsch_vars_ra[eNB_id];
      break;
3548 3549 3550
    case P_PDSCH:
      pdsch_vars = ue->pdsch_vars_p[eNB_id];
      break;
3551
    case PDSCH:
3552
      pdsch_vars = ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id];
3553 3554 3555 3556 3557 3558 3559
      break;
    case PMCH:
    case PDSCH1:
      LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch);
      pdsch_vars = NULL;
      return;
      break;
3560 3561 3562 3563 3564
    default:
      pdsch_vars = NULL;
      return;
      break;

3565 3566 3567
    }
    if (frame_rx < *dlsch_errors)
      *dlsch_errors=0;
3568

3569
    if (pdsch==RA_PDSCH) {
3570
      
3571
      if (ue->prach_resources[eNB_id]!=NULL)
3572
	dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
3573
      else {
3574 3575
	LOG_E(PHY,"[UE %d] Frame %d, subframe %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,subframe_rx);
	AssertFatal(1==0,"prach_resources is NULL");
3576 3577
      }
    }
3578
    
3579
      
hbilel's avatar
hbilel committed
3580
      // start turbo decode for CW 0
3581 3582 3583 3584 3585
      dlsch0->harq_processes[harq_pid]->G = get_G(&ue->frame_parms,
						  dlsch0->harq_processes[harq_pid]->nb_rb,
						  dlsch0->harq_processes[harq_pid]->rb_alloc_even,
						  dlsch0->harq_processes[harq_pid]->Qm,
						  dlsch0->harq_processes[harq_pid]->Nl,
3586
						  ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
3587 3588 3589
						  frame_rx,
						  subframe_rx,
						  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
gabrielC's avatar
gabrielC committed
3590
#if UE_TIMING_TRACE
3591
      start_meas(&ue->dlsch_unscrambling_stats);
gabrielC's avatar
gabrielC committed
3592
#endif
3593 3594
      dlsch_unscrambling(&ue->frame_parms,
			 0,
3595
			 dlsch0,
3596 3597 3598 3599
			 dlsch0->harq_processes[harq_pid]->G,
			 pdsch_vars->llr[0],
			 0,
			 subframe_rx<<1);
gabrielC's avatar
gabrielC committed
3600
#if UE_TIMING_TRACE
3601
      stop_meas(&ue->dlsch_unscrambling_stats);
gabrielC's avatar
gabrielC committed
3602
#endif
3603
      
hbilel's avatar
hbilel committed
3604 3605 3606 3607 3608 3609 3610 3611
#if 0
      LOG_I(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d  ------  \n", frame_rx, subframe_rx, harq_pid);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo);
3612
      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
hbilel's avatar
hbilel committed
3613
#endif
3614
      
gabrielC's avatar
gabrielC committed
3615
#if UE_TIMING_TRACE
3616
      start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
gabrielC's avatar
gabrielC committed
3617
#endif
3618 3619 3620 3621 3622
      ret = dlsch_decoding(ue,
			   pdsch_vars->llr[0],
			   &ue->frame_parms,
			   dlsch0,
			   dlsch0->harq_processes[harq_pid],
3623
			   frame_rx,
3624 3625 3626
			   subframe_rx,
			   harq_pid,
			   pdsch==PDSCH?1:0,
3627
			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
3628
      
3629
#if UE_TIMING_TRACE
3630
      stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
Cedric Roux's avatar
Cedric Roux committed
3631
#if DISABLE_LOG_X
gabrielC's avatar
gabrielC committed
3632
      printf(" --> Unscrambling for CW0 %5.3f\n",
3633
	     (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
gabrielC's avatar
gabrielC committed
3634
      printf("AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
3635
	     frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
3636 3637
#else
      LOG_D(PHY, " --> Unscrambling for CW0 %5.3f\n",
3638
	    (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
3639
      LOG_D(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
3640
	    frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
3641
#endif
3642
      
gabrielC's avatar
gabrielC committed
3643
#endif
hbilel's avatar
hbilel committed
3644
      if(is_cw1_active)
3645
	{
hbilel's avatar
hbilel committed
3646 3647
          // start turbo decode for CW 1
          dlsch1->harq_processes[harq_pid]->G = get_G(&ue->frame_parms,
3648 3649 3650 3651 3652 3653 3654 3655
						      dlsch1->harq_processes[harq_pid]->nb_rb,
						      dlsch1->harq_processes[harq_pid]->rb_alloc_even,
						      dlsch1->harq_processes[harq_pid]->Qm,
						      dlsch1->harq_processes[harq_pid]->Nl,
						      ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
						      frame_rx,
						      subframe_rx,
						      ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
gabrielC's avatar
gabrielC committed
3656
#if UE_TIMING_TRACE
hbilel's avatar
hbilel committed
3657
          start_meas(&ue->dlsch_unscrambling_stats);
gabrielC's avatar
gabrielC committed
3658
#endif
hbilel's avatar
hbilel committed
3659
          dlsch_unscrambling(&ue->frame_parms,
3660 3661 3662 3663 3664 3665
			     0,
			     dlsch1,
			     dlsch1->harq_processes[harq_pid]->G,
			     pdsch_vars->llr[1],
			     1,
			     subframe_rx<<1);
gabrielC's avatar
gabrielC committed
3666
#if UE_TIMING_TRACE
hbilel's avatar
hbilel committed
3667
          stop_meas(&ue->dlsch_unscrambling_stats);
gabrielC's avatar
gabrielC committed
3668
#endif
3669
	  
hbilel's avatar
hbilel committed
3670 3671 3672 3673 3674 3675 3676
#if 0
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G);
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo);
3677
          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
hbilel's avatar
hbilel committed
3678
#endif
3679
	  
gabrielC's avatar
gabrielC committed
3680
#if UE_TIMING_TRACE
3681
          start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
gabrielC's avatar
gabrielC committed
3682
#endif
3683
	  
hbilel's avatar
hbilel committed
3684
          ret1 = dlsch_decoding(ue,
3685 3686 3687 3688 3689 3690 3691 3692 3693 3694
				pdsch_vars->llr[1],
				&ue->frame_parms,
				dlsch1,
				dlsch1->harq_processes[harq_pid],
				frame_rx,
				subframe_rx,
				harq_pid,
				pdsch==PDSCH?1:0,
				dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
	  
3695
#if UE_TIMING_TRACE
3696
          stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
Cedric Roux's avatar
Cedric Roux committed
3697
#if DISABLE_LOG_X
gabrielC's avatar
gabrielC committed
3698
          printf(" --> Unscrambling for CW1 %5.3f\n",
3699
		 (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
gabrielC's avatar
gabrielC committed
3700
          printf("AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
3701
		 frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
3702 3703
#else
          LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n",
3704
		(ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
3705
          LOG_D(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
3706
		frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
3707
#endif
3708
	  
gabrielC's avatar
gabrielC committed
3709
#endif
3710
          LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
3711 3712 3713
		frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
	}
      
3714
      LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------  \n", frame_rx, subframe_rx);
3715
    
3716
    
3717

hbilel's avatar
hbilel committed
3718
    // Check CRC for CW 0
3719 3720
    if (ret == (1+dlsch0->max_turbo_iterations)) {
      *dlsch_errors=*dlsch_errors+1;
3721

3722 3723
      if(dlsch0->rnti != 0xffff)
      {
3724

3725 3726 3727 3728 3729 3730 3731
	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,
	      harq_pid,frame_rx,subframe_rx,
	      dlsch0->harq_processes[harq_pid]->rvidx,
	      dlsch0->harq_processes[harq_pid]->round,
	      dlsch0->harq_processes[harq_pid]->mcs,
	      dlsch0->harq_processes[harq_pid]->TBS);
3732
      }
3733

3734

3735
    } else {
3736 3737
        if(dlsch0->rnti != 0xffff)
        {
3738
      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n",
3739 3740 3741
            ue->Mod_id,dlsch0->rnti,
            harq_pid,frame_rx,subframe_rx,
            dlsch0->harq_processes[harq_pid]->rvidx,
3742
            dlsch0->harq_processes[harq_pid]->round,
3743 3744
            dlsch0->harq_processes[harq_pid]->mcs,
            dlsch0->harq_processes[harq_pid]->TBS);
3745
        }
3746

3747 3748 3749
#ifdef DEBUG_DLSCH
      int j;
      LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
3750

3751
      for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
3752 3753
  LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);

3754
      LOG_T(PHY,"\n");
3755
#endif
3756

3757

3758
      if (ue->mac_enabled == 1) {
3759
	
3760 3761
	switch (pdsch) {
	case PDSCH:
3762
		// Panos: Substitute call to ue_send_sdu() with call to fill_dlsch_indication()
3763 3764 3765 3766 3767 3768 3769
	  ue_send_sdu(ue->Mod_id,
		      CC_id,
		      frame_rx,
		      subframe_rx,
		      dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
		      dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3,
		      eNB_id);
3770 3771
	  break;
	case SI_PDSCH:
3772
		// Panos: Substitute call with call to fill_dlsch_indication()
3773 3774 3775 3776 3777 3778
	  ue_decode_si(ue->Mod_id,
		       CC_id,
		       frame_rx,
		       eNB_id,
		       ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
		       ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
3779
	  break;
3780
	case P_PDSCH:
3781 3782
		// Panos: Substitute call with call to fill_dlsch_indication()
		ue_decode_p(ue->Mod_id,
3783 3784 3785 3786 3787
		      CC_id,
		      frame_rx,
		      eNB_id,
		      ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
		      ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
3788
	  break;
3789
	case RA_PDSCH:
3790
		// Panos: Substitute with call to fill_dlsch_rar_indication()
3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801
	  process_rar(ue,proc,eNB_id,mode,abstraction_flag);
	  break;
	case PDSCH1:
	  LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n");
	  AssertFatal(1==0,"exiting");
	  break;
	case PMCH:
	  LOG_E(PHY,"Shouldn't have PMCH here\n");
	  AssertFatal(1==0,"exiting");
	  break;
	}
3802
      }
3803 3804 3805 3806 3807
      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;
    }
hbilel's avatar
hbilel committed
3808 3809
    // Check CRC for CW 1
    if(is_cw1_active)
3810
      {
hbilel's avatar
hbilel committed
3811
        if (ret1 == (1+dlsch0->max_turbo_iterations)) {
3812
	  LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n",
3813 3814 3815 3816 3817 3818
		ue->Mod_id,dlsch0->rnti,
		harq_pid,frame_rx,subframe_rx,
		dlsch0->harq_processes[harq_pid]->rvidx,
		dlsch0->harq_processes[harq_pid]->mcs,
		dlsch0->harq_processes[harq_pid]->TBS);
	  
hbilel's avatar
hbilel committed
3819
        } else {
3820
	  LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n",
3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848
		ue->Mod_id,dlsch0->rnti,
		harq_pid,frame_rx,subframe_rx,
		dlsch0->harq_processes[harq_pid]->rvidx,
		dlsch0->harq_processes[harq_pid]->mcs,
		dlsch0->harq_processes[harq_pid]->TBS);
	  
	  
	  if (ue->mac_enabled == 1) {
	    switch (pdsch) {
	    case PDSCH:
	      if(is_cw1_active)
		ue_send_sdu(ue->Mod_id,
			    CC_id,
			    frame_rx,
			    subframe_rx,
			    dlsch1->harq_processes[dlsch1->current_harq_pid]->b,
			    dlsch1->harq_processes[dlsch1->current_harq_pid]->TBS>>3,
			    eNB_id);
	      break;
	    case SI_PDSCH:
	    case P_PDSCH:
	    case RA_PDSCH:
	    case PDSCH1:
	    case PMCH:
	      AssertFatal(0,"exiting");
	      break;
	    }
	  }
hbilel's avatar
hbilel committed
3849
        }
3850 3851
      }
    
3852
#ifdef DEBUG_PHY_PROC
3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869
    LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n",
	  ue->Mod_id,
	  dlsch0->rnti,harq_pid,
	  frame_rx,subframe_rx,ret,
	  dlsch0->harq_processes[harq_pid]->mcs,
	  dlsch0->harq_processes[harq_pid]->rvidx,
	  dlsch0->harq_processes[harq_pid]->TBS);
    
    if (frame_rx%100==0) {
      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n",
	    ue->Mod_id,dlsch0->rnti,
	    frame_rx,subframe_rx,
	    ue->dlsch_errors[eNB_id],
	    ue->dlsch_received[eNB_id],
	    ue->dlsch_fer[eNB_id],
	    ue->measurements.wideband_cqi_tot[eNB_id]);
    }
3870
    
3871
#endif
3872
    
3873
  }
3874
  
3875
  
3876
}
3877

3878 3879 3880 3881 3882 3883
/*!
 * \brief This is the UE synchronize thread.
 * It performs band scanning and synchonization.
 * \param arg is a pointer to a \ref PHY_VARS_UE structure.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
3884
#ifdef UE_SLOT_PARALLELISATION
3885
#define FIFO_PRIORITY   40
3886
void *UE_thread_slot1_dl_processing(void *arg) {
3887

3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947
    static __thread int UE_dl_slot1_processing_retval;
    struct rx_tx_thread_data *rtd = arg;
    UE_rxtx_proc_t *proc = rtd->proc;
    PHY_VARS_UE    *ue   = rtd->UE;

    int frame_rx;
    uint8_t subframe_rx;
    uint8_t pilot0;
    uint8_t pilot1;
    uint8_t slot1;

    uint8_t next_subframe_rx;
    uint8_t next_subframe_slot0;

    proc->instance_cnt_slot1_dl_processing=-1;
    proc->subframe_rx=proc->sub_frame_start;

    char threadname[256];
    sprintf(threadname,"UE_thread_slot1_dl_processing_%d", proc->sub_frame_start);

    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);
    if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 )
        CPU_SET(threads.slot1_proc_two, &cpuset);
    if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 )
        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");
        }

        /*for(int th_idx=0; th_idx< RX_NB_TH; th_idx++)
        {
        frame_rx    = ue->proc.proc_rxtx[0].frame_rx;
        subframe_rx = ue->proc.proc_rxtx[0].subframe_rx;
        printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx);
        }*/
        frame_rx    = proc->frame_rx;
        subframe_rx = proc->subframe_rx;
        next_subframe_rx    = (1+subframe_rx)%10;
        next_subframe_slot0 = next_subframe_rx<<1;

        slot1  = (subframe_rx<<1) + 1;
        pilot0 = 0;

3948
        //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx);
3949 3950 3951 3952 3953 3954 3955 3956 3957

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

        /**** Slot1 FE Processing ****/
#if UE_TIMING_TRACE
3958
        start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996
#endif
        // I- start dl slot1 processing
        // do first symbol of next downlink subframe for channel estimation
        /*
        // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next subframe ofdmSym11)
        if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
        {
            front_end_fft(ue,
                    pilot0,
                    next_subframe_slot0,
                    0,
                    0);
        }

        front_end_fft(ue,
                pilot1,
                slot1,
                0,
                0);
         */
        // 1- perform FFT
        for (int l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
        {
            //if( (l != pilot0) && (l != pilot1))
            {
#if UE_TIMING_TRACE
                start_meas(&ue->ofdm_demod_stats);
#endif
                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
                //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l);
                front_end_fft(ue,
                        l,
                        slot1,
                        0,
                        0);
                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
#if UE_TIMING_TRACE
                stop_meas(&ue->ofdm_demod_stats);
3997
#endif
3998 3999
            }
        } // for l=1..l2
4000

4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022
        if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
        {
            //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0);
            front_end_fft(ue,
                    pilot0,
                    next_subframe_slot0,
                    0,
                    0);
        }

        // 2- perform Channel Estimation for slot1
        for (int l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
        {
            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++;
                }
4023
                //printf("[slot1 dl processing] ChanEst symbol %d slot %d wait%d\n",l,slot1,wait);
4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043
            }
            //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l);
            front_end_chanEst(ue,
                    l,
                    slot1,
                    0);
            ue_measurement_procedures(l-1,ue,proc,0,1+(subframe_rx<<1),0,ue->mode);
        }
        //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0);
        front_end_chanEst(ue,
                pilot0,
                next_subframe_slot0,
                0);

        if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
        {
            ue_pbch_procedures(0,ue,proc,0);
        }

        proc->chan_est_slot1_available = 1;
4044 4045
        //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
        //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
4046 4047 4048 4049 4050

        //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);


#if UE_TIMING_TRACE
4051
        stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
4052
#if DISABLE_LOG_X
4053
        printf("[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
4054
#else
4055
        LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
4056
#endif
4057

4058 4059 4060 4061 4062 4063 4064 4065 4066 4067
#endif


    //wait until pdcch is decoded
    uint32_t wait = 0;
    while(proc->dci_slot0_available == 0)
    {
        usleep(1);
        wait++;
    }
4068
    //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,subframe_rx,wait);
4069 4070 4071 4072 4073


    /**** Pdsch Procedure Slot1 ****/
    // start slot1 thread for Pdsch Procedure (slot1)
    // do procedures for C-RNTI
4074
    //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,subframe_rx);
4075 4076 4077


#if UE_TIMING_TRACE
4078
    start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
4079 4080 4081 4082 4083
#endif
    // start slave thread for Pdsch Procedure (slot1)
    // do procedures for C-RNTI
    uint8_t eNB_id = 0;
    uint8_t abstraction_flag = 0;
4084
    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098
        //wait until first ofdm symbol is processed
        //wait = 0;
        //while(proc->first_symbol_available == 0)
        //{
        //    usleep(1);
        //    wait++;
        //}
        //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,subframe_rx,wait);

        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                PDSCH,
4099
                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146
                NULL,
                (ue->frame_parms.symbols_per_tti>>1),
                ue->frame_parms.symbols_per_tti-1,
                abstraction_flag);
        LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
        LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
    }

    // do procedures for SI-RNTI
    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                SI_PDSCH,
                ue->dlsch_SI[eNB_id],
                NULL,
                (ue->frame_parms.symbols_per_tti>>1),
                ue->frame_parms.symbols_per_tti-1,
                abstraction_flag);
    }

    // do procedures for P-RNTI
    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                P_PDSCH,
                ue->dlsch_p[eNB_id],
                NULL,
                (ue->frame_parms.symbols_per_tti>>1),
                ue->frame_parms.symbols_per_tti-1,
                abstraction_flag);
    }
    // do procedures for RA-RNTI
    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                RA_PDSCH,
                ue->dlsch_ra[eNB_id],
                NULL,
                (ue->frame_parms.symbols_per_tti>>1),
                ue->frame_parms.symbols_per_tti-1,
                abstraction_flag);
    }

    proc->llr_slot1_available=1;
4147
    //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
4148 4149

#if UE_TIMING_TRACE
4150
    stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
4151
#if DISABLE_LOG_X
4152
    printf("[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
4153
#else
4154
    LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172
#endif
#endif


        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");
        }
    }
    // thread finished
        free(arg);
        return &UE_dl_slot1_processing_retval;
}
4173
#endif
4174

4175
#ifdef UE_SLOT_PARALLELISATION
4176
int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
4177
        uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode)  {
4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189

    int l,l2;
    int pmch_flag=0;
    int frame_rx = proc->frame_rx;
    int subframe_rx = proc->subframe_rx;
    uint8_t pilot0;
    uint8_t pilot1;
    uint8_t slot0;
    uint8_t slot1;
    uint8_t first_ofdm_sym;

    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
4190

4191
#if T_TRACER
4192 4193 4194
    T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));

    T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0),
fnabet's avatar
fnabet committed
4195 4196 4197
            T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti],
                    ue->frame_parms.samples_per_tti * 4));
#endif
4198 4199

    // start timers
fnabet's avatar
fnabet committed
4200
#ifdef UE_DEBUG_TRACE
4201
    LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
fnabet's avatar
fnabet committed
4202 4203 4204
#endif

#if UE_TIMING_TRACE
4205 4206
    start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
    start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]);
fnabet's avatar
fnabet committed
4207
#endif
4208 4209 4210

    pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;

fnabet's avatar
fnabet committed
4211 4212
    if (do_pdcch_flag) {
        // deactivate reception until we scan pdcch
4213 4214 4215 4216
        if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0])
            ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0;
        if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1])
            ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0;
fnabet's avatar
fnabet committed
4217 4218 4219 4220 4221 4222 4223 4224 4225 4226

        if (ue->dlsch_SI[eNB_id])
            ue->dlsch_SI[eNB_id]->active = 0;
        if (ue->dlsch_p[eNB_id])
            ue->dlsch_p[eNB_id]->active = 0;
        if (ue->dlsch_ra[eNB_id])
            ue->dlsch_ra[eNB_id]->active = 0;
    }

#ifdef DEBUG_PHY_PROC
4227
    LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n",
fnabet's avatar
fnabet committed
4228 4229
                    ue->Mod_id,frame_rx, subframe_rx);
#endif
4230 4231 4232



fnabet's avatar
fnabet committed
4233 4234 4235 4236 4237 4238 4239 4240 4241

    if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only
        l2 = 5;
    } else if (pmch_flag == 1) { // do first 2 symbols only
        l2 = 1;
    } else { // normal subframe, last symbol to be processed is the first of the second slot
        l2 = (ue->frame_parms.symbols_per_tti/2)-1;
    }

4242 4243
    int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1);
    if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) {
fnabet's avatar
fnabet committed
4244 4245 4246 4247
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // RX processing of symbols l=0...l2
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        first_ofdm_sym = 0;
4248
    } else {
fnabet's avatar
fnabet committed
4249 4250 4251 4252
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        first_ofdm_sym = 1;
4253 4254 4255 4256 4257
    }
    slot0  = (subframe_rx<<1);
    slot1  = (subframe_rx<<1) + 1;
    pilot0 = 0;
    if (ue->frame_parms.Ncp == 0) {  // normal prefix
fnabet's avatar
fnabet committed
4258
        pilot1 = 4;
4259
    } else { // extended prefix
fnabet's avatar
fnabet committed
4260
        pilot1 = 3;
4261
    }
Cedric Roux's avatar
Cedric Roux committed
4262

4263 4264 4265 4266 4267 4268 4269
    //LOG_I(PHY,"Set available channelEst to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
    //LOG_I(PHY,"Set available llrs slot1 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
    //LOG_I(PHY,"Set available dci info slot0 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
    proc->chan_est_pilot0_slot1_available=0;
    proc->llr_slot1_available=0;
    proc->dci_slot0_available=0;
    proc->first_symbol_available=0;
4270
    proc->chan_est_slot1_available=0;
tct-labo4's avatar
tct-labo4 committed
4271
    //proc->channel_level=0;
4272

4273 4274 4275 4276 4277 4278 4279 4280
    if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
        LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE slot1 dl processing\n",ue->Mod_id );
        exit_fun("nothing to add");
    }

    proc->instance_cnt_slot1_dl_processing++;
    if (proc->instance_cnt_slot1_dl_processing == 0)
    {
4281
    LOG_D(PHY,"unblock slot1 dl processing thread blocked on instance_cnt_slot1_dl_processing : %d \n", proc->instance_cnt_slot1_dl_processing );
4282 4283
        if (pthread_cond_signal(&proc->cond_slot1_dl_processing) != 0) {
            LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE slot1 processing thread\n", ue->Mod_id);
fnabet's avatar
fnabet committed
4284 4285
            exit_fun("nothing to add");
        }
4286 4287 4288 4289 4290 4291 4292 4293 4294 4295
        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
            LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE slot1 dl processing \n",ue->Mod_id );
            exit_fun("nothing to add");
        }

    } else
    {
        LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", ue->Mod_id, proc->instance_cnt_slot1_dl_processing);
        if (proc->instance_cnt_slot1_dl_processing > 2)
            exit_fun("instance_cnt_slot1_dl_processing > 2");
4296
    }
4297 4298
    //AssertFatal(pthread_cond_signal(&proc->cond_slot1_dl_processing) ==0 ,"");
    AssertFatal(pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) ==0,"");
4299

4300 4301

    /**** Slot0 FE Processing ****/
4302
    // I- start main thread for FFT/ChanEst symbol: 0/1 --> 7
fnabet's avatar
fnabet committed
4303
#if UE_TIMING_TRACE
4304
    start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
fnabet's avatar
fnabet committed
4305
#endif
4306
    // 1- perform FFT for pilot ofdm symbols first (ofdmSym7 ofdmSym4 or (ofdmSym6 ofdmSym3))
4307
    //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0);
4308 4309 4310 4311 4312
    front_end_fft(ue,
            pilot0,
            slot1,
            0,
            0);
4313
    //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1);
4314 4315 4316 4317 4318
    front_end_fft(ue,
            pilot1,
            slot0,
            0,
            0);
4319
    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1);
4320 4321 4322 4323
    front_end_chanEst(ue,
            pilot1,
            slot0,
            0);
4324
    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0);
4325 4326 4327 4328 4329
    front_end_chanEst(ue,
            pilot0,
            slot1,
            0);
    proc->chan_est_pilot0_slot1_available = 1;
4330
    //printf("Set available channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
fnabet's avatar
fnabet committed
4331

4332 4333 4334 4335 4336
    // 2- perform FFT for other ofdm symbols other than pilots
    for (l=first_ofdm_sym; l<=l2; l++)
    {
        if( (l != pilot0) && (l != pilot1))
        {
4337
            //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l);
fnabet's avatar
fnabet committed
4338
#if UE_TIMING_TRACE
4339
            start_meas(&ue->ofdm_demod_stats);
fnabet's avatar
fnabet committed
4340
#endif
4341 4342 4343 4344 4345 4346 4347
            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
            front_end_fft(ue,
                    l,
                    slot0,
                    0,
                    0);
            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
fnabet's avatar
fnabet committed
4348
#if UE_TIMING_TRACE
4349
            stop_meas(&ue->ofdm_demod_stats);
fnabet's avatar
fnabet committed
4350
#endif
4351 4352
        }
    } // for l=1..l2
hbilel's avatar
hbilel committed
4353

4354 4355 4356 4357 4358
    // 3- perform Channel Estimation for slot0
    for (l=first_ofdm_sym; l<=l2; l++)
    {
        if( (l != pilot0) && (l != pilot1))
        {
4359
            //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l);
fnabet's avatar
fnabet committed
4360 4361 4362 4363
            front_end_chanEst(ue,
                    l,
                    slot0,
                    0);
4364 4365 4366
        }
        ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
    }
hbilel's avatar
hbilel committed
4367

fnabet's avatar
fnabet committed
4368
    if (do_pdcch_flag) {
4369
#if UE_TIMING_TRACE
4370
        start_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4371
#endif
fnabet's avatar
fnabet committed
4372 4373
        if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) {
            LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx);
4374
#if UE_TIMING_TRACE
4375
            stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4376
#if DISABLE_LOG_X
4377
            printf("[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
4378
#else
4379
            LOG_D(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
4380 4381
#endif
#endif
4382
            //proc->dci_slot0_available = 1;
fnabet's avatar
fnabet committed
4383 4384
            return(-1);
        }
4385
        //proc->dci_slot0_available=1;
4386
#if UE_TIMING_TRACE
4387
        stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4388
#if DISABLE_LOG_X
4389
        printf("[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
4390
#else
4391
        LOG_D(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
4392 4393
#endif
#endif
4394
    }
4395

4396
    //printf("num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
4397

fnabet's avatar
fnabet committed
4398 4399
    // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
#if UE_TIMING_TRACE
4400
    stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
fnabet's avatar
fnabet committed
4401
#if DISABLE_LOG_X
4402
    printf("[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4403
#else
4404
    LOG_D(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4405 4406 4407
#endif
#endif

4408 4409 4410
    //wait until slot1 FE is done
    uint32_t wait = 0;
    while(proc->chan_est_slot1_available == 0)
4411
    {
4412 4413
        usleep(1);
        wait++;
4414
    }
hbilel's avatar
hbilel committed
4415

fnabet's avatar
fnabet committed
4416
#if UE_TIMING_TRACE
4417
    stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]);
fnabet's avatar
fnabet committed
4418
#if DISABLE_LOG_X
4419
    printf("[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4420
#else
4421
    LOG_D(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4422 4423
#endif
#endif
4424
    /**** End Subframe FE Processing ****/
fnabet's avatar
fnabet committed
4425

4426

4427 4428 4429 4430
#if 0
    //Trigger LLR parallelized for Slot 1
    proc->dci_slot0_available=1;
    printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
fnabet's avatar
fnabet committed
4431
#endif
4432

4433
    /**** Pdsch Procedure Slot0 ****/
4434 4435
    // start main thread for Pdsch Procedure (slot0)
    // do procedures for C-RNTI
4436 4437
    //printf("AbsSubframe %d.%d Pdsch Procedure (slot0)\n",frame_rx%1024,subframe_rx);
    //printf("AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[ue->current_thread_id[subframe_rx]][0][0]->active);
4438

fnabet's avatar
fnabet committed
4439
#if UE_TIMING_TRACE
4440
    start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4441 4442 4443
#endif

#if UE_TIMING_TRACE
4444
    start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
fnabet's avatar
fnabet committed
4445
#endif
4446
    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
fnabet's avatar
fnabet committed
4447 4448 4449 4450 4451
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                PDSCH,
4452
                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
fnabet's avatar
fnabet committed
4453
                NULL,
4454
                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4455
                (ue->frame_parms.symbols_per_tti>>1)-1,
fnabet's avatar
fnabet committed
4456 4457 4458
                abstraction_flag);

        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
4459
    }
fnabet's avatar
fnabet committed
4460

4461 4462
    // do procedures for SI-RNTI
    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
fnabet's avatar
fnabet committed
4463 4464 4465 4466 4467 4468 4469
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                SI_PDSCH,
                ue->dlsch_SI[eNB_id],
                NULL,
4470
                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4471
                (ue->frame_parms.symbols_per_tti>>1)-1,
fnabet's avatar
fnabet committed
4472 4473
                abstraction_flag);
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
4474
    }
fnabet's avatar
fnabet committed
4475

4476 4477
    // do procedures for SI-RNTI
    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
fnabet's avatar
fnabet committed
4478 4479 4480 4481 4482 4483 4484
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                P_PDSCH,
                ue->dlsch_p[eNB_id],
                NULL,
4485
                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4486
                (ue->frame_parms.symbols_per_tti>>1)-1,
fnabet's avatar
fnabet committed
4487 4488
                abstraction_flag);
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
4489
    }
hbilel's avatar
hbilel committed
4490

4491 4492
    // do procedures for RA-RNTI
    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
fnabet's avatar
fnabet committed
4493 4494 4495 4496 4497 4498 4499
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
        ue_pdsch_procedures(ue,
                proc,
                eNB_id,
                RA_PDSCH,
                ue->dlsch_ra[eNB_id],
                NULL,
4500
                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4501
                (ue->frame_parms.symbols_per_tti>>1)-1,
fnabet's avatar
fnabet committed
4502 4503
                abstraction_flag);
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
4504
    }
hbilel's avatar
hbilel committed
4505

4506 4507 4508
#if 1
    // LLR linear
    proc->dci_slot0_available=1;
4509
    //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
4510 4511
#endif

fnabet's avatar
fnabet committed
4512
#if UE_TIMING_TRACE
4513
    stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
fnabet's avatar
fnabet committed
4514
#if DISABLE_LOG_X
4515
    printf("[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4516
#else
4517
    LOG_D(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4518 4519
#endif
#endif
4520

hbilel's avatar
hbilel committed
4521

4522 4523 4524 4525 4526 4527
    //wait until LLR Slot1 is done
    wait = 0;
    while(proc->llr_slot1_available == 0)
    {
        usleep(1);
        wait++;
4528
    }
hbilel's avatar
hbilel committed
4529

fnabet's avatar
fnabet committed
4530 4531


4532
#if UE_TIMING_TRACE
4533
    stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
4534
#if DISABLE_LOG_X
4535
    printf("[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
4536
#else
4537
    LOG_D(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
4538 4539
#endif
#endif
4540
    //printf("[slot0 dl processing] AbsSubframe %d.%d Channel Decoder Start wait %d\n",frame_rx,subframe_rx,wait);
4541

fnabet's avatar
fnabet committed
4542 4543 4544

    //=====================================================================//
#if UE_TIMING_TRACE
4545
    start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
fnabet's avatar
fnabet committed
4546
#endif
tct-labo4's avatar
tct-labo4 committed
4547

4548
    LOG_D(PHY,"==> Start Turbo Decoder active dlsch %d SI %d RA %d \n",ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active,
tct-labo4's avatar
tct-labo4 committed
4549 4550 4551
    		ue->dlsch_SI[eNB_id]->active,
			//ue->dlsch_p[eNB_id]->active,
			ue->dlsch_ra[eNB_id]->active);
4552
    // Start Turbo decoder
4553
    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
4554
        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
fnabet's avatar
fnabet committed
4555 4556 4557 4558
        ue_dlsch_procedures(ue,
                proc,
                eNB_id,
                PDSCH,
4559 4560
                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1],
fnabet's avatar
fnabet committed
4561 4562 4563
                &ue->dlsch_errors[eNB_id],
                mode,
                abstraction_flag);
4564
        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
fnabet's avatar
fnabet committed
4565
    }
4566

fnabet's avatar
fnabet committed
4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606
    // do procedures for SI-RNTI
    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
        ue_dlsch_procedures(ue,
                proc,
                eNB_id,
                SI_PDSCH,
                ue->dlsch_SI[eNB_id],
                NULL,
                &ue->dlsch_SI_errors[eNB_id],
                mode,
                abstraction_flag);
        ue->dlsch_SI[eNB_id]->active = 0;
    }

    // do procedures for P-RNTI
    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
        ue_dlsch_procedures(ue,
                proc,
                eNB_id,
                P_PDSCH,
                ue->dlsch_p[eNB_id],
                NULL,
                &ue->dlsch_p_errors[eNB_id],
                mode,
                abstraction_flag);
        ue->dlsch_p[eNB_id]->active = 0;
    }
    // do procedures for RA-RNTI
    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
        ue_dlsch_procedures(ue,
                proc,
                eNB_id,
                RA_PDSCH,
                ue->dlsch_ra[eNB_id],
                NULL,
                &ue->dlsch_ra_errors[eNB_id],
                mode,
                abstraction_flag);
        ue->dlsch_ra[eNB_id]->active = 0;
    }
4607

fnabet's avatar
fnabet committed
4608
#if UE_TIMING_TRACE
4609
        stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
fnabet's avatar
fnabet committed
4610
#if DISABLE_LOG_X
4611
        printf("[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4612
#else
4613
        LOG_D(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4614
#endif
4615

fnabet's avatar
fnabet committed
4616 4617
#endif

4618
        // duplicate harq structure
4619 4620 4621
        uint8_t          current_harq_pid        = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid;
        LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid];
        harq_status_t    *current_harq_ack       = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx];
4622

4623
        // For Debug parallelisation
4624 4625 4626 4627
        //if (current_harq_ack->ack == 0) {
            //printf("[slot0 dl processing][End of Channel Decoding] AbsSubframe %d.%d Decode Fail for HarqId%d Round%d\n",frame_rx,subframe_rx,current_harq_pid,current_harq_processes->round);
        //}
        for(uint8_t rx_th_idx=1; rx_th_idx<RX_NB_TH; rx_th_idx++)
4628
        {
4629 4630
            LTE_DL_UE_HARQ_t *harq_processes_dest  = ue->dlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_processes[current_harq_pid];
            harq_status_t    *harq_ack_dest        = &ue->dlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_ack[subframe_rx];
4631 4632 4633 4634 4635 4636

            copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
            copy_ack_struct(harq_ack_dest, current_harq_ack);

        }
    /*
fnabet's avatar
fnabet committed
4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648
    LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
    LTE_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];

    harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
    harq_status_t *harq_ack_dest    = &ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
    harq_status_t *harq_ack_dest1    = &ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];

    copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
    copy_ack_struct(harq_ack_dest, current_harq_ack);

    copy_harq_proc_struct(harq_processes_dest1, current_harq_processes);
    copy_ack_struct(harq_ack_dest1, current_harq_ack);
4649
    */
4650
    if (subframe_rx==9) {
fnabet's avatar
fnabet committed
4651 4652 4653
        if (frame_rx % 10 == 0) {
            if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
                ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]);
4654

fnabet's avatar
fnabet committed
4655 4656 4657
            ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
            ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
        }
gabrielC's avatar
gabrielC committed
4658 4659


fnabet's avatar
fnabet committed
4660 4661 4662 4663 4664
        ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100;
        ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id];
        LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
                ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
                ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
gabrielC's avatar
gabrielC committed
4665

fnabet's avatar
fnabet committed
4666 4667 4668 4669
#if UE_AUTOTEST_TRACE
        if ((frame_rx % 100 == 0)) {
            LOG_I(PHY,"[UE  %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx);
        }
4670
#endif
4671

4672
    }
4673

fnabet's avatar
fnabet committed
4674
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
jiangx's avatar
jiangx committed
4675

fnabet's avatar
fnabet committed
4676
#if UE_TIMING_TRACE
4677
    stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
fnabet's avatar
fnabet committed
4678
#if DISABLE_LOG_X
4679
    printf("------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4680
#else
4681
    LOG_D(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4682 4683
#endif
#endif
jiangx's avatar
jiangx committed
4684

fnabet's avatar
fnabet committed
4685
    LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
4686
    return (0);
fnabet's avatar
fnabet committed
4687
}
4688
#endif
4689

fnabet's avatar
fnabet committed
4690

4691 4692 4693 4694 4695
void phy_procedures_UE_SL_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc) {


}

4696
int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
4697
			 uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) {
fnabet's avatar
fnabet committed
4698

4699 4700 4701 4702 4703
  int l,l2;
  int pilot1;
  int pmch_flag=0;
  int frame_rx = proc->frame_rx;
  int subframe_rx = proc->subframe_rx;
fnabet's avatar
fnabet committed
4704

4705 4706
  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
fnabet's avatar
fnabet committed
4707

4708
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
fnabet's avatar
fnabet committed
4709 4710

#if T_TRACER
hbilel's avatar
hbilel committed
4711
  T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
4712

hbilel's avatar
hbilel committed
4713
  T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0),
4714 4715
    T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti],
             ue->frame_parms.samples_per_tti * 4));
gabrielC's avatar
gabrielC committed
4716
#endif
4717

hbilel's avatar
hbilel committed
4718
  // start timers
gabrielC's avatar
gabrielC committed
4719
#ifdef UE_DEBUG_TRACE
4720
  LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
fnabet's avatar
fnabet committed
4721
#endif
4722

gabrielC's avatar
gabrielC committed
4723
#if UE_TIMING_TRACE
4724
  start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
hbilel's avatar
hbilel committed
4725
  start_meas(&ue->generic_stat);
gabrielC's avatar
gabrielC committed
4726
#endif
4727

4728
  pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;
4729

4730
  if (do_pdcch_flag) {
4731
  // deactivate reception until we scan pdcch
4732 4733 4734 4735
  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0])
    ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0;
  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1])
    ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0;
4736

4737 4738
  if (ue->dlsch_SI[eNB_id])
    ue->dlsch_SI[eNB_id]->active = 0;
4739 4740
  if (ue->dlsch_p[eNB_id])
    ue->dlsch_p[eNB_id]->active = 0;
4741 4742
  if (ue->dlsch_ra[eNB_id])
    ue->dlsch_ra[eNB_id]->active = 0;
4743
  }
4744 4745

#ifdef DEBUG_PHY_PROC
4746
  LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n",
4747
  ue->Mod_id,frame_rx, subframe_rx);
4748 4749
#endif

4750 4751 4752 4753 4754
  if (ue->frame_parms.Ncp == 0) {  // normal prefix
    pilot1 = 4;
  } else { // extended prefix
    pilot1 = 3;
  }
fnabet's avatar
fnabet committed
4755 4756


4757 4758 4759 4760 4761 4762 4763
  if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only
    l2 = 5;
  } else if (pmch_flag == 1) { // do first 2 symbols only
    l2 = 1;
  } else { // normal subframe, last symbol to be processed is the first of the second slot
    l2 = (ue->frame_parms.symbols_per_tti/2)-1;
  }
fnabet's avatar
fnabet committed
4764

4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776
  int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1);
  if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) {
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // RX processing of symbols l=0...l2
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    l=0;
  } else {
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    l=1;
  }
hbilel's avatar
hbilel committed
4777

4778 4779
  LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
  LOG_D(PHY," ------  --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
4780
  for (; l<=l2; l++) {
4781
    if (abstraction_flag == 0) {
gabrielC's avatar
gabrielC committed
4782 4783 4784
#if UE_TIMING_TRACE
        start_meas(&ue->ofdm_demod_stats);
#endif
4785 4786
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
      slot_fep(ue,
4787 4788 4789 4790 4791
         l,
         (subframe_rx<<1),
         0,
         0,
         0);
4792
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
gabrielC's avatar
gabrielC committed
4793
#if UE_TIMING_TRACE
4794
      stop_meas(&ue->ofdm_demod_stats);
gabrielC's avatar
gabrielC committed
4795
#endif
4796
    }
fnabet's avatar
fnabet committed
4797

4798
    ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
fnabet's avatar
fnabet committed
4799

4800 4801 4802 4803
    if (do_pdcch_flag) {
      if ((l==pilot1) ||
	  ((pmch_flag==1)&(l==l2)))  {
	LOG_D(PHY,"[UE  %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id);
fnabet's avatar
fnabet committed
4804

4805
	//start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]);
4806 4807 4808 4809
	if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) {
	  LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx);
	  return(-1);
	}
4810
	//stop_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]);
4811
    //printf("subframe %d n_pdcch_sym %d pdcch procedures  %5.3f \n",
4812 4813
    //        subframe_rx, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
    //     (ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
4814
	LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
4815
      }
4816
    }
4817

4818
  } // for l=1..l2
4819 4820
  ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);

4821
  LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
4822 4823 4824 4825 4826
    // If this is PMCH, call procedures and return
  if (pmch_flag == 1) {
    ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
    return 0;
  }
4827

4828
  slot_fep(ue,
4829 4830 4831 4832 4833
     0,
     1+(subframe_rx<<1),
     0,
     0,
     0);
4834

4835
  // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
gabrielC's avatar
gabrielC committed
4836
#if UE_TIMING_TRACE
hbilel's avatar
hbilel committed
4837
  stop_meas(&ue->generic_stat);
Cedric Roux's avatar
Cedric Roux committed
4838
#if DISABLE_LOG_X
gabrielC's avatar
gabrielC committed
4839
  printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
4840 4841
#else
  LOG_D(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
fnabet's avatar
fnabet committed
4842
#endif
hbilel's avatar
hbilel committed
4843

gabrielC's avatar
gabrielC committed
4844
#endif
fnabet's avatar
fnabet committed
4845

gabrielC's avatar
gabrielC committed
4846 4847
  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
#if UE_TIMING_TRACE
hbilel's avatar
hbilel committed
4848
  start_meas(&ue->generic_stat);
gabrielC's avatar
gabrielC committed
4849
#endif
4850
  // do procedures for C-RNTI
4851
  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
4852
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
4853 4854 4855 4856
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
4857
			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
4858
			NULL,
4859
			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4860 4861
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
fnabet's avatar
fnabet committed
4862

4863
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
4864
  }
hbilel's avatar
hbilel committed
4865

4866
  LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
4867 4868
  // do procedures for SI-RNTI
  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
4869
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
4870
    ue_pdsch_procedures(ue,
4871

4872 4873 4874 4875 4876
			proc,
			eNB_id,
			SI_PDSCH,
			ue->dlsch_SI[eNB_id],
			NULL,
4877
			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4878 4879
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
4880
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
4881
  }
4882 4883 4884

  // do procedures for SI-RNTI
  if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
4885
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
4886 4887 4888 4889 4890 4891
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			P_PDSCH,
			ue->dlsch_p[eNB_id],
			NULL,
4892
			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4893 4894
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
4895
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
4896 4897
  }

4898 4899
  // do procedures for RA-RNTI
  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
4900
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
4901 4902 4903 4904 4905 4906
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			RA_PDSCH,
			ue->dlsch_ra[eNB_id],
			NULL,
4907
			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
4908 4909
			ue->frame_parms.symbols_per_tti>>1,
			abstraction_flag);
4910
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
4911
  }
fnabet's avatar
fnabet committed
4912

4913 4914
  LOG_D(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
  LOG_D(PHY," ------  --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
hbilel's avatar
hbilel committed
4915

4916 4917 4918
  if (subframe_select(&ue->frame_parms,subframe_rx) != SF_S) {  // do front-end processing for second slot, and first symbol of next subframe
    for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++) {
      if (abstraction_flag == 0) {
gabrielC's avatar
gabrielC committed
4919 4920 4921
#if UE_TIMING_TRACE
          start_meas(&ue->ofdm_demod_stats);
#endif
4922 4923 4924 4925
	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
	slot_fep(ue,
		 l,
		 1+(subframe_rx<<1),
4926
		 0,
4927 4928 4929
		 0,
		 0);
	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
gabrielC's avatar
gabrielC committed
4930 4931 4932
#if UE_TIMING_TRACE
    stop_meas(&ue->ofdm_demod_stats);
#endif
4933
      }
fnabet's avatar
fnabet committed
4934

4935
      ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
fnabet's avatar
fnabet committed
4936

4937
    } // for l=1..l2
4938 4939 4940 4941 4942 4943 4944 4945

    // do first symbol of next downlink subframe for channel estimation
    int next_subframe_rx = (1+subframe_rx)%10;
    if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
    {
      slot_fep(ue,
         0,
         (next_subframe_rx<<1),
4946
         0,
4947 4948 4949
         0,
         0);
    }
4950
  } // not an S-subframe
gabrielC's avatar
gabrielC committed
4951
#if UE_TIMING_TRACE
hbilel's avatar
hbilel committed
4952
  stop_meas(&ue->generic_stat);
Cedric Roux's avatar
Cedric Roux committed
4953
#if DISABLE_LOG_X
gabrielC's avatar
gabrielC committed
4954
  printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
4955 4956 4957
#else
  LOG_D(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
#endif
fnabet's avatar
fnabet committed
4958 4959

#endif
hbilel's avatar
hbilel committed
4960

4961 4962
  LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);

4963 4964
  if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
  {
4965
    ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
4966
  }
fnabet's avatar
fnabet committed
4967 4968 4969



4970
  // do procedures for C-RNTI
4971
  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
4972
  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
4973
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
gabrielC's avatar
gabrielC committed
4974
#if UE_TIMING_TRACE
4975
    start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]);
gabrielC's avatar
gabrielC committed
4976
#endif
4977 4978 4979 4980
    ue_pdsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
4981
			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
4982 4983 4984 4985
			NULL,
			1+(ue->frame_parms.symbols_per_tti>>1),
			ue->frame_parms.symbols_per_tti-1,
			abstraction_flag);
4986 4987
    LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
    LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
gabrielC's avatar
gabrielC committed
4988
#if UE_TIMING_TRACE
4989 4990
    stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
    start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
gabrielC's avatar
gabrielC committed
4991
#endif
4992 4993 4994 4995
    ue_dlsch_procedures(ue,
			proc,
			eNB_id,
			PDSCH,
4996 4997
			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1],
4998 4999 5000
			&ue->dlsch_errors[eNB_id],
			mode,
			abstraction_flag);
gabrielC's avatar
gabrielC committed
5001
#if UE_TIMING_TRACE
5002
    stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
Cedric Roux's avatar
Cedric Roux committed
5003
#if DISABLE_LOG_X
5004 5005
    printf("[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
    printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
5006
#else
5007 5008
    LOG_D(PHY, "[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
    LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
5009
#endif
fnabet's avatar
fnabet committed
5010

gabrielC's avatar
gabrielC committed
5011
#endif
hbilel's avatar
hbilel committed
5012

5013
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
5014

5015
  }
gabrielC's avatar
gabrielC committed
5016
#if UE_TIMING_TRACE
hbilel's avatar
hbilel committed
5017
  start_meas(&ue->generic_stat);
gabrielC's avatar
gabrielC committed
5018
#endif
hbilel's avatar
hbilel committed
5019 5020

#if 0
5021
  if(subframe_rx==5 &&  ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20){
hbilel's avatar
hbilel committed
5022 5023 5024
       //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
       //write_output("llr.m","llr",  &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);

5025 5026
       write_output("rxdataF0_current.m"    , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
hbilel's avatar
hbilel committed
5027

5028
       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
hbilel's avatar
hbilel committed
5029

5030 5031 5032 5033 5034
       write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
       write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
       write_output("rxdataF_comp00.m","rxdataF_comp00",         &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
       //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1);
       //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1);
hbilel's avatar
hbilel committed
5035 5036 5037 5038 5039

       AssertFatal (0,"");
  }
#endif

5040 5041 5042
  // do procedures for SI-RNTI
  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
    ue_pdsch_procedures(ue,
5043 5044 5045 5046 5047 5048 5049 5050
      proc,
      eNB_id,
      SI_PDSCH,
      ue->dlsch_SI[eNB_id],
      NULL,
      1+(ue->frame_parms.symbols_per_tti>>1),
      ue->frame_parms.symbols_per_tti-1,
      abstraction_flag);
5051

5052
    ue_dlsch_procedures(ue,
5053 5054 5055 5056 5057 5058 5059 5060
      proc,
      eNB_id,
      SI_PDSCH,
      ue->dlsch_SI[eNB_id],
      NULL,
      &ue->dlsch_SI_errors[eNB_id],
      mode,
      abstraction_flag);
5061 5062
    ue->dlsch_SI[eNB_id]->active = 0;
  }
5063 5064 5065 5066

  // do procedures for P-RNTI
  if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
    ue_pdsch_procedures(ue,
5067 5068 5069 5070 5071 5072 5073 5074
      proc,
      eNB_id,
      P_PDSCH,
      ue->dlsch_p[eNB_id],
      NULL,
      1+(ue->frame_parms.symbols_per_tti>>1),
      ue->frame_parms.symbols_per_tti-1,
      abstraction_flag);
5075 5076

    ue_dlsch_procedures(ue,
5077 5078 5079 5080 5081 5082 5083 5084
      proc,
      eNB_id,
      P_PDSCH,
      ue->dlsch_p[eNB_id],
      NULL,
      &ue->dlsch_p_errors[eNB_id],
      mode,
      abstraction_flag);
5085 5086
    ue->dlsch_p[eNB_id]->active = 0;
  }
5087 5088 5089
  // do procedures for RA-RNTI
  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
    ue_pdsch_procedures(ue,
5090 5091 5092 5093 5094 5095 5096 5097
      proc,
      eNB_id,
      RA_PDSCH,
      ue->dlsch_ra[eNB_id],
      NULL,
      1+(ue->frame_parms.symbols_per_tti>>1),
      ue->frame_parms.symbols_per_tti-1,
      abstraction_flag);
5098
    ue_dlsch_procedures(ue,
5099 5100 5101 5102 5103 5104 5105 5106
      proc,
      eNB_id,
      RA_PDSCH,
      ue->dlsch_ra[eNB_id],
      NULL,
      &ue->dlsch_ra_errors[eNB_id],
      mode,
      abstraction_flag);
5107 5108
    ue->dlsch_ra[eNB_id]->active = 0;
  }
5109

gabrielC's avatar
gabrielC committed
5110
  // duplicate harq structure
5111

5112 5113 5114 5115
  uint8_t          current_harq_pid        = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid;
  LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid];
  LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[next1_thread_id][eNB_id][0]->harq_processes[current_harq_pid];
  LTE_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[next2_thread_id][eNB_id][0]->harq_processes[current_harq_pid];
gabrielC's avatar
gabrielC committed
5116

5117 5118 5119
  harq_status_t *current_harq_ack = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx];
  harq_status_t *harq_ack_dest    = &ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack[subframe_rx];
  harq_status_t *harq_ack_dest1    = &ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack[subframe_rx];
gabrielC's avatar
gabrielC committed
5120

5121 5122
  copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
  copy_ack_struct(harq_ack_dest, current_harq_ack);
gabrielC's avatar
gabrielC committed
5123

5124 5125 5126
  copy_harq_proc_struct(harq_processes_dest1, current_harq_processes);
  copy_ack_struct(harq_ack_dest1, current_harq_ack);

5127
  if (subframe_rx==9) {
Raymond Knopp's avatar
 
Raymond Knopp committed
5128
    if (frame_rx % 10 == 0) {
5129
      if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
5130
  ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]);
5131

5132 5133
      ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
      ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
5134
    }
5135 5136


5137 5138
    ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100;
    ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id];
5139
    LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
fnabet's avatar
fnabet committed
5140 5141
    ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
    ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
5142 5143 5144 5145 5146 5147 5148

  #if UE_AUTOTEST_TRACE
    if ((frame_rx % 100 == 0)) {
      LOG_I(PHY,"[UE  %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx);
    }
  #endif

5149
  }
5150

gabrielC's avatar
gabrielC committed
5151
#if UE_TIMING_TRACE
hbilel's avatar
hbilel committed
5152
  stop_meas(&ue->generic_stat);
gabrielC's avatar
gabrielC committed
5153 5154
  printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
#endif
jiangx's avatar
jiangx committed
5155

5156
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
hbilel's avatar
hbilel committed
5157

gabrielC's avatar
gabrielC committed
5158
#if UE_TIMING_TRACE
5159
  stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
Cedric Roux's avatar
Cedric Roux committed
5160
#if DISABLE_LOG_X
5161
  printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
5162
#else
5163
  LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
Cedric Roux's avatar
Cedric Roux committed
5164
#endif
gabrielC's avatar
gabrielC committed
5165
#endif
fnabet's avatar
fnabet committed
5166

5167
  LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
5168
  return (0);
5169
}
5170 5171 5172



5173
void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode)
5174
{
5175
#if defined(ENABLE_ITTI)
5176 5177 5178 5179 5180
  MessageDef   *msg_p;
  const char   *msg_name;
  instance_t    instance;
  unsigned int  Mod_id;
  int           result;
5181
#endif
5182

5183 5184 5185 5186
  int           frame_rx = proc->frame_rx;
  int           frame_tx = proc->frame_tx;
  int           subframe_rx = proc->subframe_rx;
  int           subframe_tx = proc->subframe_tx;
5187
#undef DEBUG_PHY_PROC
5188

5189
  UE_L2_STATE_t ret;
5190
  int slot;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
5191

5192 5193
  if (ue->mac_enabled == 0) {
    ue->UE_mode[eNB_id]=PUSCH;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
5194
  }
5195 5196


5197
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1);
gabrielC's avatar
gabrielC committed
5198
#if UE_TIMING_TRACE
5199
  start_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]);
gabrielC's avatar
gabrielC committed
5200
#endif
5201
#if defined(ENABLE_ITTI)
5202

5203 5204
  do {
    // Checks if a message has been sent to PHY sub-task
5205
    itti_poll_msg (TASK_PHY_UE, &msg_p);
5206

5207 5208 5209 5210
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
      Mod_id = instance - NB_eNB_INST;
5211

5212
      switch (ITTI_MSG_ID(msg_p)) {
5213
      case PHY_FIND_CELL_REQ:
5214 5215 5216 5217 5218
  LOG_I(PHY, "[UE %d] Received %s\n", Mod_id, msg_name);

  /* TODO process the message */
  break;

5219
      default:
5220 5221
  LOG_E(PHY, "[UE %d] Received unexpected message %s\n", Mod_id, msg_name);
  break;
5222
      }
5223

5224 5225
      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
5226 5227
    }
  } while(msg_p != NULL);
5228

5229
#endif
5230

5231
  for (slot=0;slot<2;slot++) {
5232

5233
    if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)||
5234
  (ue->frame_parms.frame_type == FDD)) {
5235
      phy_procedures_UE_TX(ue,proc,eNB_id,abstraction_flag,mode);
5236
    }
5237

5238
    if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_DL) ||
5239 5240
	(ue->frame_parms.frame_type == FDD)) {
      phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode);
5241
    }
5242

5243
    if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_S) &&
5244
  (slot==1)) {
5245
      phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag);
5246
    }
5247

5248
    if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_S) &&
5249 5250
	(slot==0)) {
	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode);
5251
    }
5252

5253 5254
    if (ue->mac_enabled==1) {
      if (slot==0) {
5255

5256
          //LOG_I(PHY,"[UE %d] Frame %d, subframe %d, star ue_scheduler\n", ue->Mod_id,frame_rx,subframe_tx);
5257 5258 5259 5260 5261 5262 5263 5264 5265
        ret = ue_scheduler(ue->Mod_id,
			   frame_rx,
			   subframe_rx,
			   frame_tx,
			   subframe_tx,
			   subframe_select(&ue->frame_parms,subframe_tx),
			   eNB_id,
			   0/*FIXME CC_id*/);
	
5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283
	if (ret == CONNECTION_LOST) {
	  LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, returning to PRACH\n",ue->Mod_id,
		frame_rx,subframe_tx);
	  ue->UE_mode[eNB_id] = PRACH;
	  //      mac_xface->macphy_exit("Connection lost");
	} else if (ret == PHY_RESYNCH) {
	  LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, trying to resynch\n",
		ue->Mod_id,
		frame_rx,subframe_tx);
	  ue->UE_mode[eNB_id] = RESYNCH;
	  //     mac_xface->macphy_exit("Connection lost");
	} else if (ret == PHY_HO_PRACH) {
	  LOG_I(PHY,"[UE %d] Frame %d, subframe %d, return to PRACH and perform a contention-free access\n",
		ue->Mod_id,frame_rx,subframe_tx);
	  ue->UE_mode[eNB_id] = PRACH;
	}
      }
    }
5284
    
5285
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0);
gabrielC's avatar
gabrielC committed
5286
#if UE_TIMING_TRACE
5287
    stop_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]);
gabrielC's avatar
gabrielC committed
5288
#endif
5289
  } // slot
5290
}
5291 5292