nr_dlsch_decoding.c 56.4 KB
Newer Older
Hongzhi Wang's avatar
Hongzhi Wang committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
/*
 * 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
 */

/*! \file PHY/NR_UE_TRANSPORT/nr_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
*/

33
#include "common/utils/LOG/vcd_signal_dumper.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
34 35 36 37 38
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/CODING/coding_extern.h"
#include "PHY/CODING/coding_defs.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
39
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
40
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
41
#include "SCHED_NR_UE/defs.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
42
#include "SIMULATION/TOOLS/sim.h"
laurent's avatar
laurent committed
43
#include "executables/nr-uesoftmodem.h"
44
#include "PHY/CODING/nrLDPC_extern.h"
cig's avatar
cig committed
45
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
46
//#define DEBUG_DLSCH_DECODING
47
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
Hongzhi Wang's avatar
Hongzhi Wang committed
48

49
//#define OAI_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX
Hongzhi Wang's avatar
Hongzhi Wang committed
50 51 52 53

static uint64_t nb_total_decod =0;
static uint64_t nb_error_decod =0;

Hongzhi Wang's avatar
Hongzhi Wang committed
54 55 56
notifiedFIFO_t freeBlocks_dl;
notifiedFIFO_elt_t *msgToPush_dl;
int nbDlProcessing =0;
57

Hongzhi Wang's avatar
Hongzhi Wang committed
58 59
//extern double cpuf;

60
void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
Hongzhi Wang's avatar
Hongzhi Wang committed
61 62 63
{

  int i,r;
64
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
65
  NR_UE_DLSCH_t *dlsch=*dlschptr;
Hongzhi Wang's avatar
Hongzhi Wang committed
66 67

  if (dlsch) {
68 69 70 71 72 73
    if (N_RB_DL != 273) {
      a_segments = a_segments*N_RB_DL;
      a_segments = a_segments/273;
    }  
 

Hongzhi Wang's avatar
Hongzhi Wang committed
74 75 76
    for (i=0; i<dlsch->Mdlharq; i++) {
      if (dlsch->harq_processes[i]) {
        if (dlsch->harq_processes[i]->b) {
laurent's avatar
laurent committed
77
          free16(dlsch->harq_processes[i]->b,a_segments*1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
78 79 80
          dlsch->harq_processes[i]->b = NULL;
        }

81
        for (r=0; r<a_segments; r++) {
82
          free16(dlsch->harq_processes[i]->c[r],1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
83 84 85
          dlsch->harq_processes[i]->c[r] = NULL;
        }

86
        for (r=0; r<a_segments; r++)
Hongzhi Wang's avatar
Hongzhi Wang committed
87
          if (dlsch->harq_processes[i]->d[r]) {
88
            free16(dlsch->harq_processes[i]->d[r],(5*8448)*sizeof(short));
Hongzhi Wang's avatar
Hongzhi Wang committed
89 90
            dlsch->harq_processes[i]->d[r] = NULL;
          }
91
        
92 93
        for (r=0; r<a_segments; r++)
          if (dlsch->harq_processes[i]->w[r]) {
94
            free16(dlsch->harq_processes[i]->w[r],(5*8448)*sizeof(short));
95 96 97
            dlsch->harq_processes[i]->w[r] = NULL;
          }

98
        for (r=0; r<a_segments; r++) {
Ahmed's avatar
Ahmed committed
99 100 101 102 103
          if (dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]){
            nrLDPC_free_mem(dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
            dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
          }
        }
Hongzhi Wang's avatar
Hongzhi Wang committed
104 105 106 107 108

        free16(dlsch->harq_processes[i],sizeof(NR_DL_UE_HARQ_t));
        dlsch->harq_processes[i] = NULL;
      }
    }
109
      
Hongzhi Wang's avatar
Hongzhi Wang committed
110 111 112 113 114
    free16(dlsch,sizeof(NR_UE_DLSCH_t));
    dlsch = NULL;
  }
}

115
NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_ldpc_iterations,uint16_t N_RB_DL, uint8_t abstraction_flag)
Hongzhi Wang's avatar
Hongzhi Wang committed
116 117 118 119 120
{

  NR_UE_DLSCH_t *dlsch;
  uint8_t exit_flag = 0,i,r;

121
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
122

Francesco Mani's avatar
Francesco Mani committed
123 124
  if (N_RB_DL != 273) {
    a_segments = a_segments*N_RB_DL;
125
    a_segments = (a_segments/273)+1;
126
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
127

128
  uint16_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
Hongzhi Wang's avatar
Hongzhi Wang committed
129 130 131 132 133 134 135 136

  dlsch = (NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));

  if (dlsch) {
    memset(dlsch,0,sizeof(NR_UE_DLSCH_t));
    dlsch->Kmimo = Kmimo;
    dlsch->Mdlharq = Mdlharq;
    dlsch->Nsoft = Nsoft;
137
    dlsch->Mlimit = 4;
Hongzhi Wang's avatar
Hongzhi Wang committed
138
    dlsch->max_ldpc_iterations = max_ldpc_iterations;
139
 
Hongzhi Wang's avatar
Hongzhi Wang committed
140 141 142 143 144 145 146
    for (i=0; i<Mdlharq; i++) {
      //      printf("new_ue_dlsch: Harq process %d\n",i);
      dlsch->harq_processes[i] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t));

      if (dlsch->harq_processes[i]) {
        memset(dlsch->harq_processes[i],0,sizeof(NR_DL_UE_HARQ_t));
        dlsch->harq_processes[i]->first_tx=1;
147
        dlsch->harq_processes[i]->b = (uint8_t*)malloc16(dlsch_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
148 149

        if (dlsch->harq_processes[i]->b)
150
          memset(dlsch->harq_processes[i]->b,0,dlsch_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
151 152 153 154
        else
          exit_flag=3;

        if (abstraction_flag == 0) {
155
          for (r=0; r<a_segments; r++) { 
Ahmed's avatar
Ahmed committed
156
            dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
Hongzhi Wang's avatar
Hongzhi Wang committed
157
            dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
158 159

            if (dlsch->harq_processes[i]->c[r])
Hongzhi Wang's avatar
Hongzhi Wang committed
160
              memset(dlsch->harq_processes[i]->c[r],0,1056);
Hongzhi Wang's avatar
Hongzhi Wang committed
161 162 163
            else
              exit_flag=2;

164
            dlsch->harq_processes[i]->d[r] = (short*)malloc16((5*8448)*sizeof(short));
Hongzhi Wang's avatar
Hongzhi Wang committed
165 166

            if (dlsch->harq_processes[i]->d[r])
167
              memset(dlsch->harq_processes[i]->d[r],0,(5*8448)*sizeof(short));
Hongzhi Wang's avatar
Hongzhi Wang committed
168 169
            else
              exit_flag=2;
170

171
            dlsch->harq_processes[i]->w[r] = (short*)malloc16((5*8448)*sizeof(short));
172 173

            if (dlsch->harq_processes[i]->w[r])
174
              memset(dlsch->harq_processes[i]->w[r],0,(5*8448)*sizeof(short));
175 176
            else
              exit_flag=2;
Hongzhi Wang's avatar
Hongzhi Wang committed
177 178 179 180 181 182 183 184 185 186 187 188
          }
        }
      } else {
        exit_flag=1;
      }
    }

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

  printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
189
  free_nr_ue_dlsch(&dlsch,N_RB_DL);
Hongzhi Wang's avatar
Hongzhi Wang committed
190 191 192 193

  return(NULL);
}

Hongzhi Wang's avatar
Hongzhi Wang committed
194
void nr_dlsch_unscrambling(int16_t* llr,
hongzhi wang's avatar
hongzhi wang committed
195
                         uint32_t size,
Hongzhi Wang's avatar
Hongzhi Wang committed
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
                         uint8_t q,
                         uint32_t Nid,
                         uint32_t n_RNTI) {

  uint8_t reset;
  uint32_t x1, x2, s=0;

  reset = 1;
  x2 = (n_RNTI<<15) + (q<<14) + Nid;

  for (int i=0; i<size; i++) {
    if ((i&0x1f)==0) {
      s = lte_gold_generic(&x1, &x2, reset);
      reset = 0;
    }
    if (((s>>(i&0x1f))&1)==1)
Ahmed's avatar
Ahmed committed
212
      llr[i] = -llr[i];
Hongzhi Wang's avatar
Hongzhi Wang committed
213 214 215 216
  }

}

217
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
218 219 220 221 222 223 224 225 226 227
			   short *dlsch_llr,
			   NR_DL_FRAME_PARMS *frame_parms,
			   NR_UE_DLSCH_t *dlsch,
			   NR_DL_UE_HARQ_t *harq_process,
			   uint32_t frame,
			   uint16_t nb_symb_sch,
			   uint8_t nr_tti_rx,
			   uint8_t harq_pid,
			   uint8_t is_crnti,
			   uint8_t llr8_flag)
Hongzhi Wang's avatar
Hongzhi Wang committed
228 229 230 231 232 233 234 235 236 237
{

#if UE_TIMING_TRACE
  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;
#endif
  uint32_t A,E;
  uint32_t G;
  uint32_t ret,offset;
238
  int32_t no_iteration_ldpc, length_dec;
239
  uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
Hongzhi Wang's avatar
Hongzhi Wang committed
240
  uint8_t crc_type;
241
  int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
Hongzhi Wang's avatar
Hongzhi Wang committed
242 243 244 245
  t_nrLDPC_dec_params decParams;
  t_nrLDPC_dec_params* p_decParams = &decParams;
  t_nrLDPC_time_stats procTime;
  t_nrLDPC_time_stats* p_procTime =&procTime ;
246 247 248 249 250
  
  if (!harq_process) {
    printf("dlsch_decoding.c: NULL harq_process pointer\n");
    return(dlsch->max_ldpc_iterations + 1);
  }
251
  t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
252

253
    
Hongzhi Wang's avatar
Hongzhi Wang committed
254 255 256
  int16_t z [68*384];
  int8_t l [68*384];
  //__m128i l;
257
  //int16_t inv_d [68*384];
258
  uint8_t kc;
Hongzhi Wang's avatar
Hongzhi Wang committed
259
  uint8_t Ilbrm = 0;
260 261 262 263

  uint32_t Tbslbrm;// = 950984;
  uint16_t nb_rb;// = 30;
  double Coderate;// = 0.0;
264

265
  uint8_t dmrs_Type = harq_process->dmrsConfigType;
266
  AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type);
267
  uint8_t nb_re_dmrs = 12;//(dmrs_Type==1)?6:4;
268
  uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
Raymond Knopp's avatar
Raymond Knopp committed
269
  AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length);
