dlsch_coding.c 35.2 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_coding.c
* \brief Top-level routines for implementing 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 "PHY/defs.h"
#include "PHY/extern.h"
#include "PHY/CODING/defs.h"
#include "PHY/CODING/extern.h"
#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/LTE_TRANSPORT/defs.h"
39
#include "PHY/LTE_TRANSPORT/proto.h"
Cedric Roux's avatar
Cedric Roux committed
40
#include "SCHED/defs.h"
41
#include "defs.h"
42
#include "UTIL/LOG/vcd_signal_dumper.h"
43 44
#include "UTIL/LOG/log.h"
#include <syscall.h>
45

46
//#define DEBUG_DLSCH_CODING
47
//#define DEBUG_DLSCH_FREE 1
root's avatar
root committed
48
//#define TD_DECODING
49 50

/*
51 52 53
#define is_not_pilot(pilots,first_pilot,re) (pilots==0) || \
  ((pilots==1)&&(first_pilot==1)&&(((re>2)&&(re<6))||((re>8)&&(re<12)))) || \
  ((pilots==1)&&(first_pilot==0)&&(((re<3))||((re>5)&&(re<9)))) \
54 55 56 57
*/
#define is_not_pilot(pilots,first_pilot,re) (1)


58 59
void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch)
{
60 61 62 63 64
  int i;
  int r;

  if (dlsch) {
#ifdef DEBUG_DLSCH_FREE
65
    printf("Freeing dlsch %p\n",dlsch);
66
#endif
67 68

    for (i=0; i<dlsch->Mdlharq; i++) {
69
#ifdef DEBUG_DLSCH_FREE
70
      printf("Freeing dlsch process %d\n",i);
71
#endif
72

73 74
      if (dlsch->harq_processes[i]) {
#ifdef DEBUG_DLSCH_FREE
75
        printf("Freeing dlsch process %d (%p)\n",i,dlsch->harq_processes[i]);
76
#endif
77 78 79 80

        if (dlsch->harq_processes[i]->b) {
          free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES);
          dlsch->harq_processes[i]->b = NULL;
81
#ifdef DEBUG_DLSCH_FREE
82
          printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
83
#endif
84 85
        }

86
#ifdef DEBUG_DLSCH_FREE
87
        printf("Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c);
88
#endif
89 90

        for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) {
91

92
#ifdef DEBUG_DLSCH_FREE
93
          printf("Freeing dlsch process %d c[%d] (%p)\n",i,r,dlsch->harq_processes[i]->c[r]);
94
#endif
95

96
          if (dlsch->harq_processes[i]->c[r]) {
97
            free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+1056);
98 99
            dlsch->harq_processes[i]->c[r] = NULL;
          }
100
          if (dlsch->harq_processes[i]->d[r]) {
101
            free16(dlsch->harq_processes[i]->d[r],(96+12+3+(3*8448)));
102 103
            dlsch->harq_processes[i]->d[r] = NULL;
          }
104

105 106 107
	}
	free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t));
	dlsch->harq_processes[i] = NULL;
108 109
      }
    }
110

111
    free16(dlsch,sizeof(LTE_eNB_DLSCH_t));
112
    dlsch = NULL;
113
    }
114

115 116
}

117
LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms)
118
{
119 120

  LTE_eNB_DLSCH_t *dlsch;
121 122
  unsigned char exit_flag = 0,i,j,r,aa,layer;
  int re;
123
  unsigned char bw_scaling =1;
124 125 126

  switch (N_RB_DL) {
  case 6:
127 128
    bw_scaling =16;
    break;
129

130 131 132
  case 25:
    bw_scaling =4;
    break;
133 134

  case 50:
135 136
    bw_scaling =2;
    break;
137

138 139 140 141
  default:
    bw_scaling =1;
    break;
  }
142

143
  dlsch = (LTE_eNB_DLSCH_t *)malloc16(sizeof(LTE_eNB_DLSCH_t));
144

145 146 147 148
  if (dlsch) {
    bzero(dlsch,sizeof(LTE_eNB_DLSCH_t));
    dlsch->Kmimo = Kmimo;
    dlsch->Mdlharq = Mdlharq;
149
    dlsch->Mlimit = 4;
150
    dlsch->Nsoft = Nsoft;
151

152 153
    for (layer=0; layer<4; layer++) {
      dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
154

155 156 157 158 159 160 161 162 163 164 165
       for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
         dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
         for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
           dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
         }
       }
     }

     dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
     for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
       dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
