dlsch_decoding.c 31.2 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3
    Copyright(c) 1999 - 2014 Eurecom
4

ghaddab's avatar
ghaddab committed
5
6
7
8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9
10


ghaddab's avatar
ghaddab committed
11
12
13
14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

ghaddab's avatar
ghaddab committed
16
    You should have received a copy of the GNU General Public License
17
18
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
ghaddab's avatar
ghaddab committed
19
   see <http://www.gnu.org/licenses/>.
20
21

  Contact Information
ghaddab's avatar
ghaddab committed
22
23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

ghaddab's avatar
ghaddab committed
28
 *******************************************************************************/
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

/*! \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
47
//#define DEBUG_DLSCH_DECODING
48

49

50
51
void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch)
{
52
53
54
55

  int i,r;

  if (dlsch) {
56
    for (i=0; i<dlsch->Mdlharq; i++) {
57
      if (dlsch->harq_processes[i]) {
58
59
60
61
62
63
        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++) {
64
65
66
          free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
          dlsch->harq_processes[i]->c[r] = NULL;
        }
67
68
69
70
71
72
73
74
75

        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;
76
77
      }
    }
78
79
80

    free16(dlsch,sizeof(LTE_UE_DLSCH_t));
    dlsch = NULL;
81
82
83
  }
}

84
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)
85
{
86
87
88

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

90
  unsigned char bw_scaling =1;
91
92
93

  switch (N_RB_DL) {
  case 6:
94
95
    bw_scaling =16;
    break;
96

97
98
99
  case 25:
    bw_scaling =4;
    break;
100
101

  case 50:
102
103
    bw_scaling =2;
    break;
104

105
106
107
108
  default:
    bw_scaling =1;
    break;
  }
109

110
  dlsch = (LTE_UE_DLSCH_t *)malloc16(sizeof(LTE_UE_DLSCH_t));
111

112
  if (dlsch) {
113
    memset(dlsch,0,sizeof(LTE_UE_DLSCH_t));
114
115
    dlsch->Kmimo = Kmimo;
    dlsch->Mdlharq = Mdlharq;
116
    dlsch->Nsoft = Nsoft;
117
118
    dlsch->max_turbo_iterations = max_turbo_iterations;

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

123
      if (dlsch->harq_processes[i]) {
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
        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;
152
153
154
155
156
157
      }
    }

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

159
  printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(LTE_DL_UE_HARQ_t), exit_flag);
160
161
162
163
164
165
166
167
168
169
170
171
172
  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,
                         uint8_t subframe,
                         uint8_t harq_pid,
                         uint8_t is_crnti,
173
174
175
176
                         uint8_t llr8_flag)
{


177
178
179
180
181
182
  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
183
  uint16_t iind;
184
185
186
187
188
  //  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
189
  uint16_t i;
190
#endif
191
192
  //#ifdef __AVX2__
#if 0
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
  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 *);

212
213
#endif
  uint8_t (*tc)(int16_t *y,
214
215
216
217
218
219
220
221
222
223
224
225
226
227
                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 *);
228

229
230
231



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

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

  if (!frame_parms) {
243
    printf("dlsch_decoding.c: NULL frame_parms pointer\n");
244
    return(dlsch->max_turbo_iterations);
245
  }
246

247
  if (subframe>9) {
248
    printf("dlsch_decoding.c: Illegal subframe index %d\n",subframe);
249
    return(dlsch->max_turbo_iterations);
250
251
  }

252
  if (llr8_flag == 0) {
253
254
    //#ifdef __AVX2__
#if 0
255
256
    tc_2cw = phy_threegpplte_turbo_decoder16avx2;
#endif
257
    tc = phy_threegpplte_turbo_decoder16;
258
  }
259
260
  else
    tc = phy_threegpplte_turbo_decoder8;
261

262
263
264
265
  //  nb_rb = dlsch->nb_rb;

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

  /*harq_pid = dlsch->current_harq_pid;
  if (harq_pid >= 8) {
272
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
273
274
275
    return(max_turbo_iterations);
  }
  */
276
277
278

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

279
280
281
282
283
284
285
286
  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);

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

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

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

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
  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;
  }

333
  if (harq_process->C > MAX_NUM_DLSCH_SEGMENTS/bw_scaling) {
334
335
336
    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));
  }
337
338
339
340
#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