Hongzhi Wang's avatar
Hongzhi Wang committed
270 271 272 273 274

  uint32_t i,j;

  __m128i *pv = (__m128i*)&z;
  __m128i *pl = (__m128i*)&l;
Hongzhi Wang's avatar
Hongzhi Wang committed
275 276
  
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
Hongzhi Wang's avatar
Hongzhi Wang committed
277

278 279
  //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0];

Ahmed's avatar
Ahmed committed
280
  if (!dlsch_llr) {
Hongzhi Wang's avatar
Hongzhi Wang committed
281
    printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
282
    return(dlsch->max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
283 284 285 286
  }

  if (!frame_parms) {
    printf("dlsch_decoding.c: NULL frame_parms pointer\n");
287
    return(dlsch->max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
288 289
  }

290
  /*if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) {
Hongzhi Wang's avatar
Hongzhi Wang committed
291
    printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx);
292
    return(dlsch->max_ldpc_iterations + 1);
293
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
294

295
  /*if (harq_process->harq_ack.ack != 2) {
Hongzhi Wang's avatar
Hongzhi Wang committed
296 297
    LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
        phy_vars_ue->Mod_id, nr_tti_rx, harq_process->harq_ack.ack);
298
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
299 300 301 302 303 304

  //  nb_rb = dlsch->nb_rb;

  /*
  if (nb_rb > frame_parms->N_RB_DL) {
    printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
305
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
306 307 308 309 310
    }*/

  /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]];
  if (harq_pid >= 8) {
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
311
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
312 313 314
  }
  */

315 316
  nb_rb = harq_process->nb_rb;

Hongzhi Wang's avatar
Hongzhi Wang committed
317 318
  harq_process->trials[harq_process->round]++;

319 320
  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs

321
  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, 0, harq_process->Nl);
322

Hongzhi Wang's avatar
Hongzhi Wang committed
323
  A = harq_process->TBS;
324
  ret = dlsch->max_ldpc_iterations + 1;
325
  dlsch->last_iteration_cnt = ret;
326
 
Raymond Knopp's avatar
Raymond Knopp committed
327
  harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, harq_process->Qm,harq_process->Nl);
Hongzhi Wang's avatar
Hongzhi Wang committed
328 329
  G = harq_process->G;

330
  LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,A/8,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
Hongzhi Wang's avatar
Hongzhi Wang committed
331

Francesco Mani's avatar
Francesco Mani committed
332
  if ((harq_process->R)<1024)
333 334 335
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
336

Ahmed's avatar
Ahmed committed
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
  if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
  {
    p_decParams->BG = 2;
    if (Coderate < 0.3333){
      p_decParams->R = 15;
      kc = 52;
    }
    else if (Coderate <0.6667){
      p_decParams->R = 13;
      kc = 32;
    }
    else {
      p_decParams->R = 23;
      kc = 17;
    }
  }
  else{
    p_decParams->BG = 1;
    if (Coderate < 0.6667){
      p_decParams->R = 13;
      kc = 68;
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
      kc = 35;
    }
    else {
      p_decParams->R = 89;
      kc = 27;
    }
  }

369 370 371

  if (harq_process->round == 0) {
    // This is a new packet, so compute quantities regarding segmentation
372 373 374 375 376
	if (A > 3824)
	  harq_process->B = A+24;
	else
	  harq_process->B = A+16;

377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
    nr_segmentation(NULL,
                    NULL,
                    harq_process->B,
                    &harq_process->C,
                    &harq_process->K,
                    &harq_process->Z, // [hna] Z is Zc
                    &harq_process->F,
                    p_decParams->BG);

#ifdef DEBUG_DLSCH_DECODING
    if (!frame%100)
      printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
#endif
  }

Hongzhi Wang's avatar
Hongzhi Wang committed
392
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
393 394 395 396

  p_decParams->Z = harq_process->Z;
  //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z);

Ahmed's avatar
Ahmed committed
397 398 399 400
  //printf("coderate %f kc %d \n", Coderate, kc);

  p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
  p_decParams->outMode= 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
401 402 403 404

  err_flag = 0;
  r_offset = 0;

405
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
406

Francesco Mani's avatar
Francesco Mani committed
407 408
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
cig's avatar
cig committed
409
    a_segments = (a_segments + 272) / 273;
410
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
411

412 413
  if (harq_process->C > a_segments) {
    LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
Hongzhi Wang's avatar
Hongzhi Wang committed
414 415
    return((1+dlsch->max_ldpc_iterations));
  }
Ahmed's avatar
Ahmed committed
416

Hongzhi Wang's avatar
Hongzhi Wang committed
417
#ifdef DEBUG_DLSCH_DECODING
418
  printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
Hongzhi Wang's avatar
Hongzhi Wang committed
419 420 421 422
#endif

  opp_enabled=1;

Ahmed's avatar
Ahmed committed
423
  Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb"
Hongzhi Wang's avatar
Hongzhi Wang committed
424 425
  Kr_bytes = Kr>>3;

Hongzhi Wang's avatar
Hongzhi Wang committed
426 427
  K_bytes_F = Kr_bytes-(harq_process->F>>3);

Hongzhi Wang's avatar
Hongzhi Wang committed
428 429
  for (r=0; r<harq_process->C; r++) {

430
    //printf("start rx segment %d\n",r);
431 432 433 434 435
    E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);

#if UE_TIMING_TRACE
    start_meas(dlsch_deinterleaving_stats);
#endif
436

Hongzhi Wang's avatar
Hongzhi Wang committed
437
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN);
438

439

440 441
    nr_deinterleaving_ldpc(E,
                           harq_process->Qm,
Ahmed's avatar
Ahmed committed
442
                           harq_process->w[r], // [hna] w is e
443 444
                           dlsch_llr+r_offset);