166

167 168
     }

169
    for (i=0; i<10; i++)
170 171
      dlsch->harq_ids[i] = Mdlharq;

172
    for (i=0; i<Mdlharq; i++) {
173
      dlsch->harq_processes[i] = (LTE_DL_eNB_HARQ_t *)malloc16(sizeof(LTE_DL_eNB_HARQ_t));
174
      LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n",
175 176
            MAX_DLSCH_PAYLOAD_BYTES/bw_scaling,bw_scaling, i,dlsch->harq_processes[i]);

177
      if (dlsch->harq_processes[i]) {
178 179 180 181 182 183 184
        bzero(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t));
        //    dlsch->harq_processes[i]->first_tx=1;
        dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);

        if (dlsch->harq_processes[i]->b) {
          bzero(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
        } else {
185
          printf("Can't get b\n");
186 187 188 189 190 191
          exit_flag=1;
        }

        if (abstraction_flag==0) {
          for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
            // account for filler in first segment and CRCs for multiple segment case
192
            dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+ 1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
193
            dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16((96+12+3+(3*8448)));
194
            if (dlsch->harq_processes[i]->c[r]) {
195
              bzero(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+ 1056);
196
            } else {
197
              printf("Can't get c\n");
198 199
              exit_flag=2;
            }
200
            if (dlsch->harq_processes[i]->d[r]) {
Hongzhi Wang's avatar
Hongzhi Wang committed
201
              bzero(dlsch->harq_processes[i]->d[r],(96+12+3+(3*8448)));
202
            } else {
203
              printf("Can't get d\n");
204 205
              exit_flag=2;
            }
206
          }
207 208
        }
      } else {
209
        printf("Can't get harq_p %d\n",i);
210
        exit_flag=3;
211 212
      }
    }
213

214
    if (exit_flag==0) {
215 216 217
      for (i=0; i<Mdlharq; i++) {
        dlsch->harq_processes[i]->round=0;

218 219 220 221 222 223
	for (j=0; j<96; j++)
	  for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
	    //      printf("dlsch->harq_processes[%d]->d[%d] %p\n",i,r,dlsch->harq_processes[i]->d[r]);
	    if (dlsch->harq_processes[i]->d[r])
	      dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
	  }
224

225
      }
226

227 228 229
      return(dlsch);
    }
  }
230

231 232
  LOG_D(PHY,"new_eNB_dlsch exit flag %d, size of  %ld\n",
	exit_flag, sizeof(LTE_eNB_DLSCH_t));
233 234
  free_eNB_dlsch(dlsch);
  return(NULL);
235 236


237 238
}

239
void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch)
240
{
241 242 243

  unsigned char Mdlharq;
  unsigned char i,j,r;
244

245 246 247 248
  if (dlsch) {
    Mdlharq = dlsch->Mdlharq;
    dlsch->rnti = 0;
    dlsch->active = 0;
249 250

    for (i=0; i<10; i++)
251 252
      dlsch->harq_ids[i] = Mdlharq;

253
    for (i=0; i<Mdlharq; i++) {
254
      if (dlsch->harq_processes[i]) {
255 256 257 258
        //  dlsch->harq_processes[i]->Ndi    = 0;
        dlsch->harq_processes[i]->status = 0;
        dlsch->harq_processes[i]->round  = 0;

259 260 261 262
	for (j=0; j<96; j++)
	  for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++)
	    if (dlsch->harq_processes[i]->d[r])
	      dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
263

264 265 266 267 268
      }
    }
  }
}

269

