dlsch_decoding.c 34.7 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
                         uint32_t frame,
164 165 166
                         uint8_t subframe,
                         uint8_t harq_pid,
                         uint8_t is_crnti,
167 168 169
                         uint8_t llr8_flag)
{

Gabriel's avatar
Gabriel committed
170
#if UE_TIMING_TRACE
171 172 173
  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;
Gabriel's avatar
Gabriel committed
174
#endif
175 176 177
  uint32_t A,E;
  uint32_t G;
  uint32_t ret,offset;
178
  uint16_t iind;
179 180 181 182 183
  //  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
184
  uint16_t i;
185
#endif
186 187
  //#ifdef __AVX2__
#if 0
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
  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 *);

207 208
#endif
  uint8_t (*tc)(int16_t *y,
209 210 211 212 213 214 215 216 217 218 219 220 221 222
                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 *);
223

224 225 226



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

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

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

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

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

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
  else
260 261 262 263 264 265
  {
	  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;
  }

266

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

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

275
  /*harq_pid = dlsch->current_harq_pid[subframe%RX_NB_TH];
276
  if (harq_pid >= 8) {
277
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
278 279 280
    return(max_turbo_iterations);
  }
  */
281 282 283

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

284 285 286 287 288 289 290 291
  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);

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

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

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

318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
  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;
  }

338
  if (harq_process->C > MAX_NUM_DLSCH_SEGMENTS/bw_scaling) {
339 340 341
    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));
  }
342 343 344 345
#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
346 347
  opp_enabled=1;

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

350

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

357
    Kr_bytes = Kr>>3;
358

359 360 361 362 363 364 365 366 367
    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 {
368
      printf("dlsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
369
      return(dlsch->max_turbo_iterations);
370
    }
371 372

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

Gabriel's avatar
Gabriel committed
376
#if UE_TIMING_TRACE
377
    start_meas(dlsch_rate_unmatching_stats);
Gabriel's avatar
Gabriel committed
378
#endif
379
    memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
380 381 382
    harq_process->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
                                            (uint8_t*) &dummy_w[r][0],
                                            (r==0) ? harq_process->F : 0);
383

384
#ifdef DEBUG_DLSCH_DECODING
Bilel's avatar
Bilel committed
385
    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",
386 387 388
          harq_pid,r, G,
          Kr*3,
          harq_process->TBS,
389
          harq_process->Qm,
390 391 392 393 394
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
#endif
395

396 397 398
#ifdef DEBUG_DLSCH_DECODING
    printf(" in decoding dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
#endif
399
    if (lte_rate_matching_turbo_rx(harq_process->RTC[r],
400 401 402 403 404
                                   G,
                                   harq_process->w[r],
                                   (uint8_t*)&dummy_w[r][0],
                                   dlsch_llr+r_offset,
                                   harq_process->C,
405
                                   dlsch->Nsoft,
406 407 408 409
                                   dlsch->Mdlharq,
                                   dlsch->Kmimo,
                                   harq_process->rvidx,
                                   (harq_process->round==0)?1:0,
410
                                   harq_process->Qm,
411 412 413
                                   harq_process->Nl,
                                   r,
                                   &E)==-1) {
Gabriel's avatar
Gabriel committed
414
#if UE_TIMING_TRACE
415
      stop_meas(dlsch_rate_unmatching_stats);
Gabriel's avatar
Gabriel committed
416
#endif
417
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
418
      return(dlsch->max_turbo_iterations);
419
    } else
Gabriel's avatar
Gabriel committed
420 421
    {
#if UE_TIMING_TRACE
422
      stop_meas(dlsch_rate_unmatching_stats);
Gabriel's avatar
Gabriel committed
423 424
#endif
    }
425 426 427
    r_offset += E;

    /*
428
    printf("Subblock deinterleaving, d %p w %p\n",
429 430
     harq_process->d[r],
     harq_process->w);
431
    */
Gabriel's avatar
Gabriel committed
432
#if UE_TIMING_TRACE
433
    start_meas(dlsch_deinterleaving_stats);
Gabriel's avatar
Gabriel committed
434
#endif
435 436
    sub_block_deinterleaving_turbo(4+Kr,
                                   &harq_process->d[r][96],
437

438
                                   harq_process->w[r]);
Gabriel's avatar
Gabriel committed
439
#if UE_TIMING_TRACE
440
    stop_meas(dlsch_deinterleaving_stats);
Gabriel's avatar
Gabriel committed
441
#endif
442
#ifdef DEBUG_DLSCH_DECODING
443 444 445 446 447
    /*
    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);
    }
448

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

455

456
    //    printf("Clearing c, %p\n",harq_process->c[r]);
457
    memset(harq_process->c[r],0,Kr_bytes);
458

459
    //    printf("done\n");
460
    if (harq_process->C == 1)
461
      crc_type = CRC24_A;
462
    else
463 464
      crc_type = CRC24_B;

465
    /*
466
    printf("decoder input(segment %d)\n",r);
467
    for (i=0;i<(3*8*Kr_bytes)+12;i++)
468 469
      if ((harq_process->d[r][96+i]>7) ||
    (harq_process->d[r][96+i] < -8))
470 471
    printf("%d : %d\n",i,harq_process->d[r][96+i]);
    printf("\n");
472 473
    */

474 475
    //#ifndef __AVX2__
#if 1
476
    if (err_flag == 0) {
Gabriel's avatar
Gabriel committed
477 478 479
/*
        LOG_I(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %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,crc_type,A,harq_process->TBS,
Bilel's avatar
Bilel committed
480
                            harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_turbo_iterations);
Gabriel's avatar
Gabriel committed
481
*/
482 483 484 485
    	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);
    	}