Hongzhi Wang's avatar
Hongzhi Wang committed
445
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
446

447
    //for (int i =0; i<16; i++)
Ahmed's avatar
Ahmed committed
448
    //          printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
449 450 451 452

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif
453

Hongzhi Wang's avatar
Hongzhi Wang committed
454 455 456 457
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif

458 459
    LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,E %d, F %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
          harq_pid,r, G,E,harq_process->F,
Hongzhi Wang's avatar
Hongzhi Wang committed
460 461 462 463 464 465 466
          Kr*3,
          harq_process->TBS,
          harq_process->Qm,
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
467

Hongzhi Wang's avatar
Hongzhi Wang committed
468

Hongzhi Wang's avatar
Hongzhi Wang committed
469
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
470

471 472 473 474 475
    if ((harq_process->Nl)<4)
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
    else
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);

476

Hongzhi Wang's avatar
Hongzhi Wang committed
477
    if (nr_rate_matching_ldpc_rx(Ilbrm,
478 479 480 481 482 483 484 485
                                 Tbslbrm,
                                 p_decParams->BG,
                                 p_decParams->Z,
                                 harq_process->d[r],
                                 harq_process->w[r],
                                 harq_process->C,
                                 harq_process->rvidx,
                                 (harq_process->round==0)?1:0,
486
                                 E,
cig's avatar
cig committed
487 488
                                 harq_process->F,
                                 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
489
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
490 491 492 493
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
494
      return(dlsch->max_ldpc_iterations + 1);
Ahmed's avatar
Ahmed committed
495
    } else {
496

Hongzhi Wang's avatar
Hongzhi Wang committed
497 498 499 500 501
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
    }

502

503
    //for (int i =0; i<16; i++)
Ahmed's avatar
Ahmed committed
504
    //      printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
Hongzhi Wang's avatar
Hongzhi Wang committed
505

506
    r_offset += E;
507

Hongzhi Wang's avatar
Hongzhi Wang committed
508 509
#ifdef DEBUG_DLSCH_DECODING
    if (r==0) {
Ahmed's avatar
Ahmed committed
510
      write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
511
      write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0);
Hongzhi Wang's avatar
Hongzhi Wang committed
512 513
    }

514
    printf("decoder input(segment %u) :",r);
Ahmed's avatar
Ahmed committed
515
    int i;
516
    for (i=0;i<E;i++)
Hongzhi Wang's avatar
Hongzhi Wang committed
517
      printf("%d : %d\n",i,harq_process->d[r][i]);
Ahmed's avatar
Ahmed committed
518
    printf("\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
519 520 521 522 523 524
#endif

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

    //    printf("done\n");
525
    if (harq_process->C == 1){
526 527 528 529 530 531 532
    	if (A > 3824) 
    		crc_type = CRC24_A;
    	else
    		crc_type = CRC16;
    	
	length_dec = harq_process->B;

533 534
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
535
      crc_type = CRC24_B;
536 537
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
538 539 540 541

    if (err_flag == 0) {

#if UE_TIMING_TRACE
Ahmed's avatar
Ahmed committed
542
      start_meas(dlsch_turbo_decoding_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
543 544
#endif

545
      //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A);
Hongzhi Wang's avatar
Hongzhi Wang committed
546

547
      //printf("harq process dr iteration %d\n", p_decParams->numMaxIter);
Hongzhi Wang's avatar
Hongzhi Wang committed
548

Ahmed's avatar
Ahmed committed
549 550 551
      memset(pv,0,2*harq_process->Z*sizeof(int16_t));
      //memset(pl,0,2*p_decParams->Z*sizeof(int8_t));
      memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
Hongzhi Wang's avatar
Hongzhi Wang committed
552

553

Ahmed's avatar
Ahmed committed
554 555 556 557
      for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++)
      {
        pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
      }
558 559 560 561
      // Kbytes_F = Kr_bytes - F>>3
      j+=(harq_process->F>>3);
      //      for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
      for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++,j++)
Ahmed's avatar
Ahmed committed
562 563 564 565 566 567 568 569 570
      {
        pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
      }

      for (i=0, j=0; j < ((kc*p_decParams->Z)>>4);  i+=2, j++)
      {
        pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
      }

cig's avatar
cig committed
571

Hongzhi Wang's avatar
Hongzhi Wang committed
572
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
573

Ahmed's avatar
Ahmed committed
574 575 576
      no_iteration_ldpc = nrLDPC_decoder(p_decParams,
                           (int8_t*)&pl[0],
                           llrProcBuf,
577
                           p_nrLDPC_procBuf[r],
578
                           p_procTime);
Hongzhi Wang's avatar
Hongzhi Wang committed
579
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
580

Ahmed's avatar
Ahmed committed
581 582
      // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
      if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
583
        LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
584 585
        //Temporary hack
        no_iteration_ldpc = dlsch->max_ldpc_iterations;
586
        ret = no_iteration_ldpc;
Ahmed's avatar
Ahmed committed
587 588
      }
      else {
589
        LOG_D(PHY,"CRC NOK\n\033[0m");
590
        ret = 1 + dlsch->max_ldpc_iterations;
Ahmed's avatar
Ahmed committed
591 592
      }

593

Ahmed's avatar
Ahmed committed
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608
      nb_total_decod++;
      if (no_iteration_ldpc > dlsch->max_ldpc_iterations){
        nb_error_decod++;
      }

      //if (!nb_total_decod%10000){
      //printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout);
      //}
      //else
      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);

      for (int m=0; m < Kr>>3; m ++)
      {
        harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
609

610
#ifdef DEBUG_DLSCH_DECODING
hongzhi wang's avatar
hongzhi wang committed
611
      //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
Guy De Souza's avatar
Guy De Souza committed
612
      for (int k=0;k<A>>3;k++)
Ahmed's avatar
Ahmed committed
613
        printf("output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
614
      printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
615
      //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
616
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
617 618 619 620 621 622


#if UE_TIMING_TRACE
      stop_meas(dlsch_turbo_decoding_stats);
#endif
    }
623 624
    
    
Hongzhi Wang's avatar
Hongzhi Wang committed
625 626 627 628 629 630 631 632 633 634

    /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f  dlsch_turbo_decoding_stats %5.3f \n",
                  harq_process->C,
                  r,
                  dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
                  dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
                  dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/


    if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
635
      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
Hongzhi Wang's avatar
Hongzhi Wang committed
636 637 638 639 640 641 642 643 644 645 646 647 648
      err_flag = 1;
    }
  }

  int32_t frame_rx_prev = frame;
  int32_t tti_rx_prev = nr_tti_rx - 1;
  if (tti_rx_prev < 0) {
    frame_rx_prev--;
    tti_rx_prev += 10*frame_parms->ttis_per_subframe;
  }
  frame_rx_prev = frame_rx_prev%1024;

  if (err_flag == 1) {
649
//#if UE_DEBUG_TRACE
650
    LOG_D(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",
Hongzhi Wang's avatar
Hongzhi Wang committed
651
        phy_vars_ue->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
652
//#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
653 654 655 656
    harq_process->harq_ack.ack = 0;
    harq_process->harq_ack.harq_id = harq_pid;
    harq_process->harq_ack.send_harq_status = 1;
    harq_process->errors[harq_process->round]++;
657
    // harq_process->round++; // [hna] uncomment this line when HARQ is implemented
Hongzhi Wang's avatar
Hongzhi Wang committed
658 659

    //    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);
660
    if (harq_process->round >= dlsch->Mlimit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
661 662 663
      harq_process->status = SCH_IDLE;
      harq_process->round  = 0;
    }
664

Hongzhi Wang's avatar
Hongzhi Wang committed
665 666
    if(is_crnti)
    {
667
    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
Hongzhi Wang's avatar
Hongzhi Wang committed
668 669 670
               phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
    }

671
    return((1 + dlsch->max_ldpc_iterations));
Hongzhi Wang's avatar
Hongzhi Wang committed
672
  } else {
673
//#if UE_DEBUG_TRACE
674
    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
675
	  phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
676
//#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
677 678 679 680 681 682

    harq_process->status = SCH_IDLE;
    harq_process->round  = 0;
    harq_process->harq_ack.ack = 1;
    harq_process->harq_ack.harq_id = harq_pid;
    harq_process->harq_ack.send_harq_status = 1;
683
    
684
    //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
Hongzhi Wang's avatar
Hongzhi Wang committed
685 686 687 688
      //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);

    if(is_crnti)
    {
689
    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
Hongzhi Wang's avatar
Hongzhi Wang committed
690 691 692 693 694 695 696
    }
    //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);

  }

  // Reassembly of Transport block here
  offset = 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
697 698
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
Hongzhi Wang's avatar
Hongzhi Wang committed
699 700 701 702 703 704

  /*
  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);
  */
705

Hongzhi Wang's avatar
Hongzhi Wang committed
706
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN);
707