270 271 272 273 274 275 276 277 278 279 280 281
int dlsch_encoding_2threads0(te_params *tep) {

  LTE_eNB_DLSCH_t *dlsch          = tep->dlsch;
  unsigned int G                  = tep->G;

  unsigned short iind;
  unsigned char harq_pid = dlsch->current_harq_pid;
  unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
  unsigned int Kr=0,Kr_bytes,r,r_offset=0;
  unsigned short m=dlsch->harq_processes[harq_pid]->mcs;


282
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_IN);
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345

  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet

    for (r=0; r<dlsch->harq_processes[harq_pid]->C>>1; r++) {

      if (r<dlsch->harq_processes[harq_pid]->Cminus)
        Kr = dlsch->harq_processes[harq_pid]->Kminus;
      else
        Kr = dlsch->harq_processes[harq_pid]->Kplus;

      Kr_bytes = Kr>>3;

      // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
      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 {
        printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
        return(-1);
      }



      threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r],
                                Kr>>3,
                                &dlsch->harq_processes[harq_pid]->d[r][96],
                                (r==0) ? dlsch->harq_processes[harq_pid]->F : 0,
                                f1f2mat_old[iind*2],   // f1 (see 36121-820, page 14)
                                f1f2mat_old[(iind*2)+1]  // f2 (see 36121-820, page 14)
                               );
      dlsch->harq_processes[harq_pid]->RTC[r] =
        sub_block_interleaving_turbo(4+(Kr_bytes*8),
                                     &dlsch->harq_processes[harq_pid]->d[r][96],
                                     dlsch->harq_processes[harq_pid]->w[r]);
    }

  }

  // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
  // outputs for each code segment, see Section 5.1.5 p.20

  for (r=0; r<dlsch->harq_processes[harq_pid]->C>>1; r++) {
    r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
                                        G,  //G
                                        dlsch->harq_processes[harq_pid]->w[r],
                                        dlsch->harq_processes[harq_pid]->e+r_offset,
                                        dlsch->harq_processes[harq_pid]->C, // C
                                        dlsch->Nsoft,                    // Nsoft,
                                        dlsch->Mdlharq,
                                        dlsch->Kmimo,
                                        dlsch->harq_processes[harq_pid]->rvidx,
                                        get_Qm(dlsch->harq_processes[harq_pid]->mcs),
                                        dlsch->harq_processes[harq_pid]->Nl,
                                        r,
                                        nb_rb,
                                        m);                       // r
  }

346
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT);
347 348 349 350 351 352

  return(0);
}

extern int oai_exit;
void *te_thread(void *param) {
353 354
  pthread_setname_np( pthread_self(),"te processing");
  LOG_I(PHY,"thread te created id=%ld", syscall(__NR_gettid));
355 356 357 358

  eNB_proc_t *proc = &((te_params *)param)->eNB->proc;
  while (!oai_exit) {

359

360
    if (wait_on_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread")<0) break;
361 362 363

    dlsch_encoding_2threads0((te_params*)param);

364

365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
    if (release_thread(&proc->mutex_te,&proc->instance_cnt_te,"te thread")<0) break;

    if (pthread_cond_signal(&proc->cond_te) != 0) {
      printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
      exit_fun( "ERROR pthread_cond_signal" );
      return(NULL);
    }
  }

  return(NULL);
}

int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
			    unsigned char *a,
			    uint8_t num_pdcch_symbols,
			    LTE_eNB_DLSCH_t *dlsch,
			    int frame,
			    uint8_t subframe,
			    time_stats_t *rm_stats,
			    time_stats_t *te_stats,
			    time_stats_t *i_stats)
{

  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
  eNB_proc_t *proc = &eNB->proc;
  unsigned int G;
  unsigned int crc=1;
  unsigned short iind;

  unsigned char harq_pid = dlsch->current_harq_pid;
  unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
  unsigned int A;
  unsigned char mod_order;
  unsigned int Kr=0,Kr_bytes,r,r_offset=0;
  unsigned short m=dlsch->harq_processes[harq_pid]->mcs;

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);

  A = dlsch->harq_processes[harq_pid]->TBS; //6228
  mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs);
405
  G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0);
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438


  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet

    // Add 24-bit crc (polynomial A) to payload
    crc = crc24a(a,
                 A)>>8;
    a[A>>3] = ((uint8_t*)&crc)[2];
    a[1+(A>>3)] = ((uint8_t*)&crc)[1];
    a[2+(A>>3)] = ((uint8_t*)&crc)[0];

    dlsch->harq_processes[harq_pid]->B = A+24;
    memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);

    if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
                         dlsch->harq_processes[harq_pid]->c,
                         dlsch->harq_processes[harq_pid]->B,
                         &dlsch->harq_processes[harq_pid]->C,
                         &dlsch->harq_processes[harq_pid]->Cplus,
                         &dlsch->harq_processes[harq_pid]->Cminus,
                         &dlsch->harq_processes[harq_pid]->Kplus,
                         &dlsch->harq_processes[harq_pid]->Kminus,
                         &dlsch->harq_processes[harq_pid]->F)<0)
      return(-1);



    if (proc->instance_cnt_te==0) {
      printf("[eNB] TE thread busy\n");
      exit_fun("TE thread busy");
      pthread_mutex_unlock( &proc->mutex_te );
      return(-1);
    }
