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

/*! \file PHY/LTE_TRANSPORT/dlsch_decoding.c
* \brief Top-level routines for decoding  Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/

//#include "defs.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "PHY/CODING/extern.h"
#include "SCHED/extern.h"
#include "SIMULATION/TOOLS/defs.h"
knopp's avatar
   
knopp committed
39
//#define DEBUG_DLSCH_DECODING
40

Bilel's avatar
Bilel committed
41
extern double cpuf;
42

43
44
void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch)
{
45
46
47
48

  int i,r;

  if (dlsch) {
49
    for (i=0; i<dlsch->Mdlharq; i++) {
50
      if (dlsch->harq_processes[i]) {
51
52
53
54
55
56
        if (dlsch->harq_processes[i]->b) {
          free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES);
          dlsch->harq_processes[i]->b = NULL;
        }

        for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) {
57
58
59
          free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
          dlsch->harq_processes[i]->c[r] = NULL;
        }
60
61
62
63
64
65
66
67
68

        for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++)
          if (dlsch->harq_processes[i]->d[r]) {
            free16(dlsch->harq_processes[i]->d[r],((3*8*6144)+12+96)*sizeof(short));
            dlsch->harq_processes[i]->d[r] = NULL;
          }

        free16(dlsch->harq_processes[i],sizeof(LTE_DL_UE_HARQ_t));
        dlsch->harq_processes[i] = NULL;
69
70
      }
    }
71
72
73

    free16(dlsch,sizeof(LTE_UE_DLSCH_t));
    dlsch = NULL;
74
75
76
  }
}

77
LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag)
78
{
79
80
81

  LTE_UE_DLSCH_t *dlsch;
  uint8_t exit_flag = 0,i,r;
82

83
  unsigned char bw_scaling =1;
84
85
86

  switch (N_RB_DL) {
  case 6:
87
88
    bw_scaling =16;
    break;
89

90
91
92
  case 25:
    bw_scaling =4;
    break;
93
94

  case 50:
95
96
    bw_scaling =2;
    break;
97

98
99
100
101
  default:
    bw_scaling =1;
    break;
  }
102

103
  dlsch = (LTE_UE_DLSCH_t *)malloc16(sizeof(LTE_UE_DLSCH_t));
104

105
  if (dlsch) {
106
    memset(dlsch,0,sizeof(LTE_UE_DLSCH_t));
107
108
    dlsch->Kmimo = Kmimo;
    dlsch->Mdlharq = Mdlharq;
109
    dlsch->Nsoft = Nsoft;
110
111
    dlsch->max_turbo_iterations = max_turbo_iterations;

112
    for (i=0; i<Mdlharq; i++) {
113
      //      printf("new_ue_dlsch: Harq process %d\n",i);
114
      dlsch->harq_processes[i] = (LTE_DL_UE_HARQ_t *)malloc16(sizeof(LTE_DL_UE_HARQ_t));
115

116
      if (dlsch->harq_processes[i]) {
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
        memset(dlsch->harq_processes[i],0,sizeof(LTE_DL_UE_HARQ_t));
        dlsch->harq_processes[i]->first_tx=1;
        dlsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);

        if (dlsch->harq_processes[i]->b)
          memset(dlsch->harq_processes[i]->b,0,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
        else
          exit_flag=3;

        if (abstraction_flag == 0) {
          for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
            dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+ 768);

            if (dlsch->harq_processes[i]->c[r])
              memset(dlsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+ 768);
            else
              exit_flag=2;

            dlsch->harq_processes[i]->d[r] = (short*)malloc16(((3*8*6144)+12+96)*sizeof(short));

            if (dlsch->harq_processes[i]->d[r])
              memset(dlsch->harq_processes[i]->d[r],0,((3*8*6144)+12+96)*sizeof(short));
            else
              exit_flag=2;
          }
        }
      } else {
        exit_flag=1;
145
146
147
148
149
150
      }
    }

    if (exit_flag==0)
      return(dlsch);
  }
151

152
  printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(LTE_DL_UE_HARQ_t), exit_flag);
153
154
155
156
157
158
159
160
161
162
  free_ue_dlsch(dlsch);

  return(NULL);
}

uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
                         short *dlsch_llr,
                         LTE_DL_FRAME_PARMS *frame_parms,
                         LTE_UE_DLSCH_t *dlsch,
                         LTE_DL_UE_HARQ_t *harq_process,
163
                         uint8_t frame,
164
165
166
                         uint8_t subframe,
                         uint8_t harq_pid,
                         uint8_t is_crnti,
167
168
169
170
                         uint8_t llr8_flag)
{


171
172
173
174
175
176
  time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats;
  time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats;
  time_stats_t *dlsch_deinterleaving_stats=&phy_vars_ue->dlsch_deinterleaving_stats;
  uint32_t A,E;
  uint32_t G;
  uint32_t ret,offset;
gauthier's avatar
gauthier committed
177
  uint16_t iind;
178
179
180
181
182
  //  uint8_t dummy_channel_output[(3*8*block_length)+12];
  short dummy_w[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)];
  uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0;
  uint8_t crc_type;
#ifdef DEBUG_DLSCH_DECODING
gauthier's avatar
gauthier committed
183
  uint16_t i;
184
#endif
185
186
  //#ifdef __AVX2__
#if 0
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  int Kr_last,skipped_last=0;
  uint8_t (*tc_2cw)(int16_t *y,
		    int16_t *y2,
		    uint8_t *,
		    uint8_t *,
		    uint16_t,
		    uint16_t,
		    uint16_t,
		    uint8_t,
		    uint8_t,
		    uint8_t,
		    time_stats_t *,
		    time_stats_t *,
		    time_stats_t *,
		    time_stats_t *,
		    time_stats_t *,
		    time_stats_t *,
		    time_stats_t *);

206
207
#endif
  uint8_t (*tc)(int16_t *y,
208
209
210
211
212
213
214
215
216
217
218
219
220
221
                uint8_t *,
                uint16_t,
                uint16_t,
                uint16_t,
                uint8_t,
                uint8_t,
                uint8_t,
                time_stats_t *,
                time_stats_t *,
                time_stats_t *,
                time_stats_t *,
                time_stats_t *,
                time_stats_t *,
                time_stats_t *);
222

223
224
225



226
  if (!dlsch_llr) {
227
    printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
228
229
230
231
    return(dlsch->max_turbo_iterations);
  }

  if (!harq_process) {
232
    printf("dlsch_decoding.c: NULL harq_process pointer\n");
233
    return(dlsch->max_turbo_iterations);
234
235
236
  }

  if (!frame_parms) {
237
    printf("dlsch_decoding.c: NULL frame_parms pointer\n");
238
    return(dlsch->max_turbo_iterations);
239
  }
240

241
  if (subframe>9) {
242
    printf("dlsch_decoding.c: Illegal subframe index %d\n",subframe);
243
    return(dlsch->max_turbo_iterations);
244
245
  }

246
  if (dlsch->harq_ack[subframe].ack != 2) {
Gabriel's avatar
Gabriel committed
247
    LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
248
249
250
        phy_vars_ue->Mod_id, subframe, dlsch->harq_ack[subframe].ack);
  }

251
  if (llr8_flag == 0) {
252
253
    //#ifdef __AVX2__
#if 0
254
255
    tc_2cw = phy_threegpplte_turbo_decoder16avx2;
#endif
256
    tc = phy_threegpplte_turbo_decoder16;
257
  }
258
  else
259
260
261
262
263
264
  {
	  AssertFatal (harq_process->TBS >= 256 , "Mismatch flag nbRB=%d TBS=%d mcs=%d Qm=%d RIV=%d round=%d \n",
			  harq_process->nb_rb, harq_process->TBS,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
	    tc = phy_threegpplte_turbo_decoder8;
  }

265

266
267
268
269
  //  nb_rb = dlsch->nb_rb;

  /*
  if (nb_rb > frame_parms->N_RB_DL) {
270
    printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
271
272
273
    return(max_turbo_iterations);
    }*/