Hongzhi Wang's avatar
Hongzhi Wang committed
708 709
  for (r=0; r<harq_process->C; r++) {

Hongzhi Wang's avatar
Hongzhi Wang committed
710
    memcpy(harq_process->b+offset,
711 712
	   harq_process->c[r],
	   Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
Hongzhi Wang's avatar
Hongzhi Wang committed
713 714 715
    offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));

#ifdef DEBUG_DLSCH_DECODING
716
    printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
717 718 719 720 721 722
    printf("copied %d bytes to b sequence (harq_pid %d)\n",
              (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
              printf("b[0] = %x,c[%d] = %x\n",
              harq_process->b[offset],
              harq_process->F>>3,
              harq_process->c[r]);
723 724 725 726 727

              /*printf ("Printing payload bytes:");
                for (int i = 0; i < Kr_bytes; i++){
                printf("%d : %d \n", i, harq_process->b[i]);
                }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
728
#endif
729 730

#if defined(ENABLE_PHY_PAYLOAD_DEBUG)
731
           if (frame%100 == 0){
732
              LOG_I (PHY, "Printing 10 first payload bytes at frame: %d ", frame);
733
              for (int i = 0; i <10 ; i++){ //Kr_bytes
734
            	  LOG_I(PHY, "[%d] : %x ", i, harq_process->b[i]);
735 736
              }
          }
Hongzhi Wang's avatar
Hongzhi Wang committed
737 738
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
739 740
  }

Hongzhi Wang's avatar
Hongzhi Wang committed
741
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT);
742

Hongzhi Wang's avatar
Hongzhi Wang committed
743 744 745 746 747 748
  dlsch->last_iteration_cnt = ret;

  return(ret);
}

#ifdef UE_DLSCH_PARALLELISATION
749
uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
Ahmed's avatar
Ahmed committed
750 751 752 753 754 755 756 757 758 759 760 761
                                    UE_nr_rxtx_proc_t *proc,
                                    int eNB_id,
                                    short *dlsch_llr,
                                    NR_DL_FRAME_PARMS *frame_parms,
                                    NR_UE_DLSCH_t *dlsch,
                                    NR_DL_UE_HARQ_t *harq_process,
                                    uint32_t frame,
                                    uint16_t nb_symb_sch,
                                    uint8_t nr_tti_rx,
                                    uint8_t harq_pid,
                                    uint8_t is_crnti,
                                    uint8_t llr8_flag)
Hongzhi Wang's avatar
Hongzhi Wang committed
762 763 764 765 766 767 768 769 770 771
{

#if UE_TIMING_TRACE
  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;
#endif
  uint32_t A,E;
  uint32_t G;
  uint32_t ret,offset;
772
  uint32_t r,r_offset=0,Kr=8424,Kr_bytes,err_flag=0,K_bytes_F;
Hongzhi Wang's avatar
Hongzhi Wang committed
773 774
  uint8_t crc_type;
  //UE_rxtx_proc_t *proc = &phy_vars_ue->proc;
775
  int32_t no_iteration_ldpc,length_dec;
Hongzhi Wang's avatar
Hongzhi Wang committed
776 777 778 779 780
  /*uint8_t C;
  uint8_t Qm;
  uint8_t r_thread;
  uint32_t Er, Gp,GpmodC;*/
  t_nrLDPC_dec_params decParams;
781 782 783
  t_nrLDPC_dec_params* p_decParams = &decParams;
  t_nrLDPC_time_stats procTime;
  t_nrLDPC_time_stats* p_procTime =&procTime ;
784
  int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
785 786 787 788
    if (!harq_process) {
    printf("dlsch_decoding.c: NULL harq_process pointer\n");
    return(dlsch->max_ldpc_iterations);
  }
789
  t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0];
790
  uint8_t Nl=4;
791 792 793
  int16_t z [68*384];
  int8_t l [68*384];
  //__m128i l;
Hongzhi Wang's avatar
Hongzhi Wang committed
794
  //int16_t inv_d [68*384];
795 796
  //int16_t *p_invd =&inv_d;
  uint8_t kb, kc;
797
  uint8_t Ilbrm = 1;
798
  uint32_t Tbslbrm = 950984;
799 800
  uint16_t nb_rb = 30;
  double Coderate = 0.0;
Hongzhi Wang's avatar
Hongzhi Wang committed
801
  uint8_t dmrs_type = harq_process->dmrsConfigType;
cig's avatar
cig committed
802 803 804
  //nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config;
  //uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;

805
  uint8_t nb_re_dmrs = 12;//(dmrs_type==1)?6:4;
Raymond Knopp's avatar
Raymond Knopp committed
806
  uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos); 
Hongzhi Wang's avatar
Hongzhi Wang committed
807

808
  uint32_t i,j;
Hongzhi Wang's avatar
Hongzhi Wang committed
809
//  int nbDlProcessing =0;
Hongzhi Wang's avatar
Hongzhi Wang committed
810

811 812 813 814
  __m128i *pv = (__m128i*)&z;
  __m128i *pl = (__m128i*)&l;
  notifiedFIFO_t nf;
  initNotifiedFIFO(&nf);
Hongzhi Wang's avatar
Hongzhi Wang committed
815

Hongzhi Wang's avatar
Hongzhi Wang committed
816
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
Hongzhi Wang's avatar
Hongzhi Wang committed
817 818 819 820 821 822

  if (!dlsch_llr) {
    printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
    return(dlsch->max_ldpc_iterations);
  }

823

Hongzhi Wang's avatar
Hongzhi Wang committed
824 825 826 827 828 829

  if (!frame_parms) {
    printf("dlsch_decoding.c: NULL frame_parms pointer\n");
    return(dlsch->max_ldpc_iterations);
  }

830
 /* if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) {
Hongzhi Wang's avatar
Hongzhi Wang committed
831 832 833 834 835 836 837
    printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx);
    return(dlsch->max_ldpc_iterations);
  }

  if (dlsch->harq_ack[nr_tti_rx].ack != 2) {
    LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
        phy_vars_ue->Mod_id, nr_tti_rx, dlsch->harq_ack[nr_tti_rx].ack);
838
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
839 840 841 842 843 844 845 846 847 848 849 850 851 852

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

  /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]];
  if (harq_pid >= 8) {
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
    return(max_ldpc_iterations);
  }
  */

853
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
854 855
  harq_process->trials[harq_process->round]++;

856 857
  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs

858
  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl);
859

860
  A = harq_process->TBS;
Hongzhi Wang's avatar
Hongzhi Wang committed
861

Hongzhi Wang's avatar
Hongzhi Wang committed
862 863
  ret = dlsch->max_ldpc_iterations + 1;
  dlsch->last_iteration_cnt = ret;
Hongzhi Wang's avatar
Hongzhi Wang committed
864

865
  harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl);
Hongzhi Wang's avatar
Hongzhi Wang committed
866 867 868

  G = harq_process->G;