439

440
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
441 442 443 444 445 446
    ++proc->instance_cnt_te;

    proc->tep.eNB               = eNB;
    proc->tep.dlsch             = dlsch;
    proc->tep.G                 = G;

447
    // wakeup worker to do second half segments
448 449 450 451 452 453 454 455
    if (pthread_cond_signal(&proc->cond_te) != 0) {
      printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
      exit_fun( "ERROR pthread_cond_signal" );
      return (-1);
    }

    pthread_mutex_unlock( &proc->mutex_te );

456
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
    for (r=dlsch->harq_processes[harq_pid]->C>>1; r<dlsch->harq_processes[harq_pid]->C; r++) {

      if (r<dlsch->harq_processes[harq_pid]->Cminus)
        Kr = dlsch->harq_processes[harq_pid]->Kminus;
      else
        Kr = dlsch->harq_processes[harq_pid]->Kplus;

      Kr_bytes = Kr>>3;

      // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
      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 {
        printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
        return(-1);
      }


      start_meas(te_stats);
      threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r],
                                Kr>>3,
                                &dlsch->harq_processes[harq_pid]->d[r][96],
                                (r==0) ? dlsch->harq_processes[harq_pid]->F : 0,
                                f1f2mat_old[iind*2],   // f1 (see 36121-820, page 14)
                                f1f2mat_old[(iind*2)+1]  // f2 (see 36121-820, page 14)
                               );
      stop_meas(te_stats);

      start_meas(i_stats);
      dlsch->harq_processes[harq_pid]->RTC[r] =
        sub_block_interleaving_turbo(4+(Kr_bytes*8),
                                     &dlsch->harq_processes[harq_pid]->d[r][96],
                                     dlsch->harq_processes[harq_pid]->w[r]);
      stop_meas(i_stats);
    }

  }
  else {

    proc->tep.eNB          = eNB;
    proc->tep.dlsch        = dlsch;
    proc->tep.G            = G;
505 506

    // wakeup worker to do second half segments
507 508 509 510 511 512 513 514 515 516
    if (pthread_cond_signal(&proc->cond_te) != 0) {
      printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
      exit_fun( "ERROR pthread_cond_signal" );
      return (-1);
    }
  }

  // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
  // outputs for each code segment, see Section 5.1.5 p.20

517
  for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
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

    // get information for E for the segments that are handled by the worker thread
    if (r<(dlsch->harq_processes[harq_pid]->C>>1)) {
      int Nl=dlsch->harq_processes[harq_pid]->Nl;
      int Qm=get_Qm(dlsch->harq_processes[harq_pid]->mcs);
      int C = dlsch->harq_processes[harq_pid]->C;
      int Gp = G/Nl/Qm;
      int GpmodC = Gp%C;
      if (r < (C-(GpmodC)))
	r_offset += Nl*Qm * (Gp/C);
      else
	r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
    }
    else  {
      start_meas(rm_stats);
      r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
					  G,  //G
					  dlsch->harq_processes[harq_pid]->w[r],
					  dlsch->harq_processes[harq_pid]->e+r_offset,
					  dlsch->harq_processes[harq_pid]->C, // C
					  dlsch->Nsoft,                    // Nsoft,
					  dlsch->Mdlharq,
					  dlsch->Kmimo,
					  dlsch->harq_processes[harq_pid]->rvidx,
					  get_Qm(dlsch->harq_processes[harq_pid]->mcs),
					  dlsch->harq_processes[harq_pid]->Nl,
					  r,
					  nb_rb,
					  m);                       // r
      stop_meas(rm_stats);
    }
  }

  // wait for worker to finish

553 554
  wait_on_busy_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread");

555 556 557 558 559 560

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);

  return(0);
}