Bilel's avatar
Bilel committed
274
  /*harq_pid = dlsch->current_harq_pid[subframe&0x1];
275
  if (harq_pid >= 8) {
276
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
277
278
279
    return(max_turbo_iterations);
  }
  */
280
281
282

  harq_process->trials[harq_process->round]++;

283
284
285
286
287
288
289
290
  A = harq_process->TBS; //2072 for QPSK 1/3

  ret = dlsch->max_turbo_iterations;


  G = harq_process->G;
  //get_G(frame_parms,nb_rb,dlsch->rb_alloc,mod_order,num_pdcch_symbols,phy_vars_ue->frame,subframe);

291
  //  printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi);
292

293
  if (harq_process->round == 0) {
294
295
296
    // This is a new packet, so compute quantities regarding segmentation
    harq_process->B = A+24;
    lte_segmentation(NULL,
297
298
299
300
301
302
303
304
                     NULL,
                     harq_process->B,
                     &harq_process->C,
                     &harq_process->Cplus,
                     &harq_process->Cminus,
                     &harq_process->Kplus,
                     &harq_process->Kminus,
                     &harq_process->F);
305
306
    //  CLEAR LLR's HERE for first packet in process
  }
307

308
309
  /*
  else {
310
    printf("dlsch_decoding.c: Ndi>0 not checked yet!!\n");
311
312
313
314
315
    return(max_turbo_iterations);
  }
  */
  err_flag = 0;
  r_offset = 0;
316

317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
  unsigned char bw_scaling =1;

  switch (frame_parms->N_RB_DL) {
  case 6:
    bw_scaling =16;
    break;

  case 25:
    bw_scaling =4;
    break;

  case 50:
    bw_scaling =2;
    break;

  default:
    bw_scaling =1;
    break;
  }

337
  if (harq_process->C > MAX_NUM_DLSCH_SEGMENTS/bw_scaling) {
338
339
340
    LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_DLSCH_SEGMENTS/bw_scaling);
    return((1+dlsch->max_turbo_iterations));
  }
341
342
343
344
#ifdef DEBUG_DLSCH_DECODING
  printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus);
