ulsch_coding.c 31.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * 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
 */

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
/*! \file PHY/LTE_TRANSPORT/ulsch_coding.c
* \brief Top-level routines for coding the ULSCH transport channel as described in 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"
#include "defs.h"
#include "extern.h"
#include "SIMULATION/ETH_TRANSPORT/extern.h"
43
#include "UTIL/LOG/vcd_signal_dumper.h"
44

45
//#define DEBUG_ULSCH_CODING
46 47 48
//#define DEBUG_ULSCH_FREE 1

/*
49 50 51
#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)))) \
52 53 54 55 56 57
*/
#define is_not_pilot(pilots,first_pilot,re) (1)




58 59
void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch)
{
60 61 62 63 64
  int i;
  int r;

  if (ulsch) {
#ifdef DEBUG_ULSCH_FREE
65
    printf("Freeing ulsch %p\n",ulsch);
66
#endif
67

68
    for (i=0; i<8; i++) {
69
#ifdef DEBUG_ULSCH_FREE
70
      printf("Freeing ulsch process %d\n",i);
71
#endif
72

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

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

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

        for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
91 92

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

96 97 98 99 100
          if (ulsch->harq_processes[i]->c[r]) {
            free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
            ulsch->harq_processes[i]->c[r] = NULL;
          }
        }
101 102 103

        free16(ulsch->harq_processes[i],sizeof(LTE_UL_UE_HARQ_t));
        ulsch->harq_processes[i] = NULL;
104 105
      }
    }
106

107
    free16(ulsch,sizeof(LTE_UE_ULSCH_t));
108
    ulsch = NULL;
109
  }
110

111 112
}

113
LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag)
114
{
115 116 117 118

  LTE_UE_ULSCH_t *ulsch;
  unsigned char exit_flag = 0,i,j,r;
  unsigned char bw_scaling =1;
119 120 121

  switch (N_RB_UL) {
  case 6:
122 123
    bw_scaling =16;
    break;
124

125 126 127
  case 25:
    bw_scaling =4;
    break;
128 129

  case 50:
130 131
    bw_scaling =2;
    break;
132

133 134 135 136
  default:
    bw_scaling =1;
    break;
  }
137

138
  ulsch = (LTE_UE_ULSCH_t *)malloc16(sizeof(LTE_UE_ULSCH_t));
139

140
  if (ulsch) {
141
    memset(ulsch,0,sizeof(LTE_UE_ULSCH_t));
142

Bilel's avatar
Bilel committed
143 144
    ulsch->Mlimit = 4;

145
    for (i=0; i<8; i++) {
146

147
      ulsch->harq_processes[i] = (LTE_UL_UE_HARQ_t *)malloc16(sizeof(LTE_UL_UE_HARQ_t));
148

149 150
      //      printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]);
      if (ulsch->harq_processes[i]) {
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
        memset(ulsch->harq_processes[i], 0, sizeof(LTE_UL_UE_HARQ_t));
        ulsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);

        if (ulsch->harq_processes[i]->b)
          memset(ulsch->harq_processes[i]->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
        else {
          LOG_E(PHY,"Can't get b\n");
          exit_flag=1;
        }

        if (abstraction_flag==0) {
          for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
            ulsch->harq_processes[i]->c[r] = (unsigned char*)malloc16(((r==0)?8:0) + 3+768);  // account for filler in first segment and CRCs for multiple segment case

            if (ulsch->harq_processes[i]->c[r])
              memset(ulsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+768);
            else {
              LOG_E(PHY,"Can't get c\n");
              exit_flag=2;
            }
          }
        }

        ulsch->harq_processes[i]->subframe_scheduling_flag = 0;
        ulsch->harq_processes[i]->first_tx = 1;
      } else {
        LOG_E(PHY,"Can't get harq_p %d\n",i);
        exit_flag=3;
179 180 181 182
      }
    }

    if ((abstraction_flag == 0) && (exit_flag==0)) {
183
      for (i=0; i<8; i++)
184 185 186 187
        for (j=0; j<96; j++)
          for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++)
            ulsch->harq_processes[i]->d[r][j] = LTE_NULL;

188
      return(ulsch);
189
    } else if (abstraction_flag==1)
190 191
      return(ulsch);
  }
192

Cedric Roux's avatar
Cedric Roux committed
193
  LOG_E(PHY,"new_ue_ulsch exit flag, size of  %d ,   %zu\n",exit_flag, sizeof(LTE_UE_ULSCH_t));
194 195
  free_ue_ulsch(ulsch);
  return(NULL);
196 197


198 199 200
}