Florian Kaltenberger's avatar
Florian Kaltenberger committed
561 562
int dlsch_encoding(PHY_VARS_eNB *eNB,
		   unsigned char *a,
563 564 565 566 567 568 569 570 571
                   uint8_t num_pdcch_symbols,
                   LTE_eNB_DLSCH_t *dlsch,
                   int frame,
                   uint8_t subframe,
                   time_stats_t *rm_stats,
                   time_stats_t *te_stats,
                   time_stats_t *i_stats)
{

572 573 574
  unsigned int G;
  unsigned int crc=1;
  unsigned short iind;
575

Florian Kaltenberger's avatar
Florian Kaltenberger committed
576
  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
577
  unsigned char harq_pid = dlsch->current_harq_pid;
578
  unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
wang's avatar
wang committed
579 580
  unsigned int A, Z;
  unsigned *pz = &Z;
581
  unsigned char mod_order;
582
  unsigned int Kr=0,Kr_bytes,r,r_offset=0,Kr_int=0;
583
  unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
Xiwen JIANG's avatar
Xiwen JIANG committed
584
  uint8_t beamforming_mode=0;
585
  uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
wang's avatar
wang committed
586
  double rate = 0.33;
587

588
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
589

590
  A = dlsch->harq_processes[harq_pid]->TBS; //6228
Hongzhi Wang's avatar
Hongzhi Wang committed
591
  printf("Encoder: A: %d frame.subframe %d.%d \n",A, frame,subframe);
592 593
  mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs);

594
  if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7)
Xiwen JIANG's avatar
Xiwen JIANG committed
595
    beamforming_mode = 7;
596
  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8)
Xiwen JIANG's avatar
Xiwen JIANG committed
597
    beamforming_mode = 8;
598
  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10)
Xiwen JIANG's avatar
Xiwen JIANG committed
599 600
    beamforming_mode = 9;
  G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode);
601

602

603 604
  //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
605 606 607
#ifdef DEBUG_DLSCH_CODING
  printf("encoding thinks this is a new packet \n");
#endif
608 609 610 611 612 613 614 615
    /*
    int i;
    printf("dlsch (tx): \n");
    for (i=0;i<(A>>3);i++)
      printf("%02x.",a[i]);
    printf("\n");
    */
    // Add 24-bit crc (polynomial A) to payload
Florian Kaltenberger's avatar
Florian Kaltenberger committed
616
    crc = crc24a(a,
617
                 A)>>8;
618 619 620
    a[A>>3] = ((uint8_t*)&crc)[2];
    a[1+(A>>3)] = ((uint8_t*)&crc)[1];
    a[2+(A>>3)] = ((uint8_t*)&crc)[0];
621 622 623 624 625
    //    printf("CRC %x (A %d)\n",crc,A);

    dlsch->harq_processes[harq_pid]->B = A+24;
    //    dlsch->harq_processes[harq_pid]->b = a;
    memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
626

wang's avatar
wang committed
627
#ifdef TD_DECODING
Florian Kaltenberger's avatar
Florian Kaltenberger committed
628 629 630 631 632 633 634 635 636
    if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
                         dlsch->harq_processes[harq_pid]->c,
                         dlsch->harq_processes[harq_pid]->B,
                         &dlsch->harq_processes[harq_pid]->C,
                         &dlsch->harq_processes[harq_pid]->Cplus,
                         &dlsch->harq_processes[harq_pid]->Cminus,
                         &dlsch->harq_processes[harq_pid]->Kplus,
                         &dlsch->harq_processes[harq_pid]->Kminus,
                         &dlsch->harq_processes[harq_pid]->F)<0)
637
      return(-1);
wang's avatar
wang committed
638 639 640 641 642 643 644 645 646 647 648
#else

    nr_segmentation(dlsch->harq_processes[harq_pid]->b,
            dlsch->harq_processes[harq_pid]->c,
            dlsch->harq_processes[harq_pid]->B,
            &dlsch->harq_processes[harq_pid]->C,
			&dlsch->harq_processes[harq_pid]->Kplus,
			&dlsch->harq_processes[harq_pid]->Kminus,
        						pz,
								&dlsch->harq_processes[harq_pid]->F);
#endif
649

650 651

    //printf("Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F);
652

Hongzhi Wang's avatar
Hongzhi Wang committed
653
#ifdef TD_DECODING
654
    for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
Hongzhi Wang's avatar
Hongzhi Wang committed
655 656 657
      if (r<dlsch->harq_processes[harq_pid]->Cminus)
        Kr = dlsch->harq_processes[harq_pid]->Kminus;
      else
658
        Kr = dlsch->harq_processes[harq_pid]->Kplus;