#endif

Bilel's avatar
Bilel committed
345
346
  opp_enabled=1;

347
  for (r=0; r<harq_process->C; r++) {
348

349

350
351
352
353
354
    // Get Turbo interleaver parameters
    if (r<harq_process->Cminus)
      Kr = harq_process->Kminus;
    else
      Kr = harq_process->Kplus;
355

356
    Kr_bytes = Kr>>3;
357

358
359
360
361
362
363
364
365
366
    if (Kr_bytes<=64)
      iind = (Kr_bytes-5);
    else if (Kr_bytes <=128)
      iind = 59 + ((Kr_bytes-64)>>1);
    else if (Kr_bytes <= 256)
      iind = 91 + ((Kr_bytes-128)>>2);
    else if (Kr_bytes <= 768)
      iind = 123 + ((Kr_bytes-256)>>3);
    else {
367
      printf("dlsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
368
      return(dlsch->max_turbo_iterations);
369
    }
370
371

#ifdef DEBUG_DLSCH_DECODING
372
    printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? harq_process->F : 0);
373
374
375
376
#endif

    start_meas(dlsch_rate_unmatching_stats);
    memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
377
378
379
    harq_process->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
                                            (uint8_t*) &dummy_w[r][0],
                                            (r==0) ? harq_process->F : 0);
380

381
#ifdef DEBUG_DLSCH_DECODING
Bilel's avatar
Bilel committed
382
    LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
383
384
385
          harq_pid,r, G,
          Kr*3,
          harq_process->TBS,
386
          harq_process->Qm,
387
388
389
390
391
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
#endif
392

393
//printf("dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
394
    if (lte_rate_matching_turbo_rx(harq_process->RTC[r],
395
396
397
398
399
                                   G,
                                   harq_process->w[r],
                                   (uint8_t*)&dummy_w[r][0],
                                   dlsch_llr+r_offset,
                                   harq_process->C,
400
                                   dlsch->Nsoft,
401
402
403
404
                                   dlsch->Mdlharq,
                                   dlsch->Kmimo,
                                   harq_process->rvidx,
                                   (harq_process->round==0)?1:0,
405
                                   harq_process->Qm,
406
407
408
                                   harq_process->Nl,
                                   r,
                                   &E)==-1) {
409
      stop_meas(dlsch_rate_unmatching_stats);
410
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
411
      return(dlsch->max_turbo_iterations);
412
    } else
413
      stop_meas(dlsch_rate_unmatching_stats);
414

415
416
417
    r_offset += E;

    /*
418
    printf("Subblock deinterleaving, d %p w %p\n",
419
420
     harq_process->d[r],
     harq_process->w);
421
422
    */
    start_meas(dlsch_deinterleaving_stats);
423
424
    sub_block_deinterleaving_turbo(4+Kr,
                                   &harq_process->d[r][96],
425

426
                                   harq_process->w[r]);
427
    stop_meas(dlsch_deinterleaving_stats);
428
429

#ifdef DEBUG_DLSCH_DECODING
430
431
432
433
434
    /*
    if (r==0) {
              write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
              write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0);
    }
435

436
    printf("decoder input(segment %d) :",r);
437
    int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
438
439
      printf("%d : %d\n",i,harq_process->d[r][96+i]);
      printf("\n");*/
440
#endif
441

442

443
    //    printf("Clearing c, %p\n",harq_process->c[r]);
444
    memset(harq_process->c[r],0,Kr_bytes);
445

446
    //    printf("done\n");
447
    if (harq_process->C == 1)
448
      crc_type = CRC24_A;
449
    else
450
451
      crc_type = CRC24_B;

452
    /*
453
    printf("decoder input(segment %d)\n",r);
454
    for (i=0;i<(3*8*Kr_bytes)+12;i++)
455
456
      if ((harq_process->d[r][96+i]>7) ||
    (harq_process->d[r][96+i] < -8))
457
458
    printf("%d : %d\n",i,harq_process->d[r][96+i]);
    printf("\n");
459
460
    */

461
462
    //#ifndef __AVX2__
#if 1
463
464
    if (err_flag == 0) {

Bilel's avatar
Bilel committed
465
466
467
468
        LOG_D(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
                            Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,
                            harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_turbo_iterations);

469
470
471
472
473
    	if (llr8_flag) {
    		AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
    				Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
    	}

474
      start_meas(dlsch_turbo_decoding_stats);
475
      ret = tc
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
            (&harq_process->d[r][96],
             harq_process->c[r],
             Kr,
             f1f2mat_old[iind*2],
             f1f2mat_old[(iind*2)+1],
             dlsch->max_turbo_iterations,
             crc_type,
             (r==0) ? harq_process->F : 0,
             &phy_vars_ue->dlsch_tc_init_stats,
             &phy_vars_ue->dlsch_tc_alpha_stats,
             &phy_vars_ue->dlsch_tc_beta_stats,
             &phy_vars_ue->dlsch_tc_gamma_stats,
             &phy_vars_ue->dlsch_tc_ext_stats,
             &phy_vars_ue->dlsch_tc_intl1_stats,
             &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);


      stop_meas(dlsch_turbo_decoding_stats);
494
    }