Gabriel's avatar
Gabriel committed
486 487 488
#if UE_TIMING_TRACE
        start_meas(dlsch_turbo_decoding_stats);
#endif
489
      LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
490
      ret = tc
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
            (&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);

Gabriel's avatar
Gabriel committed
507
#if UE_TIMING_TRACE
508
      stop_meas(dlsch_turbo_decoding_stats);
Gabriel's avatar
Gabriel committed
509
#endif
510
    }
511
#else
512
    if ((harq_process->C == 1) ||
513 514
	((r==harq_process->C-1) && (skipped_last==0))) { // last segment with odd number of segments

Gabriel's avatar
Gabriel committed
515 516 517
#if UE_TIMING_TRACE
        start_meas(dlsch_turbo_decoding_stats);
#endif
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
      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);
Gabriel's avatar
Gabriel committed
534
 #if UE_TIMING_TRACE
535
      stop_meas(dlsch_turbo_decoding_stats);
Gabriel's avatar
Gabriel committed
536
#endif
537 538 539 540 541 542 543 544 545 546 547
      //      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;
548

549 550 551 552
	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
Gabriel's avatar
Gabriel committed
553
#if UE_TIMING_TRACE
554
	  start_meas(dlsch_turbo_decoding_stats);
Gabriel's avatar
Gabriel committed
555
#endif
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
#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);
594

595
	     exit(-1);*/
Gabriel's avatar
Gabriel committed
596 597 598
#if UE_TIMING_TRACE
      stop_meas(dlsch_turbo_decoding_stats);
#endif
599
	}
600
	else { // Kr_last != Kr
Gabriel's avatar
Gabriel committed
601
#if UE_TIMING_TRACE
602
	  start_meas(dlsch_turbo_decoding_stats);
Gabriel's avatar
Gabriel committed
603
#endif
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
	  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);
Gabriel's avatar
Gabriel committed
620 621
#if UE_TIMING_TRACE
      stop_meas(dlsch_turbo_decoding_stats);
622

623
	  start_meas(dlsch_turbo_decoding_stats);
Gabriel's avatar
Gabriel committed
624 625
#endif

626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
	  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);
Gabriel's avatar
Gabriel committed
642 643 644

#if UE_TIMING_TRACE

645
	  stop_meas(dlsch_turbo_decoding_stats);
646

647
	  /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f  dlsch_turbo_decoding_stats %5.3f \n",
Bilel's avatar
Bilel committed
648 649 650 651
              harq_process->C,
              r,
              dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
              dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
652
              dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/
Gabriel's avatar
Gabriel committed
653
#endif
654 655 656 657
	}
      }
    }
#endif
658

659

660
    if ((err_flag == 0) && (ret>=(1+dlsch->max_turbo_iterations))) {// a Code segment is in error so break;
661
      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
662 663
      err_flag = 1;
    }
664
  }
665

666 667 668 669 670
  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;
671
  }
672
  frame_rx_prev = frame_rx_prev%1024;
673 674

  if (err_flag == 1) {
Gabriel's avatar
Gabriel committed
675 676 677 678
#if UE_DEBUG_TRACE
    LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
        phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
#endif
679 680 681
    dlsch->harq_ack[subframe].ack = 0;
    dlsch->harq_ack[subframe].harq_id = harq_pid;
    dlsch->harq_ack[subframe].send_harq_status = 1;
682
    harq_process->errors[harq_process->round]++;
683
    harq_process->round++;
684

685

knopp's avatar
knopp committed
686
    //    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);
687 688
    if (harq_process->round >= dlsch->Mdlharq) {
      harq_process->status = SCH_IDLE;
Bilel's avatar
Bilel committed
689 690 691 692
      harq_process->round  = 0;
    }
    if(is_crnti)
    {
693
    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
Bilel's avatar
Bilel committed
694
               phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
695
    }
696

697
    return((1+dlsch->max_turbo_iterations));
698
  } else {
Gabriel's avatar
Gabriel committed
699 700 701 702
#if UE_DEBUG_TRACE
      LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d mcs %d nb_rb %d\n",
           phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
#endif
Gabriel's avatar
Gabriel committed
703

704 705 706 707 708
    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;
Gabriel's avatar
Gabriel committed
709 710
    //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
      //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);
Bilel's avatar
Bilel committed
711

712 713
    if(is_crnti)
    {
714
    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);
715
    }