201
uint32_t ulsch_encoding(uint8_t *a,
202
                        PHY_VARS_UE *ue,
203 204
                        uint8_t harq_pid,
                        uint8_t eNB_id,
Bilel's avatar
Bilel committed
205
                        uint8_t subframe_rx,
206 207 208 209
                        uint8_t tmode,
                        uint8_t control_only_flag,
                        uint8_t Nbundled)
{
210

211 212 213 214 215
  time_stats_t *seg_stats=&ue->ulsch_segmentation_stats;
  time_stats_t *rm_stats=&ue->ulsch_rate_matching_stats;
  time_stats_t *te_stats=&ue->ulsch_turbo_encoding_stats;
  time_stats_t *i_stats=&ue->ulsch_interleaving_stats;
  time_stats_t *m_stats=&ue->ulsch_multiplexing_stats;
216

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
  //  uint16_t offset;
  uint32_t crc=1;
  uint16_t iind;
  uint32_t A;
  uint8_t Q_m=0;
  uint32_t Kr=0,Kr_bytes,r,r_offset=0;
  uint8_t y[6*14*1200],*yptr;;
  uint8_t *columnset;
  uint32_t sumKr=0;
  uint32_t Qprime,L,G,Q_CQI=0,Q_RI=0,Q_ACK=0,H=0,Hprime=0,Hpp=0,Cmux=0,Rmux=0,Rmux_prime=0;
  uint32_t Qprime_ACK=0,Qprime_CQI=0,Qprime_RI=0,len_ACK=0,len_RI=0;
  //  uint32_t E;
  uint8_t ack_parity;
  uint32_t i,q,j,iprime,j2;
  uint16_t o_RCC;
  uint8_t o_flip[8];
  uint32_t wACK_idx;
234 235 236
  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
  PHY_MEASUREMENTS *meas = &ue->measurements;
  LTE_UE_ULSCH_t *ulsch=ue->ulsch[eNB_id];
Bilel's avatar
Bilel committed
237
  LTE_UE_DLSCH_t **dlsch = ue->dlsch[0][eNB_id];
238
  uint16_t rnti = 0xffff;
239

240 241 242 243 244
  if (!ulsch) {
    LOG_E(PHY,"Null ulsch ptr %p\n",ulsch);
    return(-1);
  }

245
  if (harq_pid >= 8) {
246 247 248 249
    LOG_E(PHY,"Illegal harq_pid %d\n",harq_pid);
    return(-1);
  }

250 251 252 253 254 255 256
  if (ulsch->harq_processes[harq_pid]->O_ACK > 2) {
    LOG_E(PHY,"Illegal O_ACK %d\n",ulsch->harq_processes[harq_pid]->O_ACK);
    return(-1);
  }

  if (ulsch->O_RI > 1) {
    LOG_E(PHY,"Illegal O_RI %d\n",ulsch->O_RI);
257 258 259
    return(-1);
  }

gauthier's avatar
gauthier committed
260
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_IN);
261

262 263
  // fill CQI/PMI information
  if (ulsch->O>0) {
264
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_IN);
Bilel's avatar
Bilel committed
265
    rnti = ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti;
266
    fill_CQI(ulsch,meas,0,harq_pid,ue->frame_parms.N_RB_DL,rnti, tmode,ue->sinr_eff);
267

268
    LOG_D(PHY,"ULSCH Encoding rnti %x \n", rnti);
269
    print_CQI(ulsch->o,ulsch->uci_format,0,ue->frame_parms.N_RB_DL);
270 271

    // save PUSCH pmi for later (transmission modes 4,5,6)
272 273 274 275
    if (dlsch[0]) {
      //LOG_I(PHY,"XXX saving pmi for DL %x\n",pmi2hex_2Ar1(((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi));
      dlsch[0]->pmi_alloc = ((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi;
    }
276
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_OUT);
277 278 279 280 281 282
  }

  if (ulsch->O<=32) {
    o_flip[0] = ulsch->o[3];
    o_flip[1] = ulsch->o[2];
    o_flip[2] = ulsch->o[1];
283 284
    o_flip[3] = ulsch->o[0];
  } else {
285 286 287 288 289 290 291 292 293
    o_flip[0] = ulsch->o[7];
    o_flip[1] = ulsch->o[6];
    o_flip[2] = ulsch->o[5];
    o_flip[3] = ulsch->o[4];
    o_flip[4] = ulsch->o[3];
    o_flip[5] = ulsch->o[2];
    o_flip[6] = ulsch->o[1];
    o_flip[7] = ulsch->o[0];
  }
294