495
#else
496
    if ((harq_process->C == 1) ||
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
	((r==harq_process->C-1) && (skipped_last==0))) { // last segment with odd number of segments

      start_meas(dlsch_turbo_decoding_stats);
      ret = tc
            (&harq_process->d[r][96],
             harq_process->c[r],
             Kr,
             f1f2mat_old[iind*2],
             f1f2mat_old[(iind*2)+1],
             dlsch->max_turbo_iterations,
             crc_type,
             (r==0) ? harq_process->F : 0,
             &phy_vars_ue->dlsch_tc_init_stats,
             &phy_vars_ue->dlsch_tc_alpha_stats,
             &phy_vars_ue->dlsch_tc_beta_stats,
             &phy_vars_ue->dlsch_tc_gamma_stats,
             &phy_vars_ue->dlsch_tc_ext_stats,
             &phy_vars_ue->dlsch_tc_intl1_stats,
             &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
      stop_meas(dlsch_turbo_decoding_stats);
      //      printf("single decode, exit\n");
      //      exit(-1);
    }
    else {
    // we can merge code segments
      if ((skipped_last == 0) && (r<harq_process->C-1)) {
	skipped_last = 1;
	Kr_last = Kr;
      }
      else {
	skipped_last=0;
528

529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
	if (Kr_last == Kr) { // decode 2 code segments with AVX2 version
#ifdef DEBUG_DLSCH_DECODING
	  printf("single decoding segment %d (%p)\n",r-1,&harq_process->d[r-1][96]);
#endif
	  start_meas(dlsch_turbo_decoding_stats);
#ifdef DEBUG_DLSCH_DECODING
	  printf("double decoding segments %d,%d (%p,%p)\n",r-1,r,&harq_process->d[r-1][96],&harq_process->d[r][96]);
#endif
	  ret = tc_2cw
            (&harq_process->d[r-1][96],
	     &harq_process->d[r][96],
             harq_process->c[r-1],
             harq_process->c[r],
             Kr,
             f1f2mat_old[iind*2],
             f1f2mat_old[(iind*2)+1],
             dlsch->max_turbo_iterations,
             crc_type,
             (r==0) ? harq_process->F : 0,
             &phy_vars_ue->dlsch_tc_init_stats,
             &phy_vars_ue->dlsch_tc_alpha_stats,
             &phy_vars_ue->dlsch_tc_beta_stats,
             &phy_vars_ue->dlsch_tc_gamma_stats,
             &phy_vars_ue->dlsch_tc_ext_stats,
             &phy_vars_ue->dlsch_tc_intl1_stats,
             &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
	  /*
	  ret = tc
            (&harq_process->d[r-1][96],
             harq_process->c[r-1],
             Kr_last,
             f1f2mat_old[iind*2],
             f1f2mat_old[(iind*2)+1],
             dlsch->max_turbo_iterations,
             crc_type,
             (r==0) ? harq_process->F : 0,
             &phy_vars_ue->dlsch_tc_init_stats,
             &phy_vars_ue->dlsch_tc_alpha_stats,
             &phy_vars_ue->dlsch_tc_beta_stats,
             &phy_vars_ue->dlsch_tc_gamma_stats,
             &phy_vars_ue->dlsch_tc_ext_stats,
             &phy_vars_ue->dlsch_tc_intl1_stats,
             &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
572

573
574
	     exit(-1);*/
	  stop_meas(dlsch_turbo_decoding_stats);
575
	}
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
	else { // Kr_last != Kr
	  start_meas(dlsch_turbo_decoding_stats);
	  ret = tc
            (&harq_process->d[r-1][96],
             harq_process->c[r-1],
             Kr_last,
             f1f2mat_old[iind*2],
             f1f2mat_old[(iind*2)+1],
             dlsch->max_turbo_iterations,
             crc_type,
             (r==0) ? harq_process->F : 0,
             &phy_vars_ue->dlsch_tc_init_stats,
             &phy_vars_ue->dlsch_tc_alpha_stats,
             &phy_vars_ue->dlsch_tc_beta_stats,
             &phy_vars_ue->dlsch_tc_gamma_stats,
             &phy_vars_ue->dlsch_tc_ext_stats,
             &phy_vars_ue->dlsch_tc_intl1_stats,
             &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
	  stop_meas(dlsch_turbo_decoding_stats);
595

596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
	  start_meas(dlsch_turbo_decoding_stats);
	  ret = tc
            (&harq_process->d[r][96],
             harq_process->c[r],
             Kr,
             f1f2mat_old[iind*2],
             f1f2mat_old[(iind*2)+1],
             dlsch->max_turbo_iterations,
             crc_type,
             (r==0) ? harq_process->F : 0,
             &phy_vars_ue->dlsch_tc_init_stats,
             &phy_vars_ue->dlsch_tc_alpha_stats,
             &phy_vars_ue->dlsch_tc_beta_stats,
             &phy_vars_ue->dlsch_tc_gamma_stats,
             &phy_vars_ue->dlsch_tc_ext_stats,
             &phy_vars_ue->dlsch_tc_intl1_stats,
             &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
	  stop_meas(dlsch_turbo_decoding_stats);
614

Bilel's avatar
Bilel committed
615
616
617
618
619
620
621
	  printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f  dlsch_turbo_decoding_stats %5.3f \n",
              harq_process->C,
              r,
              dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
              dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
              dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));

622
623
624
625
	}
      }
    }
#endif
626

627

628
    if ((err_flag == 0) && (ret>=(1+dlsch->max_turbo_iterations))) {// a Code segment is in error so break;
629
      //printf("CRC failed, segment %d\n",r);
630
631
      err_flag = 1;
    }
632
  }
633

634
635
636
637
638
  int32_t frame_rx_prev = frame;
  int32_t subframe_rx_prev = subframe - 1;
  if (subframe_rx_prev < 0) {
    frame_rx_prev--;
    subframe_rx_prev += 10;
639
  }
640
  frame_rx_prev = frame_rx_prev%1024;
641
642

  if (err_flag == 1) {
643
644
645
    LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, round %d, subframe %d)\n",
        phy_vars_ue->Mod_id, frame_rx_prev, subframe_rx_prev, harq_pid, harq_process->round, subframe);