Hongzhi Wang's avatar
Hongzhi Wang committed
659 660 661
#else
      Kr = dlsch->harq_processes[harq_pid]->Kplus;
#endif
662

663
      Kr_bytes = Kr>>3;
664

665 666
      // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
      if (Kr_bytes<=64)
667
        iind = (Kr_bytes-5);
668
      else if (Kr_bytes <=128)
669
        iind = 59 + ((Kr_bytes-64)>>1);
670
      else if (Kr_bytes <= 256)
671
        iind = 91 + ((Kr_bytes-128)>>2);
672
      else if (Kr_bytes <= 768)
673
        iind = 123 + ((Kr_bytes-256)>>3);
674
      else {
675
        printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
wang's avatar
wang committed
676
       // return(-1);
677
      }
678 679


680 681 682
#ifdef DEBUG_DLSCH_CODING
      printf("Generating Code Segment %d (%d bits)\n",r,Kr);
      // generate codewords
683

684 685 686 687
      printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A);
      printf("N_RB = %d\n",nb_rb);
      printf("Ncp %d\n",frame_parms->Ncp);
      printf("mod_order %d\n",mod_order);
688
#endif
689

Hongzhi Wang's avatar
Hongzhi Wang committed
690
      //double rate = 0.33;
691 692

#ifdef DEBUG_DLSCH_CODING
693
      printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]);
694 695
#endif
      start_meas(te_stats);
wang's avatar
wang committed
696 697

#ifdef TD_DECODING
698
      threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r],
699 700 701 702 703
                                Kr>>3,
                                &dlsch->harq_processes[harq_pid]->d[r][96],
                                (r==0) ? dlsch->harq_processes[harq_pid]->F : 0,
                                f1f2mat_old[iind*2],   // f1 (see 36121-820, page 14)
                                f1f2mat_old[(iind*2)+1]  // f2 (see 36121-820, page 14)
704
                               );
705 706
      stop_meas(te_stats);
    }
wang's avatar
wang committed
707
#else
708

709 710
    Kr = dlsch->harq_processes[harq_pid]->Kplus;
    
711
    //workaround for nr ldpc using lte interleaving
712
    Kr_bytes = Kr>>3;
713 714 715 716
    if (dlsch->harq_processes[harq_pid]->C >= 2)
    	Kr_int = G/(3*dlsch->harq_processes[harq_pid]->C);
    else
    	Kr_int = Kr;
wang's avatar
wang committed
717

718 719 720 721 722
    for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
      d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][96];
#ifdef DEBUG_DLSCH_CODING
      printf("start ldpc encoder segment %d/%d\n",r,dlsch->harq_processes[harq_pid]->C);
      printf("input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]);
wang's avatar
wang committed
723
#endif
724 725 726 727 728
      //ldpc_encoder((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],&dlsch->harq_processes[harq_pid]->d[r][96],Kr,rate);
    }
    start_meas(te_stats);
    ldpc_encoder_multi_segment(dlsch->harq_processes[harq_pid]->c,d_tmp,Kr,rate,dlsch->harq_processes[harq_pid]->C);
    stop_meas(te_stats);
wang's avatar
wang committed
729
#endif
730
      /*printf("end ldpc encoder -- output\n");
wang's avatar
wang committed
731

732

733 734 735 736 737
	printf("output %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->d[r][96], dlsch->harq_processes[harq_pid]->d[r][96+1], dlsch->harq_processes[harq_pid]->d[r][96+2],dlsch->harq_processes[harq_pid]->d[r][96+3], dlsch->harq_processes[harq_pid]->d[r][96+4]);
	for (int cnt =0 ; cnt < 66*(*pz); cnt ++){
	printf("%d \n",  dlsch->harq_processes[harq_pid]->d[r][96+cnt]);
	}
	printf("\n");*/
738

739
#ifdef DEBUG_DLSCH_CODING
740
      write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[0][96],(3*8*Kr_bytes)+12,1,4);
741
#endif
742

743
      start_meas(i_stats);
744 745
      for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
	dlsch->harq_processes[harq_pid]->RTC[r] =
746
	  sub_block_interleaving_turbo((Kr_int),
747 748 749
				       &dlsch->harq_processes[harq_pid]->d[r][96],
				       dlsch->harq_processes[harq_pid]->w[r]);
      }
750
      stop_meas(i_stats);
751