716
    //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
717

718
  }
719

720 721
  // Reassembly of Transport block here
  offset = 0;
722 723

  /*
724 725 726
  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);
727
  */
728
  for (r=0; r<harq_process->C; r++) {
729 730 731 732 733 734
    if (r<harq_process->Cminus)
      Kr = harq_process->Kminus;
    else
      Kr = harq_process->Kplus;

    Kr_bytes = Kr>>3;
735

736 737 738
    //    printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes);
    if (r==0) {
      memcpy(harq_process->b,
739 740
             &harq_process->c[0][(harq_process->F>>3)],
             Kr_bytes - (harq_process->F>>3)- ((harq_process->C>1)?3:0));
741
      offset = Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0);
742
      //            printf("copied %d bytes to b sequence (harq_pid %d)\n",
743
      //          Kr_bytes - (harq_process->F>>3),harq_pid);
744
      //          printf("b[0] = %x,c[%d] = %x\n",
745 746 747 748
      //      harq_process->b[0],
      //      harq_process->F>>3,
      //      harq_process->c[0][(harq_process->F>>3)]);
    } else {
749
      memcpy(harq_process->b+offset,
750 751
             harq_process->c[r],
             Kr_bytes- ((harq_process->C>1)?3:0));
752 753 754
      offset += (Kr_bytes - ((harq_process->C>1)?3:0));
    }
  }
755

756 757
  dlsch->last_iteration_cnt = ret;

758 759 760 761 762 763 764 765 766 767
  return(ret);
}

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

768 769 770
int dlsch_abstraction_EESM(double* sinr_dB, uint8_t TM, uint32_t rb_alloc[4], uint8_t mcs, uint8_t dl_power_off)
{

771
  int ii;
772 773 774 775
  double sinr_eff = 0;
  int rb_count = 0;
  int offset;
  double bler = 0;
776 777 778 779

  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
780
    TM = TM-1;
781

782 783 784
  for (offset = 0; offset <= 24; offset++) {
    if (rb_alloc[0] & (1<<offset)) {
      rb_count++;
785 786 787 788 789 790 791 792

      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]);
      }
793
    }
794 795
  }

796
  LOG_D(OCM,"sinr_eff (lin, unweighted) = %f\n",sinr_eff);
797
  sinr_eff =  -beta2_dlsch[TM][mcs]*log((sinr_eff)/(12*rb_count));
798
  LOG_D(OCM,"sinr_eff (lin, weighted) = %f\n",sinr_eff);
799
  sinr_eff = 10 * log10(sinr_eff);
800
  LOG_D(OCM,"sinr_eff (dB) = %f\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 807
  if (uniformrandom() < bler) {
    LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f, TM %d)\n",mcs,sinr_eff,bler, TM);
808
    return(1);
809
  } else {
810
    LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f, TM %d)\n",mcs,sinr_eff,bler, TM);
811 812
    return(1);
  }
813

814 815 816
#endif
}

817 818
int dlsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint32_t rb_alloc[4], uint8_t mcs,uint8_t dl_power_off)
{
819
  int ii;
820 821
  double sinr_eff = 0;
  double x = 0;
822
  double I =0;
823 824 825 826 827 828 829 830
  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;

831 832 833 834 835 836
  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;


837 838 839
  for (offset = 0; offset <= 24; offset++) {
    if (rb_alloc[0] & (1<<offset)) {
      rb_count++;
840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865

      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]);
          }
        }
866 867 868
      }
    }
  }
869 870 871

  // averaging of accumulated MI
  I = I/(12*rb_count);
872
  //Now  I->SINR_effective Mapping
873 874 875 876 877 878 879 880 881 882

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

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

887
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
888

889
  if (uniformrandom() < bler) {
890
    LOG_N(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
891
    return(0);
892
  } else {
893
    LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
894 895
    return(1);
  }
896

897
#endif
898
}
899 900

uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
901
                             uint8_t subframe,
902
                             PDSCH_t dlsch_id,