869
  LOG_D(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d  mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
870

Hongzhi Wang's avatar
Hongzhi Wang committed
871 872 873 874 875 876 877
  proc->decoder_main_available = 1;
  proc->decoder_thread_available = 0;
  proc->decoder_thread_available1 = 0;
  //get_G(frame_parms,nb_rb,dlsch->rb_alloc,mod_order,num_pdcch_symbols,phy_vars_ue->frame,subframe);

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

Francesco Mani's avatar
Francesco Mani committed
878
  if ((harq_process->R)<1024)
879 880 881
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
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
  if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
  {
    p_decParams->BG = 2;
    if (Coderate < 0.3333){
      p_decParams->R = 15;
      kc = 52;
    }
    else if (Coderate <0.6667){
      p_decParams->R = 13;
      kc = 32;
    }
    else {
      p_decParams->R = 23;
      kc = 17;
    }
  }
  else{
    p_decParams->BG = 1;
    if (Coderate < 0.6667){
      p_decParams->R = 13;
      kc = 68;
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
      kc = 35;
    }
    else {
      p_decParams->R = 89;
      kc = 27;
    }
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
914

915 916
  if (harq_process->round == 0) {
      // This is a new packet, so compute quantities regarding segmentation
917 918 919 920 921
	  if (A > 3824)
	  	  harq_process->B = A+24;
	  else
	  	  harq_process->B = A+16;

922 923 924 925 926 927 928 929 930 931 932
      nr_segmentation(NULL,
                      NULL,
                      harq_process->B,
                      &harq_process->C,
                      &harq_process->K,
                      &harq_process->Z,
                      &harq_process->F,
                      p_decParams->BG);


    }
Hongzhi Wang's avatar
Hongzhi Wang committed
933 934
    
    p_decParams->Z = harq_process->Z;
935

936 937 938
  //printf("coderate %f kc %d \n", Coderate, kc);
  p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
  p_decParams->outMode= 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
939 940 941 942

  err_flag = 0;
  r_offset = 0;

943
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
944

Francesco Mani's avatar
Francesco Mani committed
945 946
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
947 948
    a_segments = a_segments/273;
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
949

950 951
  if (harq_process->C > a_segments) {
    LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
Hongzhi Wang's avatar
Hongzhi Wang committed
952 953 954
    return((1+dlsch->max_ldpc_iterations));
  }
#ifdef DEBUG_DLSCH_DECODING
955
  printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
Hongzhi Wang's avatar
Hongzhi Wang committed
956 957
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
958
  notifiedFIFO_elt_t *res_dl;
Hongzhi Wang's avatar
Hongzhi Wang committed
959
  opp_enabled=1;
960 961
  if (harq_process->C>1) {
	for (int nb_seg =1 ; nb_seg<harq_process->C; nb_seg++){
Hongzhi Wang's avatar
Hongzhi Wang committed
962 963
	  if ( (res_dl=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
	          pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
964 965
	        }

Hongzhi Wang's avatar
Hongzhi Wang committed
966 967
	  AssertFatal((msgToPush_dl=pullNotifiedFIFO_nothreadSafe(&freeBlocks_dl)) != NULL,"chained list failure");
          nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush_dl);
968
	  curMsg->UE=phy_vars_ue;
Hongzhi Wang's avatar
Hongzhi Wang committed
969 970 971
	  
	  nbDlProcessing++;

972 973 974 975 976 977 978 979 980 981

	  memset(&curMsg->proc, 0, sizeof(curMsg->proc));
	  curMsg->proc.frame_rx  = proc->frame_rx;
	  curMsg->proc.nr_tti_rx = proc->nr_tti_rx;
	  curMsg->proc.num_seg   = nb_seg;

	  curMsg->proc.eNB_id= eNB_id;
	  curMsg->proc.harq_pid=harq_pid;
	  curMsg->proc.llr8_flag = llr8_flag;

Hongzhi Wang's avatar
Hongzhi Wang committed
982 983
	  msgToPush_dl->key= (nr_tti_rx%2) ? (nb_seg+30): nb_seg;
	  pushTpool(Tpool_dl, msgToPush_dl);
Hongzhi Wang's avatar
Hongzhi Wang committed
984

Ahmed's avatar
Ahmed committed
985 986 987 988
  /*Qm= harq_process->Qm;
    Nl=harq_process->Nl;
    r_thread = harq_process->C/2-1;
    C= harq_process->C;
Hongzhi Wang's avatar
Hongzhi Wang committed
989

Ahmed's avatar
Ahmed committed
990 991
    Gp = G/Nl/Qm;
    GpmodC = Gp%C;
Hongzhi Wang's avatar
Hongzhi Wang committed
992 993


Ahmed's avatar
Ahmed committed
994 995 996 997 998
    if (r_thread < (C-(GpmodC)))
      Er = Nl*Qm * (Gp/C);
    else
      Er = Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
    printf("mthread Er %d\n", Er);
Hongzhi Wang's avatar
Hongzhi Wang committed
999

Ahmed's avatar
Ahmed committed
1000
    printf("mthread instance_cnt_dlsch_td %d\n",  proc->instance_cnt_dlsch_td);*/
1001
	  }
Ahmed's avatar
Ahmed committed
1002 1003 1004 1005 1006
  //proc->decoder_main_available = 1;
  }

    r = 0;  
    if (r==0) r_offset =0;
Hongzhi Wang's avatar
Hongzhi Wang committed
1007

1008
    Kr = harq_process->K;
Hongzhi Wang's avatar
Hongzhi Wang committed
1009
    Kr_bytes = Kr>>3;
1010
    K_bytes_F = Kr_bytes-(harq_process->F>>3);
Hongzhi Wang's avatar
Hongzhi Wang committed
1011

1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
    E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);

    /*
    printf("Subblock deinterleaving, dlsch_llr %p, w %p\n",
     dlsch_llr+r_offset,
     &harq_process->w[r]);
    */
#if UE_TIMING_TRACE
    start_meas(dlsch_deinterleaving_stats);
#endif
    nr_deinterleaving_ldpc(E,
                           harq_process->Qm,
                           harq_process->w[r],
                           dlsch_llr+r_offset);

#ifdef DEBUG_DLSCH_DECODING
        for (int i =0; i<16; i++)
1029
              printf("rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
1030 1031 1032 1033 1034 1035
#endif

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif

#ifdef DEBUG_DLSCH_DECODING
    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",
          harq_pid,r, G,
          Kr*3,
          harq_process->TBS,
          harq_process->Qm,
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
#endif

1052 1053 1054 1055
    // for tbslbrm calculation according to 5.4.2.1 of 38.212
    if (harq_process->Nl < Nl)
      Nl = harq_process->Nl;

Hongzhi Wang's avatar
Hongzhi Wang committed
1056
    Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
1057

1058
    if (nr_rate_matching_ldpc_rx(Ilbrm,
1059 1060 1061 1062 1063 1064 1065 1066
                                 Tbslbrm,
                                 p_decParams->BG,
                                 p_decParams->Z,
                                 harq_process->d[r],
                                 harq_process->w[r],
                                 harq_process->C,
                                 harq_process->rvidx,
                                 (harq_process->round==0)?1:0,
1067 1068 1069
                                 E,
				 harq_process->F,
				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
      return(dlsch->max_ldpc_iterations);
    } else
    {
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
    }
1081 1082

    //for (int i =0; i<16; i++)
Ahmed's avatar
Ahmed committed
1083
    //      printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
1084

1085
    //r_offset += E;
Hongzhi Wang's avatar
Hongzhi Wang committed
1086
    //printf("main thread r_offset %d\n",r_offset);
1087 1088 1089
 
#ifdef DEBUG_DLSCH_DECODING   
    for (int i =0; i<16; i++)
1090
      printf("rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset);
1091
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1092 1093

#ifdef DEBUG_DLSCH_DECODING
1094

Hongzhi Wang's avatar
Hongzhi Wang committed
1095
    if (r==0) {
Ahmed's avatar
Ahmed committed
1096 1097
      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);
Hongzhi Wang's avatar
Hongzhi Wang committed
1098 1099
    }

1100
    printf("decoder input(segment %u) :",r);
1101 1102
    for (int i=0;i<(3*8*Kr_bytes);i++)
      printf("%d : %d\n",i,harq_process->d[r][i]);
Ahmed's avatar
Ahmed committed
1103
    printf("\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
1104 1105 1106 1107 1108 1109 1110
#endif


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

    //    printf("done\n");
1111
    if (harq_process->C == 1){
1112 1113 1114 1115 1116
      if (A > 3824)
    	crc_type = CRC24_A;
      else
    	crc_type = CRC16;

1117 1118 1119
      length_dec = harq_process->B;
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
1120
      crc_type = CRC24_B;
1121 1122
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1123 1124

    //#ifndef __AVX2__
1125

Hongzhi Wang's avatar
Hongzhi Wang committed
1126 1127
    if (err_flag == 0) {
/*
1128
        LOG_D(PHY, "LDPC 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",
Hongzhi Wang's avatar
Hongzhi Wang committed
1129 1130 1131
                            Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
                            harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations);
*/
1132

Hongzhi Wang's avatar
Hongzhi Wang committed
1133
#if UE_TIMING_TRACE
Ahmed's avatar
Ahmed committed
1134
      start_meas(dlsch_turbo_decoding_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
1135
#endif
1136
      LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
Hongzhi Wang's avatar
Hongzhi Wang committed
1137

1138
      /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
Ahmed's avatar
Ahmed committed
1139
        inv_d[cnt] = (1)*harq_process->d[r][cnt];
1140
      }*/
Ahmed's avatar
Ahmed committed
1141 1142 1143 1144 1145 1146

      memset(pv,0,2*p_decParams->Z*sizeof(int16_t));
      //memset(pl,0,2*p_decParams->Z*sizeof(int8_t));
      memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));


1147
      for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++)
Ahmed's avatar
Ahmed committed
1148
      {
1149
        pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
Ahmed's avatar
Ahmed committed
1150 1151
      }

Hongzhi Wang's avatar
Hongzhi Wang committed
1152 1153 1154
      j+=(harq_process->F>>3);
      //      for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
      for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++,j++)
Ahmed's avatar
Ahmed committed
1155
      {
1156
        pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
Ahmed's avatar
Ahmed committed
1157
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1158
      
Ahmed's avatar
Ahmed committed
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178
      for (i=0, j=0; j < ((kc*p_decParams->Z)>>4);  i+=2, j++)
      {
        pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
      }

      no_iteration_ldpc = nrLDPC_decoder(p_decParams,
               (int8_t*)&pl[0],
               llrProcBuf,
               p_nrLDPC_procBuf,
               p_procTime);

      nb_total_decod++;
      if (no_iteration_ldpc > 10){
        nb_error_decod++;
        ret = 1+dlsch->max_ldpc_iterations;
      }
      else {
        ret=2;
      }

1179
      if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
1180
        printf("Segment %u CRC OK\n",r);
Ahmed's avatar
Ahmed committed
1181 1182 1183 1184 1185 1186 1187
        ret = 2;
      }
      else {
        printf("CRC NOK\n");
        ret = 1+dlsch->max_ldpc_iterations;
      }

Hongzhi Wang's avatar
Hongzhi Wang committed
1188 1189 1190
    if (!nb_total_decod%10000){
        printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout);
    }
Ahmed's avatar
Ahmed committed
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215

    //else
      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);

      for (int m=0; m < Kr>>3; m ++)
      {
        harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
      }

    /*for (int u=0; u < Kr>>3; u ++)
      {
        ullrProcBuf[u]= (uint8_t) llrProcBuf[u];
      }


      printf("output unsigned ullrProcBuf \n");

      for (int j=0; j < Kr>>3; j ++)
      {
        printf(" %d \n", ullrProcBuf[j]);
      }
      printf(" \n");*/
    //printf("output channel decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);

    //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