295 296 297 298 299
  if (control_only_flag == 0) {
    A=ulsch->harq_processes[harq_pid]->TBS;
    Q_m = get_Qm_ul(ulsch->harq_processes[harq_pid]->mcs);

    ulsch->harq_processes[harq_pid]->control_only = 0;
300

301
#ifdef DEBUG_ULSCH_CODING
302
    printf("[PHY][UE] ULSCH coding : A %d, Qm %d, mcs %d, harq_pid %d, round %d, RV %d\n",
303 304 305 306 307 308 309 310
        ulsch->harq_processes[harq_pid]->TBS,
        Q_m,
        ulsch->harq_processes[harq_pid]->mcs,
        harq_pid,
        ulsch->harq_processes[harq_pid]->round,
        ulsch->harq_processes[harq_pid]->rvidx);

    for (i=0; i<ulsch->harq_processes[harq_pid]->O_ACK; i++)
311
      printf("ulsch_coding: o_ACK[%d] %d\n",i,ulsch->o_ACK[i]);
312 313

    for (i=0; i<ulsch->O_RI; i++)
314
      printf("ulsch_coding: o_RI[%d] %d\n",i,ulsch->o_RI[i]);
315

316
    printf("ulsch_coding: O=%d\n",ulsch->O);
317 318 319

    for (i=0; i<1+((8+ulsch->O)/8); i++) {
      //    ulsch->o[i] = i;
320
      printf("ulsch_coding: O[%d] %d\n",i,ulsch->o[i]);
321 322 323
    }

    if ((tmode != 4))
324
      print_CQI(ulsch->o,wideband_cqi_rank1_2A,0,ue->frame_parms.N_RB_DL);
325
    else
326
      print_CQI(ulsch->o,HLC_subband_cqi_rank1_2A,0,ue->frame_parms.N_RB_DL);
327

328
#endif
329

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

332 333 334
      start_meas(seg_stats);
      // Add 24-bit crc (polynomial A) to payload
      crc = crc24a(a,
335 336
                   A)>>8;

337 338 339
      a[A>>3] = ((uint8_t*)&crc)[2];
      a[1+(A>>3)] = ((uint8_t*)&crc)[1];
      a[2+(A>>3)] = ((uint8_t*)&crc)[0];
340

341 342 343
      ulsch->harq_processes[harq_pid]->B = A+24;
      ulsch->harq_processes[harq_pid]->b = a;
      lte_segmentation(ulsch->harq_processes[harq_pid]->b,
344 345 346 347 348 349 350 351
                       ulsch->harq_processes[harq_pid]->c,
                       ulsch->harq_processes[harq_pid]->B,
                       &ulsch->harq_processes[harq_pid]->C,
                       &ulsch->harq_processes[harq_pid]->Cplus,
                       &ulsch->harq_processes[harq_pid]->Cminus,
                       &ulsch->harq_processes[harq_pid]->Kplus,
                       &ulsch->harq_processes[harq_pid]->Kminus,
                       &ulsch->harq_processes[harq_pid]->F);
352 353

      stop_meas(seg_stats);
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373

      for (r=0; r<ulsch->harq_processes[harq_pid]->C; r++) {
        if (r<ulsch->harq_processes[harq_pid]->Cminus)
          Kr = ulsch->harq_processes[harq_pid]->Kminus;
        else
          Kr = ulsch->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 {
          LOG_E(PHY,"ulsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
gauthier's avatar
gauthier committed
374
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
375 376 377 378
          return(-1);
        }


379
#ifdef DEBUG_ULSCH_CODING
380
        printf("Generating Code Segment %d (%d bits)\n",r,Kr);
381 382
        // generate codewords

383 384 385 386
        printf("bits_per_codeword (Kr)= %d\n",Kr);
        printf("N_RB = %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
        printf("Ncp %d\n",frame_parms->Ncp);
        printf("Qm %d\n",Q_m);
387
#endif
388 389 390 391 392

        //  offset=0;


#ifdef DEBUG_ULSCH_CODING
393
        printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]);
394
#endif
395 396 397 398 399 400 401 402 403
        start_meas(te_stats);
        threegpplte_turbo_encoder(ulsch->harq_processes[harq_pid]->c[r],
                                  Kr>>3,
                                  &ulsch->harq_processes[harq_pid]->d[r][96],
                                  (r==0) ? ulsch->harq_processes[harq_pid]->F : 0,
                                  f1f2mat_old[iind*2],   // f1 (see 36212-820, page 14)
                                  f1f2mat_old[(iind*2)+1]  // f2 (see 36212-820, page 14)
                                 );
        stop_meas(te_stats);
404
#ifdef DEBUG_ULSCH_CODING
405 406 407 408

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

409
#endif
410 411 412 413 414 415
        start_meas(i_stats);
        ulsch->harq_processes[harq_pid]->RTC[r] =
          sub_block_interleaving_turbo(4+(Kr_bytes*8),
                                       &ulsch->harq_processes[harq_pid]->d[r][96],
                                       ulsch->harq_processes[harq_pid]->w[r]);
        stop_meas(i_stats);
416
      }
417

418
    }
419

420 421
    if (ulsch->harq_processes[harq_pid]->C == 0) {
      LOG_E(PHY,"null segment\n");
gauthier's avatar
gauthier committed
422
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
423 424
      return(-1);
    }
425

426
    sumKr = 0;
427 428

    for (r=0; r<ulsch->harq_processes[harq_pid]->C; r++) {
429
      if (r<ulsch->harq_processes[harq_pid]->Cminus)
430
        Kr = ulsch->harq_processes[harq_pid]->Kminus;
431
      else
432 433
        Kr = ulsch->harq_processes[harq_pid]->Kplus;

434 435
      sumKr += Kr;
    }