752 753 754 755 756
  }

  // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
  // outputs for each code segment, see Section 5.1.5 p.20

757
  for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
758
#ifdef DEBUG_DLSCH_CODING
759
    printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
760 761 762 763
        r,
        G,
        Kr*3,
        mod_order,nb_rb);
764 765 766
#endif

    start_meas(rm_stats);
767 768 769
#ifdef DEBUG_DLSCH_CODING
  printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
#endif
770
    r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
771 772
                                        G,  //G
                                        dlsch->harq_processes[harq_pid]->w[r],
Florian Kaltenberger's avatar
Florian Kaltenberger committed
773
                                        dlsch->harq_processes[harq_pid]->e+r_offset,
774
                                        dlsch->harq_processes[harq_pid]->C, // C
775
                                        dlsch->Nsoft,                    // Nsoft,
776 777 778 779 780 781 782 783
                                        dlsch->Mdlharq,
                                        dlsch->Kmimo,
                                        dlsch->harq_processes[harq_pid]->rvidx,
                                        get_Qm(dlsch->harq_processes[harq_pid]->mcs),
                                        dlsch->harq_processes[harq_pid]->Nl,
                                        r,
                                        nb_rb,
                                        m);                       // r
784 785
    stop_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING
786

787
    if (r==dlsch->harq_processes[harq_pid]->C-1)
788
      write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4);
789

790 791
#endif
  }
792

793
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
794

795 796 797
  return(0);
}

798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825

int dlsch_encoding_SIC(PHY_VARS_UE *ue,
                   unsigned char *a,
                   uint8_t num_pdcch_symbols,
                   LTE_eNB_DLSCH_t *dlsch,
                   int frame,
                   uint8_t subframe,
                   time_stats_t *rm_stats,
                   time_stats_t *te_stats,
                   time_stats_t *i_stats)
{

  unsigned int G;
  unsigned int crc=1;
  unsigned short iind;

  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
  unsigned char harq_pid = dlsch->current_harq_pid;
  unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
  unsigned int A;
  unsigned char mod_order;
  unsigned int Kr=0,Kr_bytes,r,r_offset=0;
  unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
  uint8_t beamforming_mode=0;

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);

  A = dlsch->harq_processes[harq_pid]->TBS; //6228
826
  printf("Encoder: A: %d\n",A);
827 828 829 830 831 832 833 834 835 836 837 838 839
  mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs);

  if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7)
    beamforming_mode = 7;
  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8)
    beamforming_mode = 8;
  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10)
    beamforming_mode = 9;
  G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode);


  //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
840 841 842
#ifdef DEBUG_DLSCH_CODING
  printf("SIC encoding thinks this is a new packet \n");
#endif
843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948
    /*
    int i;
    printf("dlsch (tx): \n");
    for (i=0;i<(A>>3);i++)
      printf("%02x.",a[i]);
    printf("\n");
    */
    // Add 24-bit crc (polynomial A) to payload
    crc = crc24a(a,
                 A)>>8;
    a[A>>3] = ((uint8_t*)&crc)[2];
    a[1+(A>>3)] = ((uint8_t*)&crc)[1];
    a[2+(A>>3)] = ((uint8_t*)&crc)[0];
    //    printf("CRC %x (A %d)\n",crc,A);

    dlsch->harq_processes[harq_pid]->B = A+24;
    //    dlsch->harq_processes[harq_pid]->b = a;
    memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);

    if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
                         dlsch->harq_processes[harq_pid]->c,
                         dlsch->harq_processes[harq_pid]->B,
                         &dlsch->harq_processes[harq_pid]->C,
                         &dlsch->harq_processes[harq_pid]->Cplus,
                         &dlsch->harq_processes[harq_pid]->Cminus,
                         &dlsch->harq_processes[harq_pid]->Kplus,
                         &dlsch->harq_processes[harq_pid]->Kminus,
                         &dlsch->harq_processes[harq_pid]->F)<0)
      return(-1);

    for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {

      if (r<dlsch->harq_processes[harq_pid]->Cminus)
        Kr = dlsch->harq_processes[harq_pid]->Kminus;
      else
        Kr = dlsch->harq_processes[harq_pid]->Kplus;

      Kr_bytes = Kr>>3;

      // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
      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 {
        printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
        return(-1);
      }


#ifdef DEBUG_DLSCH_CODING
      printf("Generating Code Segment %d (%d bits)\n",r,Kr);
      // generate codewords

      printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A);
      printf("N_RB = %d\n",nb_rb);
      printf("Ncp %d\n",frame_parms->Ncp);
      printf("mod_order %d\n",mod_order);