1216
#ifdef DEBUG_DLSCH_DECODING
Ahmed's avatar
Ahmed committed
1217 1218
      for (int k=0;k<32;k++)
        printf("output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
1219
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230

#if UE_TIMING_TRACE
      stop_meas(dlsch_turbo_decoding_stats);
#endif
    }


    if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
      err_flag = 1;
    }
1231
  //} //loop r
Hongzhi Wang's avatar
Hongzhi Wang committed
1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242

  int32_t frame_rx_prev = frame;
  int32_t tti_rx_prev = nr_tti_rx - 1;
  if (tti_rx_prev < 0) {
    frame_rx_prev--;
    tti_rx_prev += 10*frame_parms->ttis_per_subframe;
  }
  frame_rx_prev = frame_rx_prev%1024;

  if (err_flag == 1) {
#if UE_DEBUG_TRACE
1243
    LOG_D(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",
Hongzhi Wang's avatar
Hongzhi Wang committed
1244 1245
        phy_vars_ue->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
#endif
1246 1247 1248
    harq_process->harq_ack.ack = 0;
    harq_process->harq_ack.harq_id = harq_pid;
    harq_process->harq_ack.send_harq_status = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1249 1250 1251 1252 1253
    harq_process->errors[harq_process->round]++;
    harq_process->round++;


    //    printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
1254
    if (harq_process->round >= dlsch->Mlimit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1255 1256 1257 1258 1259 1260
      harq_process->status = SCH_IDLE;
      harq_process->round  = 0;
    }
    if(is_crnti)
    {
    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
1261
               phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS);
Hongzhi Wang's avatar
Hongzhi Wang committed
1262 1263 1264 1265 1266
    }

    return((1+dlsch->max_ldpc_iterations));
  } else {
#if UE_DEBUG_TRACE
1267
      LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d\n",
Hongzhi Wang's avatar
Hongzhi Wang committed
1268 1269 1270 1271 1272
           phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
#endif

    harq_process->status = SCH_IDLE;
    harq_process->round  = 0;
1273 1274 1275
    harq_process->harq_ack.ack = 1;
    harq_process->harq_ack.harq_id = harq_pid;
    harq_process->harq_ack.send_harq_status = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294
    //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);

    if(is_crnti)
    {
    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
    }
    //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);

  }

  // Reassembly of Transport block here
  offset = 0;

  /*
  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);
  */
Hongzhi Wang's avatar
Hongzhi Wang committed
1295 1296 1297
  //uint32_t wait = 0;
  
  /* while((proc->decoder_thread_available == 0) )
Hongzhi Wang's avatar
Hongzhi Wang committed
1298 1299 1300
  {
          usleep(1);
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
1301
  proc->decoder_thread_available == 0;*/