341
  for (r=0; r<harq_process->C; r++) {
342

343

344
345
346
347
348
    // Get Turbo interleaver parameters
    if (r<harq_process->Cminus)
      Kr = harq_process->Kminus;
    else
      Kr = harq_process->Kplus;
349

350
    Kr_bytes = Kr>>3;
351

352
353
354
355
356
357
358
359
360
    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 {
361
      printf("dlsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
362
      return(dlsch->max_turbo_iterations);
363
    }
364
365

#ifdef DEBUG_DLSCH_DECODING
366
    printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? harq_process->F : 0);
367
368
369
370
#endif

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

375
#ifdef DEBUG_DLSCH_DECODING
knopp's avatar
   
knopp committed
376
    LOG_I(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",
377
378
379
          harq_pid,r, G,
          Kr*3,
          harq_process->TBS,
380
          harq_process->Qm,
381
382
383
384
385
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
#endif
386

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

409
410
411
    r_offset += E;

    /*
412
    printf("Subblock deinterleaving, d %p w %p\n",
413
414
     harq_process->d[r],
     harq_process->w);
415
416
    */
    start_meas(dlsch_deinterleaving_stats);
417
418
    sub_block_deinterleaving_turbo(4+Kr,
                                   &harq_process->d[r][96],
419

420
                                   harq_process->w[r]);
421
    stop_meas(dlsch_deinterleaving_stats);
422
423

#ifdef DEBUG_DLSCH_DECODING
424
425
426
427
428
    /*
    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);
    }
429

430
    printf("decoder input(segment %d) :",r);
431
    int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
432
433
      printf("%d : %d\n",i,harq_process->d[r][96+i]);
      printf("\n");*/
434
#endif
435

436

437
    //    printf("Clearing c, %p\n",harq_process->c[r]);
438
    memset(harq_process->c[r],0,Kr_bytes);
439

440
    //    printf("done\n");
441
    if (harq_process->C == 1)
442
      crc_type = CRC24_A;
443
    else
444
445
      crc_type = CRC24_B;

446
    /*
447
    printf("decoder input(segment %d)\n",r);
448
    for (i=0;i<(3*8*Kr_bytes)+12;i++)
449
450
      if ((harq_process->d[r][96+i]>7) ||
    (harq_process->d[r][96+i] < -8))
451
452
    printf("%d : %d\n",i,harq_process->d[r][96+i]);
    printf("\n");
453
454
    */

455
456
    //#ifndef __AVX2__
#if 1
457
458
    if (err_flag == 0) {

459
      start_meas(dlsch_turbo_decoding_stats);
460
      ret = tc
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
            (&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);
479
    }
480
#else
481
    if ((harq_process->C == 1) ||
482
483
484
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
	((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;
513

514
515
516
517
518
519
520
521
522
523
524
525
526
527
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
	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);
557

558
559
	     exit(-1);*/
	  stop_meas(dlsch_turbo_decoding_stats);
560
	}
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
	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);
580

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
	  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);
599

600
601
602
603
	}
      }
    }
#endif
604

605

606
    if ((err_flag == 0) && (ret>=(1+dlsch->max_turbo_iterations))) {// a Code segment is in error so break;
607
      //printf("CRC failed, segment %d\n",r);
608
609
610
611
612
613
614
615
616
      err_flag = 1;
    }

  }

  if (err_flag == 1) {
    dlsch->harq_ack[subframe].ack = 0;
    dlsch->harq_ack[subframe].harq_id = harq_pid;
    dlsch->harq_ack[subframe].send_harq_status = 1;
617
    harq_process->errors[harq_process->round]++;
618
    harq_process->round++;
619

knopp's avatar
knopp committed
620
621
    //    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
    //    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);
622
623
624
    if (harq_process->round >= dlsch->Mdlharq) {
      harq_process->status = SCH_IDLE;
    }
625

626
    return((1+dlsch->max_turbo_iterations));
627
  } else {
628
629
630
631
632
    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;
knopp's avatar
   
knopp committed
633
634
    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);

635
  }
636

637
638
  // Reassembly of Transport block here
  offset = 0;
639
640

  /*
641
642
643
  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);
644
  */