646
647
648
    dlsch->harq_ack[subframe].ack = 0;
    dlsch->harq_ack[subframe].harq_id = harq_pid;
    dlsch->harq_ack[subframe].send_harq_status = 1;
649
    harq_process->errors[harq_process->round]++;
650
    harq_process->round++;
651

Gabriel's avatar
Gabriel committed
652

knopp's avatar
knopp committed
653
    //    printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
654
655
    if (harq_process->round >= dlsch->Mdlharq) {
      harq_process->status = SCH_IDLE;
Bilel's avatar
Bilel committed
656
657
658
659
660
661
      harq_process->round  = 0;
    }
    if(is_crnti)
    {
    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
               phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
662
    }
663

664
    return((1+dlsch->max_turbo_iterations));
665
  } else {
666

667
668
669
670
671
    harq_process->status = SCH_IDLE;
    harq_process->round  = 0;
    dlsch->harq_ack[subframe].ack = 1;
    dlsch->harq_ack[subframe].harq_id = harq_pid;
    dlsch->harq_ack[subframe].send_harq_status = 1;
Bilel's avatar
Bilel committed
672
673
674
    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, pid status %d, round %d, subframe %d)\n",
        phy_vars_ue->Mod_id, frame_rx_prev, subframe_rx_prev, harq_pid, harq_process->status, harq_process->round, subframe);

Gabriel's avatar
Gabriel committed
675
676
677
678
    if(is_crnti)
    {
    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS);
    }
679
    //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
knopp's avatar
   
knopp committed
680

681
  }
682

683
684
  // Reassembly of Transport block here
  offset = 0;
685
686

  /*
687
688
689
  printf("harq_pid %d\n",harq_pid);
  printf("F %d, Fbytes %d\n",harq_process->F,harq_process->F>>3);
  printf("C %d\n",harq_process->C);
690
  */
691
  for (r=0; r<harq_process->C; r++) {
692
693
694
695
696
697
    if (r<harq_process->Cminus)
      Kr = harq_process->Kminus;
    else
      Kr = harq_process->Kplus;

    Kr_bytes = Kr>>3;
698

699
700
701
    //    printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes);
    if (r==0) {
      memcpy(harq_process->b,
702
703
             &harq_process->c[0][(harq_process->F>>3)],
             Kr_bytes - (harq_process->F>>3)- ((harq_process->C>1)?3:0));
704
      offset = Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0);
705
      //            printf("copied %d bytes to b sequence (harq_pid %d)\n",
706
      //          Kr_bytes - (harq_process->F>>3),harq_pid);
707
      //          printf("b[0] = %x,c[%d] = %x\n",
708
709
710
711
      //      harq_process->b[0],
      //      harq_process->F>>3,
      //      harq_process->c[0][(harq_process->F>>3)]);
    } else {
712
      memcpy(harq_process->b+offset,
713
714
             harq_process->c[r],
             Kr_bytes- ((harq_process->C>1)?3:0));
715
716
717
      offset += (Kr_bytes - ((harq_process->C>1)?3:0));
    }
  }
718

719
720
  dlsch->last_iteration_cnt = ret;

721
722
723
724
725
726
727
728
729
730
  return(ret);
}

#ifdef PHY_ABSTRACTION
#include "SIMULATION/TOOLS/defs.h"
#ifdef OPENAIR2
#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/defs.h"
#endif