436
  } else { // This is a control-only PUSCH, set sumKr to O_CQI-MIN
437 438 439
    ulsch->harq_processes[harq_pid]->control_only = 1;
    sumKr = ulsch->O_CQI_MIN;
  }
440

441 442 443 444
  ulsch->harq_processes[harq_pid]->sumKr = sumKr;
  // Compute Q_ri (p. 23 36-212)

  Qprime = ulsch->O_RI*ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_ri_times8;
445

446 447 448 449 450
  if (Qprime > 0) {
    if ((Qprime % (8*sumKr)) > 0)
      Qprime = 1+(Qprime/(8*sumKr));
    else
      Qprime = Qprime/(8*sumKr);
451

452 453 454 455 456 457 458 459 460
    if (Qprime > 4*ulsch->harq_processes[harq_pid]->nb_rb * 12)
      Qprime = 4*ulsch->harq_processes[harq_pid]->nb_rb * 12;
  }

  Q_RI = Q_m*Qprime;
  Qprime_RI = Qprime;

  // Compute Q_ack (p. 23 36-212)
  Qprime = ulsch->harq_processes[harq_pid]->O_ACK*ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_harqack_times8;
461

462 463 464 465 466
  if (Qprime > 0) {
    if ((Qprime % (8*sumKr)) > 0)
      Qprime = 1+(Qprime/(8*sumKr));
    else
      Qprime = Qprime/(8*sumKr);
467

468 469 470 471 472 473 474
    if (Qprime > 4*ulsch->harq_processes[harq_pid]->nb_rb * 12)
      Qprime = 4*ulsch->harq_processes[harq_pid]->nb_rb * 12;
  }

  Q_ACK = Qprime * Q_m;
  Qprime_ACK = Qprime;

475 476 477 478 479 480 481 482 483 484
  LOG_D(PHY,"UE (%x/%d) O_ACK %d, Mcs_initial %d, Nsymb_initial %d, beta_offset_harqack*8 %d, sum Kr %d, Qprime_ACK %d, Q_ACK %d\n",
      rnti, harq_pid,
      ulsch->harq_processes[harq_pid]->O_ACK,
      ulsch->harq_processes[harq_pid]->Msc_initial,
      ulsch->harq_processes[harq_pid]->Nsymb_initial,
      ulsch->beta_offset_harqack_times8,
      sumKr,
      Qprime_ACK,
      Q_ACK);

485 486
  // Compute Q_cqi, assume O>11, p. 26 36-212
  if (control_only_flag == 0) {
487

488 489
    if (ulsch->O < 12)
      L=0;
490
    else
491
      L=8;
492

493 494 495 496
    if (ulsch->O > 0)
      Qprime = (ulsch->O + L) * ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_cqi_times8;
    else
      Qprime = 0;
497

498 499
    if (Qprime > 0) {
      if ((Qprime % (8*sumKr)) > 0)
500
        Qprime = 1+(Qprime/(8*sumKr));
501
      else
502
        Qprime = Qprime/(8*sumKr);
503
    }
504

505 506 507 508
    G = ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);

    if (Qprime > (G - ulsch->O_RI))
      Qprime = G - ulsch->O_RI;
509

510 511 512 513
    Q_CQI = Q_m * Qprime;
    Qprime_CQI = Qprime;


514

515
    G = G - Q_RI - Q_CQI;
516 517 518
    ulsch->harq_processes[harq_pid]->G = G;

/*
519
    LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial,ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK);
520

Gabriel's avatar
Gabriel committed
521
    LOG_I(PHY,"ULSCH Encoding (Nid_cell %d, rnti %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d\n",
522 523 524 525 526 527 528 529 530
          frame_parms->Nid_cell,ulsch->rnti,
          harq_pid,
          ulsch->harq_processes[harq_pid]->round,
          ulsch->harq_processes[harq_pid]->rvidx,
          ulsch->harq_processes[harq_pid]->mcs,
          ulsch->O_RI,
          ulsch->harq_processes[harq_pid]->O_ACK,
          G);
*/
531

532 533
    if ((int)G < 0) {
      LOG_E(PHY,"FATAL: ulsch_coding.c G < 0 (%d) : Q_RI %d, Q_CQI %d, O %d, betaCQI_times8 %d)\n",G,Q_RI,Q_CQI,ulsch->O,ulsch->beta_offset_cqi_times8);
gauthier's avatar
gauthier committed
534
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
535 536 537 538 539 540 541 542 543 544 545 546 547
      return(-1);
    }


    // Data and control multiplexing (5.2.2.7 36-212)

    H = G + Q_CQI;
    Hprime = H/Q_m;



    // 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
548 549

    for (r=0; r<ulsch->harq_processes[harq_pid]->C; r++) {
550
#ifdef DEBUG_ULSCH_CODING
551
      printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
552 553 554 555
          r,
          G,
          Kr*3,
          Q_m,ulsch->harq_processes[harq_pid]->nb_rb);
556
#endif
557 558

      start_meas(rm_stats);