1302 1303 1304 1305 1306 1307 1308

  /*notifiedFIFO_elt_t *res1=tryPullTpool(&nf, Tpool);
  if (!res1) {
	  printf("mthread trypull null\n");
	  usleep(1);
	  wait++;
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
1309 1310
  
  //usleep(50);
Hongzhi Wang's avatar
Hongzhi Wang committed
1311 1312

  proc->decoder_main_available = 0;
1313 1314
  Kr = harq_process->K; //to check if same K in all segments
  Kr_bytes = Kr>>3;
Hongzhi Wang's avatar
Hongzhi Wang committed
1315 1316 1317
  
  for (r=0; r<harq_process->C; r++) {

Ahmed's avatar
Ahmed committed
1318 1319 1320 1321
      memcpy(harq_process->b+offset,
               harq_process->c[r],
               Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
      offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
1322 1323

#ifdef DEBUG_DLSCH_DECODING
1324
      printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
Ahmed's avatar
Ahmed committed
1325 1326 1327 1328 1329 1330
      printf("copied %d bytes to b sequence (harq_pid %d)\n",
                (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
                printf("b[0] = %x,c[%d] = %x\n",
                harq_process->b[offset],
                harq_process->F>>3,
                harq_process->c[r]);
1331
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1332
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
1333 1334
  
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
1335 1336 1337 1338 1339 1340 1341 1342 1343 1344

  dlsch->last_iteration_cnt = ret;
  //proc->decoder_thread_available = 0;
  //proc->decoder_main_available = 0;

  return(ret);
}
#endif

#ifdef UE_DLSCH_PARALLELISATION
Hongzhi Wang's avatar
Hongzhi Wang committed
1345
void nr_dlsch_decoding_process(void *arg)
Hongzhi Wang's avatar
Hongzhi Wang committed
1346
{
1347 1348 1349
	nr_rxtx_thread_data_t *rxtxD= (nr_rxtx_thread_data_t *)arg;
    UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
    PHY_VARS_NR_UE    *phy_vars_ue   = rxtxD->UE;
1350
    NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
Hongzhi Wang's avatar
Hongzhi Wang committed
1351
    int llr8_flag1;
1352
    int32_t no_iteration_ldpc,length_dec;
Hongzhi Wang's avatar
Hongzhi Wang committed
1353 1354 1355 1356
    t_nrLDPC_dec_params decParams;
    t_nrLDPC_dec_params* p_decParams = &decParams;
    t_nrLDPC_time_stats procTime;
    t_nrLDPC_time_stats* p_procTime =&procTime ;
1357
    int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
1358
    t_nrLDPC_procBuf* p_nrLDPC_procBuf; 
Hongzhi Wang's avatar
Hongzhi Wang committed
1359 1360 1361
    int16_t z [68*384];
    int8_t l [68*384];
    //__m128i l;
Hongzhi Wang's avatar
Hongzhi Wang committed
1362 1363
    //int16_t inv_d [68*384];
    //int16_t *p_invd =&inv_d;
1364
    uint8_t kb, kc;
1365
    uint8_t Ilbrm = 1;
1366 1367
    uint32_t Tbslbrm = 950984;
    uint16_t nb_rb = 30; //to update
1368
    double Coderate = 0.0;
1369 1370 1371
    uint16_t nb_symb_sch = 12;
    uint8_t nb_re_dmrs = 6;
    uint16_t length_dmrs = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1372 1373 1374 1375 1376 1377 1378 1379

    uint32_t i,j;
    uint32_t k;

    __m128i *pv = (__m128i*)&z;
    __m128i *pl = (__m128i*)&l;

    proc->instance_cnt_dlsch_td=-1;
1380
    //proc->nr_tti_rx=proc->sub_frame_start;
Hongzhi Wang's avatar
Hongzhi Wang committed
1381

1382
    proc->decoder_thread_available = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1383 1384 1385 1386 1387 1388 1389 1390 1391 1392
    

#if UE_TIMING_TRACE
  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;
#endif
  uint32_t A,E;
  uint32_t G;
  uint32_t ret,offset;
1393
  uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bytes_F;
Hongzhi Wang's avatar
Hongzhi Wang committed
1394
  uint8_t crc_type;
1395 1396 1397 1398
  uint8_t C,Cprime;
  uint8_t Qm;
  uint8_t Nl;
  //uint32_t Er;
Hongzhi Wang's avatar
Hongzhi Wang committed
1399

1400 1401 1402 1403
  int eNB_id                = proc->eNB_id;
  int harq_pid              = proc->harq_pid;
  llr8_flag1                = proc->llr8_flag;
  int frame                 = proc->frame_rx;
1404 1405
  int slot                  = proc->nr_tti_rx;
  r               	    = proc->num_seg;
Ahmed's avatar
Ahmed committed
1406

1407 1408 1409 1410 1411 1412
  NR_UE_DLSCH_t *dlsch      = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[slot]][eNB_id][0];
  NR_DL_UE_HARQ_t *harq_process  = dlsch->harq_processes[harq_pid];
  short *dlsch_llr        = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[slot]][eNB_id]->llr[0];
  //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag);
  p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r];
  nb_symb_sch = harq_process->nb_symbols;
1413
  printf("dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_tti_rx, proc->num_seg, r, harq_process->nb_symbols);
Ahmed's avatar
Ahmed committed
1414

Hongzhi Wang's avatar
Hongzhi Wang committed
1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428

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

  /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]];
  if (harq_pid >= 8) {
    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
    return(max_ldpc_iterations);
  }
  */

1429
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
1430 1431 1432

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

1433 1434
  uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs

1435
  harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl);
1436

Hongzhi Wang's avatar
Hongzhi Wang committed
1437 1438
  A = harq_process->TBS; //2072 for QPSK 1/3

1439

Hongzhi Wang's avatar
Hongzhi Wang committed
1440 1441
  ret = dlsch->max_ldpc_iterations;

1442
  harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl);
Hongzhi Wang's avatar
Hongzhi Wang committed
1443
  G = harq_process->G;
1444

1445
  LOG_D(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
1446

Francesco Mani's avatar
Francesco Mani committed
1447
  if ((harq_process->R)<1024)
1448 1449 1450
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
1451

1452 1453 1454 1455 1456 1457 1458 1459
  if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
  {
    p_decParams->BG = 2;
    if (Coderate < 0.3333){
      p_decParams->R = 15;
      kc = 52;
    }
    else if (Coderate <0.6667){
Ahmed's avatar
Ahmed committed
1460
      p_decParams->R = 13;
1461
      kc = 32;
Ahmed's avatar
Ahmed committed
1462
    }
1463 1464 1465 1466 1467 1468 1469 1470
    else {
      p_decParams->R = 23;
      kc = 17;
    }
  }
  else{
    p_decParams->BG = 1;
    if (Coderate < 0.6667){
Ahmed's avatar
Ahmed committed
1471
      p_decParams->R = 13;
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481
      kc = 68;
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
      kc = 35;
    }
    else {
      p_decParams->R = 89;
      kc = 27;
    }
1482 1483
  }    

Hongzhi Wang's avatar
Hongzhi Wang committed
1484
  harq_process->round  =0;
magounak's avatar
magounak committed
1485
 // if (harq_process->round == 0) {
1486
    // This is a new packet, so compute quantities regarding segmentation
1487 1488 1489 1490
	if (A > 3824)
	  harq_process->B = A+24;
	else
	  harq_process->B = A+16;
1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502

    nr_segmentation(NULL,
                    NULL,
                    harq_process->B,
                    &harq_process->C,
                    &harq_process->K,
                    &harq_process->Z,
                    &harq_process->F,
                    p_decParams->BG);

    p_decParams->Z = harq_process->Z;

magounak's avatar
magounak committed
1503
   // }
Hongzhi Wang's avatar
Hongzhi Wang committed
1504 1505
    
    //printf("round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
1506

1507

1508
  p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
1509
  p_decParams->outMode= 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520

  /*
  else {
    printf("dlsch_decoding.c: Ndi>0 not checked yet!!\n");
    return(max_ldpc_iterations);
  }
  */
  err_flag = 0;
  //r_offset = 0;

  /*
1521
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
Hongzhi Wang's avatar
Hongzhi Wang committed
1522

Francesco Mani's avatar
Francesco Mani committed
1523 1524
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
1525 1526
    a_segments = a_segments/273;
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
1527

1528 1529
  if (harq_process->C > a_segments) {
    LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
Hongzhi Wang's avatar
Hongzhi Wang committed
1530 1531 1532 1533 1534 1535 1536 1537 1538
    return((1+dlsch->max_ldpc_iterations));
  }*/
#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

  opp_enabled=1;
  
  Qm= harq_process->Qm;
1539 1540 1541
  Nl=harq_process->Nl;
  //r_thread = harq_process->C/2-1;
  C= harq_process->C;
Hongzhi Wang's avatar
Hongzhi Wang committed
1542

1543
  Cprime = C; //assume CBGTI not present
Hongzhi Wang's avatar
Hongzhi Wang committed
1544

1545
  if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
Ahmed's avatar
Ahmed committed
1546
    r_offset = Nl*Qm*(G/(Nl*Qm*Cprime));
1547
  else
Ahmed's avatar
Ahmed committed
1548
    r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
Hongzhi Wang's avatar
Hongzhi Wang committed
1549

Ahmed's avatar
Ahmed committed
1550 1551
    //  printf("thread0 r_offset %d\n",r_offset);
           
Hongzhi Wang's avatar
Hongzhi Wang committed
1552
  //for (r=(harq_process->C/2); r<harq_process->C; r++) {
1553
     //    r=1; //(harq_process->C/2);
Hongzhi Wang's avatar
Hongzhi Wang committed
1554

1555
  r_offset = r*r_offset;
Hongzhi Wang's avatar
Hongzhi Wang committed
1556

1557 1558 1559
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
  K_bytes_F = Kr_bytes-(harq_process->F>>3);
Hongzhi Wang's avatar
Hongzhi Wang committed
1560

1561
  E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
1562 1563 1564 1565 1566 1567 1568 1569 1570

#if UE_TIMING_TRACE
    start_meas(dlsch_deinterleaving_stats);
#endif
    nr_deinterleaving_ldpc(E,
                           harq_process->Qm,
                           harq_process->w[r],
                           dlsch_llr+r_offset);

1571 1572
#ifdef DEBUG_DLSCH_DECODING
    for (int i =0; i<16; i++)
1573
              printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
1574
#endif
1575 1576 1577 1578 1579

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif

#ifdef DEBUG_DLSCH_DECODING
    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",
          harq_pid,r, G,
          Kr*3,
          harq_process->TBS,
          harq_process->Qm,
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
#endif

1596 1597 1598 1599 1600
    if (Nl<4)
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl,harq_process->C);
    else
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);