731
732
733
int dlsch_abstraction_EESM(double* sinr_dB, uint8_t TM, uint32_t rb_alloc[4], uint8_t mcs, uint8_t dl_power_off)
{

734
  int ii;
735
736
737
738
  double sinr_eff = 0;
  int rb_count = 0;
  int offset;
  double bler = 0;
739
740
741
742

  if(TM==5 && dl_power_off==1) {
    //do nothing -- means there is no second UE and TM 5 is behaving like TM 6 for a singal user
  } else
743
    TM = TM-1;
744

745
746
747
  for (offset = 0; offset <= 24; offset++) {
    if (rb_alloc[0] & (1<<offset)) {
      rb_count++;
748
749
750
751
752
753
754
755

      for(ii=0; ii<12; ii++) {
        sinr_eff += exp(-(pow(10, 0.1*(sinr_dB[(offset*12)+ii])))/beta1_dlsch[TM][mcs]);
        //printf("sinr_eff1 = %f, power %lf\n",sinr_eff, exp(-pow(10,6.8)));

        //  sinr_eff += exp(-(pow(10, (sinr_dB[offset*2+1])/10))/beta1_dlsch[TM][mcs]);
        //printf("sinr_dB[%d]=%f\n",offset,sinr_dB[offset*2]);
      }
756
    }
757
758
  }

759
  LOG_D(OCM,"sinr_eff (lin, unweighted) = %f\n",sinr_eff);
760
  sinr_eff =  -beta2_dlsch[TM][mcs]*log((sinr_eff)/(12*rb_count));
761
  LOG_D(OCM,"sinr_eff (lin, weighted) = %f\n",sinr_eff);
762
  sinr_eff = 10 * log10(sinr_eff);
763
  LOG_D(OCM,"sinr_eff (dB) = %f\n",sinr_eff);
764

765
  bler = interp(sinr_eff,&sinr_bler_map[mcs][0][0],&sinr_bler_map[mcs][1][0],table_length[mcs]);
766

767
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
768

769
770
  if (uniformrandom() < bler) {
    LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f, TM %d)\n",mcs,sinr_eff,bler, TM);
771
    return(1);
772
  } else {
773
    LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f, TM %d)\n",mcs,sinr_eff,bler, TM);
774
775
    return(1);
  }
776

777
778
779
#endif
}