#endif


#ifdef DEBUG_DLSCH_CODING
      printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]);
#endif
      start_meas(te_stats);
      threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r],
                                Kr>>3,
                                &dlsch->harq_processes[harq_pid]->d[r][96],
                                (r==0) ? dlsch->harq_processes[harq_pid]->F : 0,
                                f1f2mat_old[iind*2],   // f1 (see 36121-820, page 14)
                                f1f2mat_old[(iind*2)+1]  // f2 (see 36121-820, page 14)
                               );
      stop_meas(te_stats);
#ifdef DEBUG_DLSCH_CODING

      if (r==0)
        write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[r][96],(3*8*Kr_bytes)+12,1,4);

#endif
      start_meas(i_stats);
      dlsch->harq_processes[harq_pid]->RTC[r] =
        sub_block_interleaving_turbo(4+(Kr_bytes*8),
                                     &dlsch->harq_processes[harq_pid]->d[r][96],
                                     dlsch->harq_processes[harq_pid]->w[r]);
      stop_meas(i_stats);
    }

  }

  // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
  // outputs for each code segment, see Section 5.1.5 p.20

  for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
#ifdef DEBUG_DLSCH_CODING
    printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
        r,
        G,
        Kr*3,
        mod_order,nb_rb);
#endif

    start_meas(rm_stats);
949 950 951
#ifdef DEBUG_DLSCH_CODING
    printf("rvidx in SIC encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
#endif
952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982
    r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
                                        G,  //G
                                        dlsch->harq_processes[harq_pid]->w[r],
                                        dlsch->harq_processes[harq_pid]->e+r_offset,
                                        dlsch->harq_processes[harq_pid]->C, // C
                                        dlsch->Nsoft,                    // Nsoft,
                                        dlsch->Mdlharq,
                                        dlsch->Kmimo,
                                        dlsch->harq_processes[harq_pid]->rvidx,
                                        get_Qm(dlsch->harq_processes[harq_pid]->mcs),
                                        dlsch->harq_processes[harq_pid]->Nl,
                                        r,
                                        nb_rb,
                                        m);                       // r
    stop_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING

    if (r==dlsch->harq_processes[harq_pid]->C-1)
      write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4);

#endif
  }

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);

  return(0);
}




983 984
#ifdef PHY_ABSTRACTION
void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
985 986 987
                         uint8_t *DLSCH_pdu,
                         LTE_eNB_DLSCH_t *dlsch)
{
988 989 990 991 992

  //int payload_offset = 0;
  unsigned char harq_pid = dlsch->current_harq_pid;
  unsigned short i;

993 994
  //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {
  if (dlsch->harq_processes[harq_pid]->round == 0) {
995
    memcpy(dlsch->harq_processes[harq_pid]->b,
996 997 998 999 1000 1001 1002 1003
           DLSCH_pdu,
           dlsch->harq_processes[harq_pid]->TBS>>3);
    LOG_D(PHY, "eNB %d dlsch_encoding_emul, tbs is %d harq pid %d \n",
          phy_vars_eNB->Mod_id,
          dlsch->harq_processes[harq_pid]->TBS>>3,
          harq_pid);

    for (i=0; i<dlsch->harq_processes[harq_pid]->TBS>>3; i++)
1004
      LOG_T(PHY,"%x.",DLSCH_pdu[i]);
1005

1006 1007
    LOG_T(PHY,"\n");

Raymond Knopp's avatar
 
Raymond Knopp committed
1008
    memcpy(&eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].transport_blocks[eNB_transport_info_TB_index[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]],
1009 1010 1011 1012 1013
           //     memcpy(&eNB_transport_info[phy_vars_eNB->Mod_id].transport_blocks[payload_offset],
           DLSCH_pdu,
           dlsch->harq_processes[harq_pid]->TBS>>3);
  }

Raymond Knopp's avatar
 
Raymond Knopp committed
1014
  eNB_transport_info_TB_index[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]+=dlsch->harq_processes[harq_pid]->TBS>>3;
1015
  //payload_offset +=dlsch->harq_processes[harq_pid]->TBS>>3;
1016

1017 1018
}
#endif