645
  for (r=0; r<harq_process->C; r++) {
646
647
648
649
650
651
    if (r<harq_process->Cminus)
      Kr = harq_process->Kminus;
    else
      Kr = harq_process->Kplus;

    Kr_bytes = Kr>>3;
652

653
654
655
    //    printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes);
    if (r==0) {
      memcpy(harq_process->b,
656
657
             &harq_process->c[0][(harq_process->F>>3)],
             Kr_bytes - (harq_process->F>>3)- ((harq_process->C>1)?3:0));
658
      offset = Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0);
659
      //            printf("copied %d bytes to b sequence (harq_pid %d)\n",
660
      //          Kr_bytes - (harq_process->F>>3),harq_pid);
661
      //          printf("b[0] = %x,c[%d] = %x\n",
662
663
664
665
      //      harq_process->b[0],
      //      harq_process->F>>3,
      //      harq_process->c[0][(harq_process->F>>3)]);
    } else {
666
      memcpy(harq_process->b+offset,
667
668
             harq_process->c[r],
             Kr_bytes- ((harq_process->C>1)?3:0));
669
670
671
      offset += (Kr_bytes - ((harq_process->C>1)?3:0));
    }
  }
672

673
674
  dlsch->last_iteration_cnt = ret;

675
676
677
678
679
680
681
682
683
684
  return(ret);
}

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

685
686
687
int dlsch_abstraction_EESM(double* sinr_dB, uint8_t TM, uint32_t rb_alloc[4], uint8_t mcs, uint8_t dl_power_off)
{

688
  int ii;
689
690
691
692
  double sinr_eff = 0;
  int rb_count = 0;
  int offset;
  double bler = 0;
693
694
695
696

  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
697
    TM = TM-1;
698

699
700
701
  for (offset = 0; offset <= 24; offset++) {
    if (rb_alloc[0] & (1<<offset)) {
      rb_count++;
702
703
704
705
706
707
708
709

      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]);
      }
710
    }
711
712
  }

713
  LOG_D(OCM,"sinr_eff (lin, unweighted) = %f\n",sinr_eff);
714
  sinr_eff =  -beta2_dlsch[TM][mcs]*log((sinr_eff)/(12*rb_count));
715
  LOG_D(OCM,"sinr_eff (lin, weighted) = %f\n",sinr_eff);
716
  sinr_eff = 10 * log10(sinr_eff);
717
  LOG_D(OCM,"sinr_eff (dB) = %f\n",sinr_eff);
718

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

721
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
722

723
724
  if (uniformrandom() < bler) {
    LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f, TM %d)\n",mcs,sinr_eff,bler, TM);
725
    return(1);
726
  } else {
727
    LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f, TM %d)\n",mcs,sinr_eff,bler, TM);
728
729
    return(1);
  }
730

731
732
733
#endif
}

734
735
int dlsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint32_t rb_alloc[4], uint8_t mcs,uint8_t dl_power_off)
{
736
  int ii;
737
738
  double sinr_eff = 0;
  double x = 0;
739
  double I =0;
740
741
742
743
744
745
746
747
  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;

748
749
750
751
752
753
  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;


754
755
756
  for (offset = 0; offset <= 24; offset++) {
    if (rb_alloc[0] & (1<<offset)) {
      rb_count++;
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782

      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]);
          }
        }
783
784
785
      }
    }
  }
786
787
788

  // averaging of accumulated MI
  I = I/(12*rb_count);
789
  //Now  I->SINR_effective Mapping
790
791
792
793
794
795
796
797
798
799

  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]);
800
  LOG_D(OCM,"SINR_Eff = %e\n",sinr_eff);
801

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

804
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
805

806
  if (uniformrandom() < bler) {
807
    LOG_N(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
808
    return(0);
809
  } else {
810
    LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
811
812
    return(1);
  }
813

814
#endif
815
}
816
817

uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
818
                             uint8_t subframe,
819
                             PDSCH_t dlsch_id,