903 904
                             uint8_t eNB_id)
{
905 906 907 908 909 910 911

  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
912
  uint16_t i;
913
#endif
knopp's avatar
knopp committed
914
  uint8_t CC_id = phy_vars_ue->CC_id;
915

916
  // may not be necessary for PMCH??
917
  for (eNB_id2=0; eNB_id2<NB_eNB_INST; eNB_id2++) {
918
    if (PHY_vars_eNB_g[eNB_id2][CC_id]->frame_parms.Nid_cell == phy_vars_ue->frame_parms.Nid_cell)
919 920
      break;
  }
921

922 923
  if (eNB_id2==NB_eNB_INST) {
    LOG_E(PHY,"FATAL : Could not find attached eNB for DLSCH emulation !!!!\n");
924
    mac_xface->macphy_exit("Could not find attached eNB for DLSCH emulation");
925 926 927 928 929 930 931 932
  }

  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) {
933 934 935
  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;
936
    //    printf("Doing SI: TBS %d\n",dlsch_ue->harq_processes[0]->TBS>>3);
937
    memcpy(dlsch_ue->harq_processes[0]->b,dlsch_eNB->harq_processes[0]->b,dlsch_ue->harq_processes[0]->TBS>>3);
938
#ifdef DEBUG_DLSCH_DECODING
939
    LOG_D(PHY,"SI Decoded\n");
940 941

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

944 945 946 947
    LOG_T(PHY,"\n");
#endif
    return(1);
    break;
948

949 950 951
  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;
952
    memcpy(dlsch_ue->harq_processes[0]->b,dlsch_eNB->harq_processes[0]->b,dlsch_ue->harq_processes[0]->TBS>>3);
953
#ifdef DEBUG_DLSCH_DECODING
954
    LOG_D(PHY,"RA Decoded\n");
955 956

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

959 960 961 962
    LOG_T(PHY,"\n");
#endif
    return(1);
    break;
963

964
  case PDSCH: // TB0
965
    dlsch_ue  = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0];
966
    harq_pid = dlsch_ue->current_harq_pid;
967
    ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]);
968
    DevAssert( ue_id != (uint32_t)-1 );
969
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[ue_id][0];
970 971

#ifdef DEBUG_DLSCH_DECODING
972 973

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

976 977 978
    LOG_T(PHY,"\n current harq pid is %d ue id %d \n", harq_pid, ue_id);
#endif

979 980 981 982 983 984
    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
985 986 987 988 989
      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;
990

991
      if (dlsch_ue->harq_processes[harq_pid]->round == 0)
992 993 994 995
        memcpy(dlsch_ue->harq_processes[harq_pid]->b,
               dlsch_eNB->harq_processes[harq_pid]->b,
               dlsch_ue->harq_processes[harq_pid]->TBS>>3);

996
      return(1);
997
    } else {
998 999 1000 1001 1002 1003
      // 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;
1004
      dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
1005
      return(1+dlsch_ue->max_turbo_iterations);
1006
    }
1007 1008

    break;
1009

1010
  case PDSCH1: { // TB1
1011
    dlsch_ue = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1];
1012
    harq_pid = dlsch_ue->current_harq_pid;
1013
    int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] );
1014
    DevAssert( UE_id != -1 );
1015
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[UE_id][1];
1016
    // reset HARQ
1017 1018 1019 1020 1021
    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;
1022

1023
    if (dlsch_ue->harq_processes[harq_pid]->round == 0)
1024
      memcpy(dlsch_eNB->harq_processes[harq_pid]->b,dlsch_ue->harq_processes[harq_pid]->b,dlsch_ue->harq_processes[harq_pid]->TBS>>3);
1025

1026
    break;
1027
  }
1028

1029
  case PMCH: // PMCH
1030

1031 1032
    dlsch_ue  = phy_vars_ue->dlsch_MCH[eNB_id];
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch_MCH;
1033 1034 1035

    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
1036 1037

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

1040
    printf("\n");
1041
#endif
1042

1043
    /*
1044 1045 1046
      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) {
    */
1047
    if (1) {
1048
      // reset HARQ
1049 1050 1051
      dlsch_ue->harq_processes[0]->status = SCH_IDLE;
      dlsch_ue->harq_processes[0]->round  = 0;
      memcpy(dlsch_ue->harq_processes[0]->b,
1052 1053
             dlsch_eNB->harq_processes[0]->b,
             dlsch_ue->harq_processes[0]->TBS>>3);
1054
      dlsch_ue->last_iteration_cnt = 1;
1055
      return(1);
1056
    } else {
1057
      // retransmission
1058
      dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
1059 1060
      return(1+dlsch_ue->max_turbo_iterations);
    }
1061

1062
    break;
1063

1064
  default:
1065
    dlsch_ue = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0];
1066
    LOG_E(PHY,"dlsch_decoding_emul: FATAL, unknown DLSCH_id %d\n",dlsch_id);
1067
    dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
1068 1069 1070 1071 1072 1073 1074
    return(1+dlsch_ue->max_turbo_iterations);
  }

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