780
781
int dlsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint32_t rb_alloc[4], uint8_t mcs,uint8_t dl_power_off)
{
782
  int ii;
783
784
  double sinr_eff = 0;
  double x = 0;
785
  double I =0;
786
787
788
789
790
791
792
793
  double qpsk_max=12.2;
  double qam16_max=19.2;
  double qam64_max=25.2;
  double sinr_min = -20;
  int rb_count = 0;
  int offset=0;
  double bler = 0;

794
795
796
797
798
799
  if(TM==5 && dl_power_off==1) {
    //do nothing -- means there is no second UE and TM 5 is behaving like TM 6 for a singal user
  } else
    TM = TM-1;


800
801
802
  for (offset = 0; offset <= 24; offset++) {
    if (rb_alloc[0] & (1<<offset)) {
      rb_count++;
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828

      for(ii=0; ii<12; ii++) {
        //x is the sinr_dB in dB
        x = sinr_dB[(offset*12)+ii] - 10*log10(beta1_dlsch_MI[TM][mcs]);

        if(x<sinr_min)
          I +=0;
        else {
          if(mcs<10) {
            if(x>qpsk_max)
              I += 1;
            else
              I += (q_qpsk[0]*pow(x,7) + q_qpsk[1]*pow(x,6) + q_qpsk[2]*pow(x,5) + q_qpsk[3]*pow(x,4) + q_qpsk[4]*pow(x,3) + q_qpsk[5]*pow(x,2) + q_qpsk[6]*x + q_qpsk[7]);
          } else if(mcs>9 && mcs<17) {
            if(x>qam16_max)
              I += 1;
            else
              I += (q_qam16[0]*pow(x,7) + q_qam16[1]*pow(x,6) + q_qam16[2]*pow(x,5) + q_qam16[3]*pow(x,4) + q_qam16[4]*pow(x,3) + q_qam16[5]*pow(x,2) + q_qam16[6]*x + q_qam16[7]);
          } else if(mcs>16 && mcs<23) {

            if(x>qam64_max)
              I += 1;
            else
              I += (q_qam64[0]*pow(x,7) + q_qam64[1]*pow(x,6) + q_qam64[2]*pow(x,5) + q_qam64[3]*pow(x,4) + q_qam64[4]*pow(x,3) + q_qam64[5]*pow(x,2) + q_qam64[6]*x + q_qam64[7]);
          }
        }
829
830
831
      }
    }
  }
832
833
834

  // averaging of accumulated MI
  I = I/(12*rb_count);
835
  //Now  I->SINR_effective Mapping
836
837
838
839
840
841
842
843
844
845

  if(mcs<10) {
    sinr_eff = (p_qpsk[0]*pow(I,7) + p_qpsk[1]*pow(I,6) + p_qpsk[2]*pow(I,5) + p_qpsk[3]*pow(I,4) + p_qpsk[4]*pow(I,3) + p_qpsk[5]*pow(I,2) + p_qpsk[6]*I + p_qpsk[7]);
  } else if(mcs>9 && mcs<17) {
    sinr_eff = (p_qam16[0]*pow(I,7) + p_qam16[1]*pow(I,6) + p_qam16[2]*pow(I,5) + p_qam16[3]*pow(I,4) + p_qam16[4]*pow(I,3) + p_qam16[5]*pow(I,2) + p_qam16[6]*I + p_qam16[7]);
  } else if(mcs>16 && mcs<23) {
    sinr_eff = (p_qam64[0]*pow(I,7) + p_qam64[1]*pow(I,6) + p_qam64[2]*pow(I,5) + p_qam64[3]*pow(I,4) + p_qam64[4]*pow(I,3) + p_qam64[5]*pow(I,2) + p_qam64[6]*I + p_qam64[7]);
  }

  //sinr_eff = sinr_eff + 10*log10(beta2_dlsch_MI[TM][mcs]);
846
  LOG_D(OCM,"SINR_Eff = %e\n",sinr_eff);
847

848
  bler = interp(sinr_eff,&sinr_bler_map[mcs][0][0],&sinr_bler_map[mcs][1][0],table_length[mcs]);
849

850
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
851

852
  if (uniformrandom() < bler) {
853
    LOG_N(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
854
    return(0);
855
  } else {
856
    LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
857
858
    return(1);
  }
859

860
#endif
861
}
862
863

uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
864
                             uint8_t subframe,
865
                             PDSCH_t dlsch_id,
866
867
                             uint8_t eNB_id)
{
868
869
870
871
872
873
874

  LTE_UE_DLSCH_t *dlsch_ue;
  LTE_eNB_DLSCH_t *dlsch_eNB;
  uint8_t harq_pid;
  uint32_t eNB_id2;
  uint32_t ue_id;
#ifdef DEBUG_DLSCH_DECODING
gauthier's avatar
gauthier committed
875
  uint16_t i;
876
#endif
knopp's avatar
   
knopp committed
877
  uint8_t CC_id = phy_vars_ue->CC_id;
878

879
  // may not be necessary for PMCH??
880
  for (eNB_id2=0; eNB_id2<NB_eNB_INST; eNB_id2++) {
881
    if (PHY_vars_eNB_g[eNB_id2][CC_id]->frame_parms.Nid_cell == phy_vars_ue->frame_parms.Nid_cell)
882
883
      break;
  }
884

885
886
  if (eNB_id2==NB_eNB_INST) {
    LOG_E(PHY,"FATAL : Could not find attached eNB for DLSCH emulation !!!!\n");
887
    mac_xface->macphy_exit("Could not find attached eNB for DLSCH emulation");
888
889
890
891
892
893
894
895
  }

  LOG_D(PHY,"[UE] dlsch_decoding_emul : subframe %d, eNB_id %d, dlsch_id %d\n",subframe,eNB_id2,dlsch_id);

  //  printf("dlsch_eNB_ra->harq_processes[0] %p\n",PHY_vars_eNB_g[eNB_id]->dlsch_eNB_ra->harq_processes[0]);


  switch (dlsch_id) {
896
897
898
  case SI_PDSCH: // SI
    dlsch_ue = phy_vars_ue->dlsch_SI[eNB_id];
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch_SI;
899
    //    printf("Doing SI: TBS %d\n",dlsch_ue->harq_processes[0]->TBS>>3);
900
    memcpy(dlsch_ue->harq_processes[0]->b,dlsch_eNB->harq_processes[0]->b,dlsch_ue->harq_processes[0]->TBS>>3);
901
#ifdef DEBUG_DLSCH_DECODING
902
    LOG_D(PHY,"SI Decoded\n");
903
904

    for (i=0; i<dlsch_ue->harq_processes[0]->TBS>>3; i++)
905
      LOG_T(PHY,"%x.",dlsch_eNB->harq_processes[0]->b[i]);
906

907
908
909
910
    LOG_T(PHY,"\n");
#endif
    return(1);
    break;
911

912
913
914
  case RA_PDSCH: // RA
    dlsch_ue  = phy_vars_ue->dlsch_ra[eNB_id];
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch_ra;
915
    memcpy(dlsch_ue->harq_processes[0]->b,dlsch_eNB->harq_processes[0]->b,dlsch_ue->harq_processes[0]->TBS>>3);
916
#ifdef DEBUG_DLSCH_DECODING
917
    LOG_D(PHY,"RA Decoded\n");
918
919

    for (i=0; i<dlsch_ue->harq_processes[0]->TBS>>3; i++)
920
      LOG_T(PHY,"%x.",dlsch_eNB->harq_processes[0]->b[i]);
921

922
923
924
925
    LOG_T(PHY,"\n");
#endif
    return(1);
    break;
926

927
  case PDSCH: // TB0
Bilel's avatar
Bilel committed
928
    dlsch_ue  = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0];
929
    harq_pid = dlsch_ue->current_harq_pid;
930
    ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]);
931
    DevAssert( ue_id != (uint32_t)-1 );
932
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[ue_id][0];
933
934

#ifdef DEBUG_DLSCH_DECODING
935
936

    for (i=0; i<dlsch_ue->harq_processes[harq_pid]->TBS>>3; i++)
937
      LOG_T(PHY,"%x.",dlsch_eNB->harq_processes[harq_pid]->b[i]);
938

939
940
941
    LOG_T(PHY,"\n current harq pid is %d ue id %d \n", harq_pid, ue_id);