820
821
                             uint8_t eNB_id)
{
822
823
824
825
826
827
828

  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
829
  uint16_t i;
830
#endif
knopp's avatar
   
knopp committed
831
  uint8_t CC_id = phy_vars_ue->CC_id;
832

833
  // may not be necessary for PMCH??
834
  for (eNB_id2=0; eNB_id2<NB_eNB_INST; eNB_id2++) {
835
    if (PHY_vars_eNB_g[eNB_id2][CC_id]->frame_parms.Nid_cell == phy_vars_ue->frame_parms.Nid_cell)
836
837
      break;
  }
838

839
840
  if (eNB_id2==NB_eNB_INST) {
    LOG_E(PHY,"FATAL : Could not find attached eNB for DLSCH emulation !!!!\n");
841
    mac_xface->macphy_exit("Could not find attached eNB for DLSCH emulation");
842
843
844
845
846
847
848
849
  }

  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) {
850
851
852
  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;
853
    //    printf("Doing SI: TBS %d\n",dlsch_ue->harq_processes[0]->TBS>>3);
854
    memcpy(dlsch_ue->harq_processes[0]->b,dlsch_eNB->harq_processes[0]->b,dlsch_ue->harq_processes[0]->TBS>>3);
855
#ifdef DEBUG_DLSCH_DECODING
856
    LOG_D(PHY,"SI Decoded\n");
857
858

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

861
862
863
864
    LOG_T(PHY,"\n");
#endif
    return(1);
    break;
865

866
867
868
  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;
869
    memcpy(dlsch_ue->harq_processes[0]->b,dlsch_eNB->harq_processes[0]->b,dlsch_ue->harq_processes[0]->TBS>>3);
870
#ifdef DEBUG_DLSCH_DECODING
871
    LOG_D(PHY,"RA Decoded\n");
872
873

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

876
877
878
879
    LOG_T(PHY,"\n");
#endif
    return(1);
    break;
880

881
  case PDSCH: // TB0
882
    dlsch_ue  = phy_vars_ue->dlsch[eNB_id][0];
883
    harq_pid = dlsch_ue->current_harq_pid;
884
    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]);
885
    DevAssert( ue_id != (uint32_t)-1 );
886
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[ue_id][0];
887
888

#ifdef DEBUG_DLSCH_DECODING
889
890

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

893
894
895
    LOG_T(PHY,"\n current harq pid is %d ue id %d \n", harq_pid, ue_id);
#endif

896
897
898
899
900
901
    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
902
903
904
905
906
      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;
907

908
      if (dlsch_ue->harq_processes[harq_pid]->round == 0)
909
910
911
912
        memcpy(dlsch_ue->harq_processes[harq_pid]->b,
               dlsch_eNB->harq_processes[harq_pid]->b,
               dlsch_ue->harq_processes[harq_pid]->TBS>>3);

913
      return(1);
914
    } else {
915
916
917
918
919
920
      // 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;
921
      dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
922
      return(1+dlsch_ue->max_turbo_iterations);
923
    }
924
925

    break;
926

927
928
  case PDSCH1: { // TB1
    dlsch_ue = phy_vars_ue->dlsch[eNB_id][1];
929
    harq_pid = dlsch_ue->current_harq_pid;
930
    int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] );
931
    DevAssert( UE_id != -1 );
932
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[UE_id][1];
933
    // reset HARQ
934
935
936
937
938
    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;
939

940
    if (dlsch_ue->harq_processes[harq_pid]->round == 0)
941
      memcpy(dlsch_eNB->harq_processes[harq_pid]->b,dlsch_ue->harq_processes[harq_pid]->b,dlsch_ue->harq_processes[harq_pid]->TBS>>3);
942

943
    break;
944
  }
945

946
  case PMCH: // PMCH
947

948
949
    dlsch_ue  = phy_vars_ue->dlsch_MCH[eNB_id];
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch_MCH;
950
951
952

    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
953
954

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

957
    printf("\n");
958
#endif
959

960
    /*
961
962
963
      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) {
    */
964
    if (1) {
965
      // reset HARQ
966
967
968
      dlsch_ue->harq_processes[0]->status = SCH_IDLE;
      dlsch_ue->harq_processes[0]->round  = 0;
      memcpy(dlsch_ue->harq_processes[0]->b,
969
970
             dlsch_eNB->harq_processes[0]->b,
             dlsch_ue->harq_processes[0]->TBS>>3);
971
      dlsch_ue->last_iteration_cnt = 1;
972
      return(1);
973
    } else {
974
      // retransmission
975
      dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
976
977
      return(1+dlsch_ue->max_turbo_iterations);
    }
978

979
    break;
980

981
  default:
982
    dlsch_ue = phy_vars_ue->dlsch[eNB_id][0];
983
    LOG_E(PHY,"dlsch_decoding_emul: FATAL, unknown DLSCH_id %d\n",dlsch_id);
984
    dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
985
986
987
988
989
990
991
    return(1+dlsch_ue->max_turbo_iterations);
  }

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