dlsch_decoding.c 34.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
                         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);
    }*/

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

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

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

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

453

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

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

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

472 473
    //#ifndef __AVX2__
#if 1
474
    if (err_flag == 0) {
Gabriel's avatar
Gabriel committed
475 476 477
/*
        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
478
                            harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_turbo_iterations);
Gabriel's avatar
Gabriel committed
479
*/
480 481 482 483
    	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
484 485 486
#if UE_TIMING_TRACE
        start_meas(dlsch_turbo_decoding_stats);
#endif
487
      LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
488
      ret = tc
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
            (&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
505
#if UE_TIMING_TRACE
506
      stop_meas(dlsch_turbo_decoding_stats);
Gabriel's avatar
Gabriel committed
507
#endif
508
    }
509
#else
510
    if ((harq_process->C == 1) ||
511 512
	((r==harq_process->C-1) && (skipped_last==0))) { // last segment with odd number of segments

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

547 548 549 550
	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
551
#if UE_TIMING_TRACE
552
	  start_meas(dlsch_turbo_decoding_stats);
Gabriel's avatar
Gabriel committed
553
#endif
554 555 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
#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);
592

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

621
	  start_meas(dlsch_turbo_decoding_stats);
Gabriel's avatar
Gabriel committed
622 623
#endif

624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
	  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
640 641 642

#if UE_TIMING_TRACE

643
	  stop_meas(dlsch_turbo_decoding_stats);
644

645
	  /*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
646 647 648 649
              harq_process->C,
              r,
              dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
              dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
650
              dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/
Gabriel's avatar
Gabriel committed
651
#endif
652 653 654 655
	}
      }
    }
#endif
656

657

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

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

  if (err_flag == 1) {
Gabriel's avatar
Gabriel committed
673 674 675 676
#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
677 678 679
    dlsch->harq_ack[subframe].ack = 0;
    dlsch->harq_ack[subframe].harq_id = harq_pid;
    dlsch->harq_ack[subframe].send_harq_status = 1;
680
    harq_process->errors[harq_process->round]++;
681
    harq_process->round++;
682

683

knopp's avatar
knopp committed
684
    //    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);
685 686
    if (harq_process->round >= dlsch->Mdlharq) {
      harq_process->status = SCH_IDLE;
Bilel's avatar
Bilel committed
687 688 689 690
      harq_process->round  = 0;
    }
    if(is_crnti)
    {
691
    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
692
               phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
693
    }
694

695
    return((1+dlsch->max_turbo_iterations));
696
  } else {
Gabriel's avatar
Gabriel committed
697 698 699 700
#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
701

702 703 704 705 706
    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
707 708
    //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
709

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

716
  }
717

718 719
  // Reassembly of Transport block here
  offset = 0;
720 721

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

    Kr_bytes = Kr>>3;
733

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

754 755
  dlsch->last_iteration_cnt = ret;

756 757 758 759 760 761 762 763 764 765
  return(ret);
}

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

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

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

  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
778
    TM = TM-1;
779

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

      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]);
      }
791
    }
792 793
  }

794
  LOG_D(OCM,"sinr_eff (lin, unweighted) = %f\n",sinr_eff);
795
  sinr_eff =  -beta2_dlsch[TM][mcs]*log((sinr_eff)/(12*rb_count));
796
  LOG_D(OCM,"sinr_eff (lin, weighted) = %f\n",sinr_eff);
797
  sinr_eff = 10 * log10(sinr_eff);
798
  LOG_D(OCM,"sinr_eff (dB) = %f\n",sinr_eff);
799

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

802
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
803

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

812 813 814
#endif
}

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

829 830 831 832 833 834
  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;


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

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

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

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

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

885
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
886

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

895
#endif
896
}
897 898

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

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

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

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

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

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

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

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

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

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

962
  case PDSCH: // TB0
963
    dlsch_ue  = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0];
964
    harq_pid = dlsch_ue->current_harq_pid;
Bilel's avatar
Bilel committed
965
    ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[subframe & 0x1][(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]);
966
    DevAssert( ue_id != (uint32_t)-1 );
967
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[ue_id][0];
968 969

#ifdef DEBUG_DLSCH_DECODING
970 971

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

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

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

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

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

    break;
1007

1008
  case PDSCH1: { // TB1
1009
    dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1];
1010
    harq_pid = dlsch_ue->current_harq_pid;
Bilel's avatar
Bilel committed
1011
    int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[subframe & 0x1][eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] );
1012
    DevAssert( UE_id != -1 );
1013
    dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[UE_id][1];
1014
    // reset HARQ
1015 1016 1017 1018 1019
    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;
1020

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

1024
    break;
1025
  }
1026

1027
  case PMCH: // PMCH
1028

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

    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
1034 1035

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

1038
    printf("\n");
1039
#endif
1040

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

1060
    break;
1061

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

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