#endif

942
943
944
945
946
947
    if (dlsch_abstraction_MIESM(phy_vars_ue->sinr_dB,
                                phy_vars_ue->transmission_mode[eNB_id],
                                dlsch_eNB->harq_processes[harq_pid]->rb_alloc,
                                dlsch_eNB->harq_processes[harq_pid]->mcs,
                                PHY_vars_eNB_g[eNB_id][CC_id]->mu_mimo_mode[ue_id].dl_pow_off) == 1) {
      // reset HARQ
948
949
950
951
952
      dlsch_ue->harq_processes[harq_pid]->status = SCH_IDLE;
      dlsch_ue->harq_processes[harq_pid]->round  = 0;
      dlsch_ue->harq_ack[subframe].ack = 1;
      dlsch_ue->harq_ack[subframe].harq_id = harq_pid;
      dlsch_ue->harq_ack[subframe].send_harq_status = 1;
953

954
      if (dlsch_ue->harq_processes[harq_pid]->round == 0)
955
956
957
958
        memcpy(dlsch_ue->harq_processes[harq_pid]->b,
               dlsch_eNB->harq_processes[harq_pid]->b,
               dlsch_ue->harq_processes[harq_pid]->TBS>>3);

959
      return(1);
960
    } else {
961
962
963
964
965
966
      // retransmission
      dlsch_ue->harq_processes[harq_pid]->status = ACTIVE;
      dlsch_ue->harq_processes[harq_pid]->round++;
      dlsch_ue->harq_ack[subframe].ack = 0;
      dlsch_ue->harq_ack[subframe].harq_id = harq_pid;
      dlsch_ue->harq_ack[subframe].send_harq_status = 1;
967
      dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
968
      return(1+dlsch_ue->max_turbo_iterations);
969
    }
970
971

    break;
972

973
  case PDSCH1: { // TB1
Bilel's avatar
Bilel committed
974
    dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1];
975
    harq_pid = dlsch_ue->current_harq_pid;
976
    int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] );
977
    DevAssert( UE_id != -1 );
978
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[UE_id][1];
979
    // reset HARQ
980
981
982
983
984
    dlsch_ue->harq_processes[harq_pid]->status = SCH_IDLE;
    dlsch_ue->harq_processes[harq_pid]->round  = 0;
    dlsch_ue->harq_ack[subframe].ack = 1;
    dlsch_ue->harq_ack[subframe].harq_id = harq_pid;
    dlsch_ue->harq_ack[subframe].send_harq_status = 1;
985

986
    if (dlsch_ue->harq_processes[harq_pid]->round == 0)
987
      memcpy(dlsch_eNB->harq_processes[harq_pid]->b,dlsch_ue->harq_processes[harq_pid]->b,dlsch_ue->harq_processes[harq_pid]->TBS>>3);
988

989
    break;
990
  }
991

992
  case PMCH: // PMCH
993

994
995
    dlsch_ue  = phy_vars_ue->dlsch_MCH[eNB_id];
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch_MCH;
996
997
998

    LOG_D(PHY,"decoding pmch emul (size is %d, enb %d %d)\n",  dlsch_ue->harq_processes[0]->TBS>>3, eNB_id, eNB_id2);
#ifdef DEBUG_DLSCH_DECODING
999
1000

    for (i=0; i<dlsch_ue->harq_processes[0]->TBS>>3; i++)
1001
      printf("%x.",dlsch_eNB->harq_processes[0]->b[i]);
1002

1003
    printf("\n");
1004
#endif
1005

1006
    /*
1007
1008
1009
      if (dlsch_abstraction_MIESM(phy_vars_ue->sinr_dB, phy_vars_ue->transmission_mode[eNB_id], dlsch_eNB->rb_alloc,
        dlsch_eNB->harq_processes[0]->mcs,PHY_vars_eNB_g[eNB_id]->mu_mimo_mode[ue_id].dl_pow_off) == 1) {
    */
1010
    if (1) {
1011
      // reset HARQ
1012
1013
1014
      dlsch_ue->harq_processes[0]->status = SCH_IDLE;
      dlsch_ue->harq_processes[0]->round  = 0;
      memcpy(dlsch_ue->harq_processes[0]->b,
1015
1016
             dlsch_eNB->harq_processes[0]->b,
             dlsch_ue->harq_processes[0]->TBS>>3);
1017
      dlsch_ue->last_iteration_cnt = 1;
1018
      return(1);
1019
    } else {
1020
      // retransmission
1021
      dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
1022
1023
      return(1+dlsch_ue->max_turbo_iterations);
    }
1024

1025
    break;
1026

1027
  default:
Bilel's avatar
Bilel committed
1028
    dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0];
1029
    LOG_E(PHY,"dlsch_decoding_emul: FATAL, unknown DLSCH_id %d\n",dlsch_id);
1030
    dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
1031
1032
1033
1034
1035
1036
1037
    return(1+dlsch_ue->max_turbo_iterations);
  }

  LOG_E(PHY,"[FATAL] dlsch_decoding.c: Should never exit here ...\n");
  return(0);
}
#endif