559
      r_offset += lte_rate_matching_turbo(ulsch->harq_processes[harq_pid]->RTC[r],
560 561 562 563 564
                                          G,
                                          ulsch->harq_processes[harq_pid]->w[r],
                                          ulsch->e+r_offset,
                                          ulsch->harq_processes[harq_pid]->C, // C
                                          NSOFT,                    // Nsoft,
565
                                          0,  // this means UL
566 567 568 569 570 571 572
                                          1,
                                          ulsch->harq_processes[harq_pid]->rvidx,
                                          get_Qm_ul(ulsch->harq_processes[harq_pid]->mcs),
                                          1,
                                          r,
                                          ulsch->harq_processes[harq_pid]->nb_rb,
                                          ulsch->harq_processes[harq_pid]->mcs);                       // r
573 574
      stop_meas(rm_stats);
#ifdef DEBUG_ULSCH_CODING
575

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

579 580
#endif
    }
581
  } else { //control-only PUSCH
582 583 584 585 586 587 588 589 590
    Q_CQI = (ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch)) - Q_RI;
    H = Q_CQI;
    Hprime = H/Q_m;
  }


  //  Do CQI coding
  if ((ulsch->O>1) && (ulsch->O < 12)) {
    LOG_E(PHY,"short CQI sizes not supported yet\n");
gauthier's avatar
gauthier committed
591
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
592
    return(-1);
593
  } else {
594 595
    // add 8-bit CRC
    crc = crc8(o_flip,
596
               ulsch->O)>>24;
597 598 599 600
#ifdef DEBUG_ULSCH_CODING
    printf("crc(cqi) tx : %x\n",crc);
#endif
    memset((void *)&ulsch->o_d[0],LTE_NULL,96);
601

602
    ccodelte_encode(ulsch->O,
603 604 605 606
                    1,
                    o_flip,
                    &ulsch->o_d[96],
                    0);
607 608


609 610 611
    o_RCC = sub_block_interleaving_cc(8+ulsch->O,
                                      &ulsch->o_d[96],
                                      ulsch->o_w);
612 613

    lte_rate_matching_cc(o_RCC,
614 615 616 617
                         Q_CQI,
                         ulsch->o_w,
                         ulsch->q);

618 619 620
  }

  i=0;
621

622 623 624 625 626 627 628 629
  //  Do RI coding
  if (ulsch->O_RI == 1) {
    switch (Q_m) {
    case 2:
      ulsch->q_RI[0] = ulsch->o_RI[0];
      ulsch->q_RI[1] = PUSCH_y;//ulsch->o_RI[0];
      len_RI=2;
      break;
630

631 632 633 634 635 636 637
    case 4:
      ulsch->q_RI[0] = ulsch->o_RI[0];
      ulsch->q_RI[1] = PUSCH_y;//1;
      ulsch->q_RI[2] = PUSCH_x;//ulsch->o_RI[0];
      ulsch->q_RI[3] = PUSCH_x;//1;
      len_RI=4;
      break;
638

639 640 641 642 643 644 645 646 647 648
    case 6:
      ulsch->q_RI[0] = ulsch->o_RI[0];
      ulsch->q_RI[1] = PUSCH_y;//1;
      ulsch->q_RI[2] = PUSCH_x;//1;
      ulsch->q_RI[3] = PUSCH_x;//ulsch->o_RI[0];
      ulsch->q_RI[4] = PUSCH_x;//1;
      ulsch->q_RI[5] = PUSCH_x;//1;
      len_RI=6;
      break;
    }
649
  } else if (ulsch->O_RI>1) {
650
    LOG_E(PHY,"RI cannot be more than 1 bit yet\n");
gauthier's avatar
gauthier committed
651
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
652 653
    return(-1);
  }
654

655 656 657
  //  Do ACK coding, Section 5.2.2.6 36.213 (p.23-24 in v8.6)
  wACK_idx = (ulsch->bundling==0) ? 4 : ((Nbundled-1)&3);
#ifdef DEBUG_ULSCH_CODING
658
  printf("ulsch_coding.c: Bundling %d, Nbundled %d, wACK_idx %d\n",
659 660
      ulsch->bundling,Nbundled,wACK_idx);
#endif
661

662 663 664 665 666 667 668 669
  // 1-bit ACK/NAK
  if (ulsch->harq_processes[harq_pid]->O_ACK == 1) {
    switch (Q_m) {
    case 2:
      ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);//ulsch->o_ACK[0];
      len_ACK = 2;
      break;
670

671 672 673 674 675 676 677
    case 4:
      ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);
      ulsch->q_ACK[2] = PUSCH_x;
      ulsch->q_ACK[3] = PUSCH_x;
      len_ACK = 4;
      break;
678

679 680 681 682 683 684 685 686 687 688 689
    case 6:
      ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);
      ulsch->q_ACK[2] = PUSCH_x;
      ulsch->q_ACK[3] = PUSCH_x;
      ulsch->q_ACK[4] = PUSCH_x;
      ulsch->q_ACK[6] = PUSCH_x;
      len_ACK = 6;
      break;
    }
  }
690