1601
    if (nr_rate_matching_ldpc_rx(Ilbrm,
1602 1603 1604 1605 1606 1607 1608 1609
                                 Tbslbrm,
                                 p_decParams->BG,
                                 p_decParams->Z,
                                 harq_process->d[r],
                                 harq_process->w[r],
                                 harq_process->C,
                                 harq_process->rvidx,
                                 (harq_process->round==0)?1:0,
1610 1611 1612
                                 E,
				 harq_process->F,
				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
      //return(dlsch->max_ldpc_iterations);
    } else
    {
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
    }

1625
    //for (int i =0; i<16; i++)
Ahmed's avatar
Ahmed committed
1626
    //      printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
1627

1628
    //r_offset += E;
1629

1630
#ifdef DEBUG_DLSCH_DECODING
Hongzhi Wang's avatar
Hongzhi Wang committed
1631 1632
    if (r==0) {
              write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
1633
              write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0);
Hongzhi Wang's avatar
Hongzhi Wang committed
1634 1635
    }

1636
    printf("decoder input(segment %u) :",r);
Hongzhi Wang's avatar
Hongzhi Wang committed
1637
    int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
1638 1639
      printf("%d : %d\n",i,harq_process->d[r][i]);
      printf("\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
1640 1641 1642 1643 1644 1645
#endif


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

1646
    if (harq_process->C == 1){
1647 1648 1649 1650 1651
    	if (A > 3824)
    	 	crc_type = CRC24_A;
    	else
    		crc_type = CRC16;

1652 1653 1654
      length_dec = harq_process->B;
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
1655
      crc_type = CRC24_B;
1656 1657
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1658 1659 1660

    if (err_flag == 0) {
/*
1661
        LOG_D(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",
Hongzhi Wang's avatar
Hongzhi Wang committed
1662 1663 1664
                            Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
                            harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations);
*/
Ahmed's avatar
Ahmed committed
1665 1666 1667 1668
      if (llr8_flag1) {
        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);
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1669 1670 1671 1672
#if UE_TIMING_TRACE
        start_meas(dlsch_turbo_decoding_stats);
#endif
//      LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
1673
/*
1674 1675 1676
        for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
              inv_d[cnt] = (1)*harq_process->d[r][cnt];
              }
1677
*/
Hongzhi Wang's avatar
Hongzhi Wang committed
1678

1679 1680 1681
        memset(pv,0,2*p_decParams->Z*sizeof(int16_t));
        //memset(pl,0,2*p_decParams->Z*sizeof(int8_t));
        memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
Hongzhi Wang's avatar
Hongzhi Wang committed
1682

1683
        for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++)
Ahmed's avatar
Ahmed committed
1684
        {
1685
          pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
Ahmed's avatar
Ahmed committed
1686
        }
1687

Hongzhi Wang's avatar
Hongzhi Wang committed
1688 1689 1690
        j+=(harq_process->F>>3);
        //      for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
        for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++,j++)
1691
        {
Hongzhi Wang's avatar
Hongzhi Wang committed
1692
         pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
1693
        }
1694

1695 1696 1697 1698
        for (i=0, j=0; j < ((kc*p_decParams->Z)>>4);  i+=2, j++)
        {
          pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
        }
Hongzhi Wang's avatar
Hongzhi Wang committed
1699

1700
        no_iteration_ldpc = nrLDPC_decoder(p_decParams,
1701 1702 1703 1704
                                           (int8_t*)&pl[0],
                                           llrProcBuf,
                                           p_nrLDPC_procBuf,
                                           p_procTime);
Hongzhi Wang's avatar
Hongzhi Wang committed
1705

1706 1707
        // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
        if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
1708
          LOG_D(PHY,"Segment %u CRC OK\n",r);
1709 1710 1711
          ret = 2;
        }
        else {
1712
          LOG_D(PHY,"Segment %u CRC NOK\n",r);
1713 1714 1715
          ret = 1+dlsch->max_ldpc_iterations;
        }

Ahmed's avatar
Ahmed committed
1716
    if (no_iteration_ldpc > 10)
1717
      LOG_D(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
Ahmed's avatar
Ahmed committed
1718 1719
    //else
      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);
Hongzhi Wang's avatar
Hongzhi Wang committed
1720

Ahmed's avatar
Ahmed committed
1721 1722 1723 1724
    for (int m=0; m < Kr>>3; m ++)
                    {
                  harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
                    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1725

Ahmed's avatar
Ahmed committed
1726 1727 1728 1729
            /*for (int u=0; u < Kr>>3; u ++)
                            {
                      ullrProcBuf[u]= (uint8_t) llrProcBuf[u];
                            }
Hongzhi Wang's avatar
Hongzhi Wang committed
1730 1731


Ahmed's avatar
Ahmed committed
1732
            printf("output unsigned ullrProcBuf \n");
Hongzhi Wang's avatar
Hongzhi Wang committed
1733

Ahmed's avatar
Ahmed committed
1734 1735
            for (int j=0; j < Kr>>3; j ++)
                                    {
Hongzhi Wang's avatar
Hongzhi Wang committed
1736

Ahmed's avatar
Ahmed committed
1737
                              printf(" %d \n", ullrProcBuf[j]);
Hongzhi Wang's avatar
Hongzhi Wang committed
1738

Ahmed's avatar
Ahmed committed
1739 1740 1741 1742 1743
                                    }
          printf(" \n");*/
#ifdef DEBUG_DLSCH_DECODING       
  for (int k=0;k<2;k++)
      printf("segment 1 output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
1744
#endif 
Ahmed's avatar
Ahmed committed
1745
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756
#if UE_TIMING_TRACE
      stop_meas(dlsch_turbo_decoding_stats);
#endif
    }

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

1757 1758 1759
  proc->decoder_thread_available = 1;
  //proc->decoder_main_available = 0;
}
Hongzhi Wang's avatar
Hongzhi Wang committed
1760

1761 1762 1763 1764 1765
void *dlsch_thread(void *arg) {
  //this thread should be over the processing thread to keep in real time
  PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
  notifiedFIFO_t nf;
  initNotifiedFIFO(&nf);
Hongzhi Wang's avatar
Hongzhi Wang committed
1766 1767
  notifiedFIFO_elt_t *res_dl;
  initNotifiedFIFO_nothreadSafe(&freeBlocks_dl);
Hongzhi Wang's avatar
Hongzhi Wang committed
1768

Hongzhi Wang's avatar
Hongzhi Wang committed
1769
  for (int i=0; i<RX_NB_TH_DL+1; i++){
Hongzhi Wang's avatar
Hongzhi Wang committed
1770
    pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,
Hongzhi Wang's avatar
Hongzhi Wang committed
1771
                                  newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), 0,&nf,nr_dlsch_decoding_process));}
Hongzhi Wang's avatar
Hongzhi Wang committed
1772

1773
  while (!oai_exit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1774

1775
    notifiedFIFO_elt_t *res;
Hongzhi Wang's avatar
Hongzhi Wang committed
1776

1777
    while (nbDlProcessing >= RX_NB_TH_DL) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1778
      if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
1779
        nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData;
Hongzhi Wang's avatar
Hongzhi Wang committed
1780 1781
        //nbDlProcessing--;
        pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res);
1782
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1783

1784
      usleep(200);
Hongzhi Wang's avatar
Hongzhi Wang committed
1785
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1786 1787 1788 1789 1790
    
    res_dl=pullTpool(&nf, Tpool_dl);
    nbDlProcessing--;
	pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1791

1792 1793
    //msgToPush->key=0;
    //pushTpool(Tpool, msgToPush);
Hongzhi Wang's avatar
Hongzhi Wang committed
1794

1795
  } // while !oai_exit
Hongzhi Wang's avatar
Hongzhi Wang committed
1796

Hongzhi Wang's avatar
Hongzhi Wang committed
1797
  return NULL;
Hongzhi Wang's avatar
Hongzhi Wang committed
1798 1799 1800
}

#endif