691 692 693
  // two-bit ACK/NAK
  if (ulsch->harq_processes[harq_pid]->O_ACK == 2) {
    ack_parity = (ulsch->o_ACK[0]+ulsch->o_ACK[1])&1;
694

695 696 697 698 699 700 701 702 703 704
    switch (Q_m) {
    case 2:
      ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[1] = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[2] = (ack_parity+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[3] = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
      ulsch->q_ACK[4] = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
      ulsch->q_ACK[5] = (ack_parity+wACK[wACK_idx][1])&1;
      len_ACK = 6;
      break;
705

706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
    case 4:
      ulsch->q_ACK[0]  = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[1]  = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[2]  = PUSCH_x;
      ulsch->q_ACK[3]  = PUSCH_x;//1;
      ulsch->q_ACK[4]  = (ack_parity+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[5]  = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
      ulsch->q_ACK[6]  = PUSCH_x;
      ulsch->q_ACK[7]  = PUSCH_x;//1;
      ulsch->q_ACK[8]  = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
      ulsch->q_ACK[9]  = (ack_parity+wACK[wACK_idx][1])&1;
      ulsch->q_ACK[10] = PUSCH_x;
      ulsch->q_ACK[11] = PUSCH_x;//1;
      len_ACK = 12;
      break;
721

722 723 724 725 726 727 728 729 730 731 732
    case 6:
      ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[1] = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[2] = PUSCH_x;
      ulsch->q_ACK[3] = PUSCH_x;
      ulsch->q_ACK[4] = PUSCH_x;
      ulsch->q_ACK[5] = PUSCH_x;

      ulsch->q_ACK[6] = (ack_parity+wACK[wACK_idx][0])&1;
      ulsch->q_ACK[7] = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
      ulsch->q_ACK[8] = PUSCH_x;
733
      ulsch->q_ACK[9] = PUSCH_x;
734 735 736 737 738 739 740 741 742 743 744 745 746 747
      ulsch->q_ACK[10] = PUSCH_x;
      ulsch->q_ACK[11] = PUSCH_x;

      ulsch->q_ACK[12] = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
      ulsch->q_ACK[13] = (ack_parity+wACK[wACK_idx][1])&1;
      ulsch->q_ACK[14] = PUSCH_x;
      ulsch->q_ACK[15] = PUSCH_x;
      ulsch->q_ACK[16] = PUSCH_x;
      ulsch->q_ACK[17] = PUSCH_x;
      len_ACK = 18;

      break;
    }
  }
748

749 750
  if (ulsch->harq_processes[harq_pid]->O_ACK > 2) {
    LOG_E(PHY,"ACK cannot be more than 2 bits yet\n");
gauthier's avatar
gauthier committed
751
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
752 753 754 755 756 757 758 759
    return(-1);
  }


  // channel multiplexing/interleaving

  start_meas(m_stats);
  Hpp = Hprime + Q_RI;
760

761 762 763 764 765 766 767 768 769
  Cmux       = ulsch->Nsymb_pusch;
  Rmux       = Hpp*Q_m/Cmux;
  Rmux_prime = Rmux/Q_m;

  Qprime_RI  = Q_RI / Q_m;
  Qprime_ACK = Q_ACK / Q_m;
  Qprime_CQI = Q_CQI / Q_m;

  //  printf("Qprime_CQI = %d\n",Qprime_CQI);
770
  // RI BITS
771 772 773 774 775 776 777

  memset(y,LTE_NULL,Q_m*Hpp);

  if (frame_parms->Ncp == 0)
    columnset = cs_ri_normal;
  else
    columnset = cs_ri_extended;
778 779 780 781

  j=0;

  for (i=0; i<Qprime_RI; i++) {
782
    r = Rmux_prime - 1 - (i>>2);
783 784

    for (q=0; q<Q_m; q++)  {
785 786 787
      y[q+(Q_m*((r*Cmux) + columnset[j]))]  = ulsch->q_RI[(q+(Q_m*i))%len_RI];
      //      printf("ri[%d] %d => y[%d]\n",q+(Q_m*i)%len_RI,ulsch->q_RI[(q+(Q_m*i))%len_RI],q+(Q_m*((r*Cmux) + columnset[j])),y[q+(Q_m*((r*Cmux) + columnset[j]))]);
    }
788

789 790 791 792 793 794 795 796 797 798 799
    j=(j+3)&3;

  }


  // CQI and Data bits
  j=0;
  /*
  for (i=0,iprime=-Qprime_CQI;i<Hprime;i++,iprime++) {

    while (y[Q_m*j] != LTE_NULL) j++;
800

801 802
    if (i<Qprime_CQI) {
      for (q=0;q<Q_m;q++) {
803 804
  y[q+(Q_m*j)] = ulsch->q[q+(Q_m*i)];
  //printf("cqi[%d] %d => y[%d]\n",q+(Q_m*i),ulsch->q[q+(Q_m*i)],q+(Q_m*j));
805 806 807 808
      }
    }
    else {
      for (q=0;q<Q_m;q++) {
809 810
  y[q+(Q_m*j)] = ulsch->e[q+(Q_m*iprime)];
  //  printf("e[%d] %d => y[%d]\n",q+(Q_m*iprime),ulsch->e[q+(Q_m*iprime)],q+(Q_m*j));
811 812 813 814 815 816
      }
    }
    j++;
  }
  */

817
  for (i=0; i<Qprime_CQI; i++) {
818 819 820

    while (y[Q_m*j] != LTE_NULL) j++;

821
    for (q=0; q<Q_m; q++) {
822 823 824
      y[q+(Q_m*j)] = ulsch->q[q+(Q_m*i)];
      //        printf("cqi[%d] %d => y[%d] (j %d)\n",q+(Q_m*i),ulsch->q[q+(Q_m*i)],q+(Q_m*j),j);
    }
825

826 827 828 829
    j++;
  }

  j2 = j*Q_m;
830

831 832 833 834
  switch (Q_m) {

  case 2:

835
    for (iprime=0; iprime<(Hprime-Qprime_CQI)<<1; iprime+=2) {
836
      while (y[j2] != LTE_NULL) j2+=2;
837

838 839 840 841
      y[j2]   = ulsch->e[iprime];
      y[1+j2] = ulsch->e[1+iprime];
      j2+=2;
    }
842

843 844 845
    break;

  case 4:
846
    for (iprime=0; iprime<(Hprime-Qprime_CQI)<<2; iprime+=4) {
847
      while (y[j2] != LTE_NULL) j2+=4;
848

849 850 851 852 853
      y[j2]   = ulsch->e[iprime];
      y[1+j2] = ulsch->e[1+iprime];
      y[2+j2] = ulsch->e[2+iprime];
      y[3+j2] = ulsch->e[3+iprime];
      j2+=4;
854 855
    }

856 857 858
    break;

  case 6:
859
    for (iprime=0; iprime<(Hprime-Qprime_CQI)*6; iprime+=6) {
860
      while (y[j2] != LTE_NULL) j2+=6;
861

862 863 864 865 866 867 868
      y[j2]   = ulsch->e[iprime];
      y[1+j2] = ulsch->e[1+iprime];
      y[2+j2] = ulsch->e[2+iprime];
      y[3+j2] = ulsch->e[3+iprime];
      y[4+j2] = ulsch->e[4+iprime];
      y[5+j2] = ulsch->e[5+iprime];
      j2+=6;
869 870
    }

871 872 873
    break;

  }
874

875 876 877 878 879 880 881 882
  // HARQ-ACK Bits (Note these overwrite some bits)

  if (frame_parms->Ncp == 0)
    columnset = cs_ack_normal;
  else
    columnset = cs_ack_extended;

  j=0;
883 884

  for (i=0; i<Qprime_ACK; i++) {
885
    r = Rmux_prime - 1 - (i>>2);
886 887

    for (q=0; q<Q_m; q++) {
888 889
      y[q+(Q_m*((r*Cmux) + columnset[j]))]  = ulsch->q_ACK[(q+(Q_m*i))%len_ACK];
#ifdef DEBUG_ULSCH_CODING
890
      printf("ulsch_coding.c: ACK %d => y[%d]=%d (i %d, r*Cmux %d, columnset %d)\n",q+(Q_m*i),
891 892
          q+(Q_m*((r*Cmux) + columnset[j])),ulsch->q_ACK[(q+(Q_m*i))%len_ACK],
          i,r*Cmux,columnset[j]);
893 894
#endif
    }
895

896 897 898 899 900 901
    j=(j+3)&3;

  }

  // write out buffer
  j=0;
902

903 904
  switch (Q_m) {
  case 2:
905 906 907 908 909
    for (i=0; i<Cmux; i++)
      for (r=0; r<Rmux_prime; r++) {
        yptr=&y[((r*Cmux)+i)<<1];
        ulsch->h[j++] = *yptr++;
        ulsch->h[j++] = *yptr++;
910
      }
911

912
    break;
913

914
  case 4:
915 916 917 918 919 920 921
    for (i=0; i<Cmux; i++)
      for (r=0; r<Rmux_prime; r++) {
        yptr = &y[((r*Cmux)+i)<<2];
        ulsch->h[j++] = *yptr++;
        ulsch->h[j++] = *yptr++;
        ulsch->h[j++] = *yptr++;
        ulsch->h[j++] = *yptr++;
922
      }
923

924
    break;
925

926
  case 6:
927 928 929 930 931 932 933 934 935
    for (i=0; i<Cmux; i++)
      for (r=0; r<Rmux_prime; r++) {
        yptr = &y[((r*Cmux)+i)*6];
        ulsch->h[j++] = *yptr++;
        ulsch->h[j++] = *yptr++;
        ulsch->h[j++] = *yptr++;
        ulsch->h[j++] = *yptr++;
        ulsch->h[j++] = *yptr++;
        ulsch->h[j++] = *yptr++;
936
      }
937

938
    break;
939

940 941 942
  default:
    break;
  }
943

944 945 946
  stop_meas(m_stats);

  if (j!=(H+Q_RI)) {
947
    LOG_E(PHY,"Error in output buffer length (j %d, H+Q_RI %d)\n",j,H+Q_RI);
gauthier's avatar
gauthier committed
948
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
949 950 951
    return(-1);
  }

gauthier's avatar
gauthier committed
952
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
953 954 955 956 957 958 959 960 961
  return(0);
}


#ifdef PHY_ABSTRACTION
#ifdef OPENAIR2
#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/defs.h"
#endif
962
int ulsch_encoding_emul(uint8_t *ulsch_buffer,
963
                        PHY_VARS_UE *ue,
964
                        uint8_t eNB_id,
Bilel's avatar
Bilel committed
965
                        uint8_t subframe_rx,
966 967 968
                        uint8_t harq_pid,
                        uint8_t control_only_flag)
{
969

970
  LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id];
Bilel's avatar
Bilel committed
971
  LTE_UE_DLSCH_t **dlsch = ue->dlsch[0][eNB_id];
972 973
  PHY_MEASUREMENTS *meas = &ue->measurements;
  uint8_t tmode = ue->transmission_mode[eNB_id];
Bilel's avatar
Bilel committed
974
  uint16_t rnti=ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti;
975
  LOG_D(PHY,"EMUL UE ulsch_encoding for eNB %d,mod_id %d, harq_pid %d rnti %x, ACK(%d,%d) \n",
976
        eNB_id,ue->Mod_id, harq_pid, rnti,ulsch->o_ACK[0],ulsch->o_ACK[1]);
977 978

  if (ulsch->O>0) {
979 980
    /*
    if(flag_LA==1)
981
      sinr_eff = sinr_eff_cqi_calc(ue, eNB_id);
982 983 984
    else
      sinr_eff = meas->wideband_cqi_avg[eNB_id];
    */
985

986
    fill_CQI(ulsch,meas,eNB_id,harq_pid,ue->frame_parms.N_RB_DL,rnti,tmode,ue->sinr_eff);
987
    //LOG_D(PHY,"UE CQI\n");
988 989 990
    //    print_CQI(ulsch->o,ulsch->uci_format,eNB_id);

    // save PUSCH pmi for later (transmission modes 4,5,6)
991
    //    printf("ulsch: saving pmi for DL %x\n",pmi2hex_2Ar1(((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi));
992 993 994 995
    // if (ulsch->uci_format != HLC_subband_cqi_mcs_CBA)
    dlsch[0]->harq_processes[harq_pid]->pmi_alloc = ((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi;
  }

996
  memcpy(ue->ulsch[eNB_id]->harq_processes[harq_pid]->b,
997
         ulsch_buffer,
998
         ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3);
999

1000

1001 1002
  //memcpy(&UE_transport_info[ue->Mod_id].transport_blocks[UE_transport_info_TB_index[ue->Mod_id]],
  memcpy(&UE_transport_info[ue->Mod_id][ue->CC_id].transport_blocks,
1003
         ulsch_buffer,
1004 1005
         ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3);
  //UE_transport_info_TB_index[ue->Mod_id]+=ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3;
1006
  // navid: currently more than one eNB is not supported in the code
1007
  UE_transport_info[ue->Mod_id][ue->CC_id].num_eNB = 1;
Bilel's avatar
Bilel committed
1008
  UE_transport_info[ue->Mod_id][ue->CC_id].rnti[0] = ue->pdcch_vars[subframe_rx%RX_NB_TH][0]->crnti;
1009 1010 1011
  UE_transport_info[ue->Mod_id][ue->CC_id].eNB_id[0]  = eNB_id;
  UE_transport_info[ue->Mod_id][ue->CC_id].harq_pid[0] = harq_pid;
  UE_transport_info[ue->Mod_id][ue->CC_id].tbs[0]     = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3 ;
1012
  // printf("\nue->Mod_id%d\n",ue->Mod_id);
1013 1014 1015 1016

  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pusch_flag = 1;
  //UE_transport_info[ue->Mod_id].cntl.pusch_uci = *(uint32_t *)ulsch->o;
  memcpy(UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pusch_uci,
1017 1018
         ulsch->o,
         MAX_CQI_BYTES);
1019
  // printf("[UE]cqi is %d \n", ((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1);
1020

1021 1022 1023 1024
  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.length_uci = ulsch->O;
  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.uci_format = ulsch->uci_format;
  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pusch_ri = (ulsch->o_RI[0]&1)+((ulsch->o_RI[1]&1)<<1);
  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pusch_ack =   (ulsch->o_ACK[0]&1) + ((ulsch->o_ACK[1]&1)<<1);
1025
  //printf("ack is %d %d %d\n",UE_transport_info[ue->Mod_id].cntl.pusch_ack, (ulsch->o_ACK[1]&1)<<1, ulsch->o_ACK[0]&1);
1026
  return(0);
1027

1028 1029
}
#endif