nr_dlsch_decoding.c 56.3 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"
Hongzhi Wang's avatar
Hongzhi Wang committed
44 45
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
46
//#define DEBUG_DLSCH_DECODING 1
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 74
    if (N_RB_DL != 273) {
      a_segments = a_segments*N_RB_DL;
      a_segments = a_segments/273;
    }  
 
    uint16_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment

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

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

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

99
        for (r=0; r<a_segments; r++) {
Ahmed's avatar
Ahmed committed
100 101 102 103 104
          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
105 106 107 108 109

        free16(dlsch->harq_processes[i],sizeof(NR_DL_UE_HARQ_t));
        dlsch->harq_processes[i] = NULL;
      }
    }
110
      
Hongzhi Wang's avatar
Hongzhi Wang committed
111 112 113 114 115 116 117 118 119 120 121
    free16(dlsch,sizeof(NR_UE_DLSCH_t));
    dlsch = NULL;
  }
}

NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_ldpc_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag)
{

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

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

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

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

  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;
138
    dlsch->Mlimit = 4;
Hongzhi Wang's avatar
Hongzhi Wang committed
139
    dlsch->max_ldpc_iterations = max_ldpc_iterations;
140
 
Hongzhi Wang's avatar
Hongzhi Wang committed
141 142 143 144 145 146 147
    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;
148
        dlsch->harq_processes[i]->b = (uint8_t*)malloc16(dlsch_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
149 150

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

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

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

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

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

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

            if (dlsch->harq_processes[i]->w[r])
175
              memset(dlsch->harq_processes[i]->w[r],0,(5*8448)*sizeof(short));
176 177
            else
              exit_flag=2;
Hongzhi Wang's avatar
Hongzhi Wang committed
178 179 180 181 182 183 184 185 186 187 188 189
          }
        }
      } 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);
190
  free_nr_ue_dlsch(&dlsch,N_RB_DL);
Hongzhi Wang's avatar
Hongzhi Wang committed
191 192 193 194

  return(NULL);
}

Hongzhi Wang's avatar
Hongzhi Wang committed
195
void nr_dlsch_unscrambling(int16_t* llr,
hongzhi wang's avatar
hongzhi wang committed
196
                         uint32_t size,
Hongzhi Wang's avatar
Hongzhi Wang committed
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
                         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
213
      llr[i] = -llr[i];
Hongzhi Wang's avatar
Hongzhi Wang committed
214 215 216 217
  }

}

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

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

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

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

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

  uint32_t i,j;

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

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

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

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

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

296
  /*if (harq_process->harq_ack.ack != 2) {
Hongzhi Wang's avatar
Hongzhi Wang committed
297 298
    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);
299
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
300 301 302 303 304 305

  //  nb_rb = dlsch->nb_rb;

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

  /*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);
312
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
313 314 315
  }
  */

316 317
  nb_rb = harq_process->nb_rb;

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

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

Raymond Knopp's avatar
Raymond Knopp committed
322
  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, harq_process->Nl);
323

Hongzhi Wang's avatar
Hongzhi Wang committed
324
  A = harq_process->TBS;
325
  ret = dlsch->max_ldpc_iterations + 1;
326
  dlsch->last_iteration_cnt = ret;
327
 
Raymond Knopp's avatar
Raymond Knopp committed
328
  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
329 330
  G = harq_process->G;

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

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

Ahmed's avatar
Ahmed committed
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 369
  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;
    }
  }

370 371 372

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

378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
    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
393
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
394 395 396 397

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

Ahmed's avatar
Ahmed committed
398 399 400 401
  //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
402 403 404 405

  err_flag = 0;
  r_offset = 0;

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

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

413 414
  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
415 416
    return((1+dlsch->max_ldpc_iterations));
  }
Ahmed's avatar
Ahmed committed
417

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

  opp_enabled=1;

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

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

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

431
    //printf("start rx segment %d\n",r);
432 433 434 435 436
    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
437

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

440

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

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

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

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif
454

Hongzhi Wang's avatar
Hongzhi Wang committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
#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

Hongzhi Wang's avatar
Hongzhi Wang committed
471
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
472

473 474 475 476 477
    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);

478

Hongzhi Wang's avatar
Hongzhi Wang committed
479
    if (nr_rate_matching_ldpc_rx(Ilbrm,
480 481 482 483 484 485 486 487
                                 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,
488
                                 E,
cig's avatar
cig committed
489 490
                                 harq_process->F,
                                 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
491
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
492 493 494 495
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
      LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
496
      return(dlsch->max_ldpc_iterations + 1);
Ahmed's avatar
Ahmed committed
497
    } else {
498

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

504

505
    //for (int i =0; i<16; i++)
Ahmed's avatar
Ahmed committed
506
    //      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
507

508
    r_offset += E;
509

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

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

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

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

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

    if (err_flag == 0) {

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

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

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

Ahmed's avatar
Ahmed committed
551 552 553
      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
554

555

Ahmed's avatar
Ahmed committed
556 557 558 559
      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]));
      }
560 561 562 563
      // 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
564 565 566 567 568 569 570 571 572
      {
        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
573

Hongzhi Wang's avatar
Hongzhi Wang committed
574
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
575

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

Ahmed's avatar
Ahmed committed
583 584
      // 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)) {
585
        LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
586 587
        //Temporary hack
        no_iteration_ldpc = dlsch->max_ldpc_iterations;
588
        ret = no_iteration_ldpc;
Ahmed's avatar
Ahmed committed
589 590
      }
      else {
591
        LOG_D(PHY,"CRC NOK\n\033[0m");
592
        ret = 1 + dlsch->max_ldpc_iterations;
Ahmed's avatar
Ahmed committed
593 594
      }

595

Ahmed's avatar
Ahmed committed
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
      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
611

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


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

    /*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;
637
      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
638 639 640 641 642 643 644 645 646 647 648 649 650
      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) {
651
//#if UE_DEBUG_TRACE
652
    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
653
        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);
654
//#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
655 656 657 658
    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]++;
659
    // harq_process->round++; // [hna] uncomment this line when HARQ is implemented
Hongzhi Wang's avatar
Hongzhi Wang committed
660 661

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

Hongzhi Wang's avatar
Hongzhi Wang committed
667 668
    if(is_crnti)
    {
669
    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
670 671 672
               phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
    }

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

    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;
685
    
686
    //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
687 688 689 690
      //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);

    if(is_crnti)
    {
691
    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
692 693 694 695 696 697 698
    }
    //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
699 700
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
Hongzhi Wang's avatar
Hongzhi Wang committed
701 702 703 704 705 706

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

Hongzhi Wang's avatar
Hongzhi Wang committed
708
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN);
709

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

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

#ifdef DEBUG_DLSCH_DECODING
718
    printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
719 720 721 722 723 724
    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]);
725 726 727 728 729

              /*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
730
#endif
731 732

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

Hongzhi Wang's avatar
Hongzhi Wang committed
741 742
  }

Hongzhi Wang's avatar
Hongzhi Wang committed
743
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT);
744

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

  return(ret);
}

#ifdef UE_DLSCH_PARALLELISATION
751
uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
Ahmed's avatar
Ahmed committed
752 753 754 755 756 757 758 759 760 761 762 763
                                    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
764 765 766 767 768 769 770 771 772 773
{

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

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

  ret = dlsch->max_ldpc_iterations;

864
  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
865 866 867

  G = harq_process->G;

868
  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);
869

Hongzhi Wang's avatar
Hongzhi Wang committed
870 871 872 873 874 875 876
  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
877
  if ((harq_process->R)<1024)
878 879 880
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
881

882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912
  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
913

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

921 922 923 924 925 926 927 928 929 930 931 932 933
      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;

    }

934 935 936
  //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
937 938 939 940

  err_flag = 0;
  r_offset = 0;

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

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

948 949
  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
950 951 952
    return((1+dlsch->max_ldpc_iterations));
  }
#ifdef DEBUG_DLSCH_DECODING
953
  printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
Hongzhi Wang's avatar
Hongzhi Wang committed
954 955
#endif

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

Hongzhi Wang's avatar
Hongzhi Wang committed
964 965
	  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);
966
	  curMsg->UE=phy_vars_ue;
Hongzhi Wang's avatar
Hongzhi Wang committed
967 968 969
	  
	  nbDlProcessing++;

970 971 972 973 974 975 976 977 978 979

	  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
980 981
	  msgToPush_dl->key= (nr_tti_rx%2) ? (nb_seg+30): nb_seg;
	  pushTpool(Tpool_dl, msgToPush_dl);
Hongzhi Wang's avatar
Hongzhi Wang committed
982

Ahmed's avatar
Ahmed committed
983 984 985 986
  /*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
987

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


Ahmed's avatar
Ahmed committed
992 993 994 995 996
    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
997

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

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

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

1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
    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++)
1027
              printf("rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
1028 1029 1030 1031 1032 1033
#endif

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
#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

1050 1051 1052 1053
    // 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
1054
    Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
1055

1056
    if (nr_rate_matching_ldpc_rx(Ilbrm,
1057 1058 1059 1060 1061 1062 1063 1064
                                 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,
1065 1066 1067
                                 E,
				 harq_process->F,
				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
#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
    }
1079 1080

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

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

#ifdef DEBUG_DLSCH_DECODING
1092

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

1098
    printf("decoder input(segment %u) :",r);
1099 1100
    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
1101
    printf("\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
1102 1103 1104 1105 1106 1107 1108
#endif


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

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

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

    //#ifndef __AVX2__
1123

Hongzhi Wang's avatar
Hongzhi Wang committed
1124 1125
    if (err_flag == 0) {
/*
1126
        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
1127 1128 1129
                            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);
*/
1130

Hongzhi Wang's avatar
Hongzhi Wang committed
1131
#if UE_TIMING_TRACE
Ahmed's avatar
Ahmed committed
1132
      start_meas(dlsch_turbo_decoding_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
1133
#endif
1134
      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
1135

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

      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));


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

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

      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;
      }

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

Hongzhi Wang's avatar
Hongzhi Wang committed
1184 1185 1186
    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
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211

    //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]);
1212
#ifdef DEBUG_DLSCH_DECODING
Ahmed's avatar
Ahmed committed
1213 1214
      for (int k=0;k<32;k++)
        printf("output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
1215
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226

#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;
    }
1227
  //} //loop r
Hongzhi Wang's avatar
Hongzhi Wang committed
1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238

  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
1239
    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
1240 1241
        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
1242 1243 1244
    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
1245 1246 1247 1248 1249
    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);
1250
    if (harq_process->round >= dlsch->Mlimit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1251 1252 1253 1254 1255 1256
      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",
1257
               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
1258 1259 1260 1261 1262
    }

    return((1+dlsch->max_ldpc_iterations));
  } else {
#if UE_DEBUG_TRACE
1263
      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
1264 1265 1266 1267 1268
           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;
1269 1270 1271
    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
1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
    //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
1291 1292 1293
  //uint32_t wait = 0;
  
  /* while((proc->decoder_thread_available == 0) )
Hongzhi Wang's avatar
Hongzhi Wang committed
1294 1295 1296
  {
          usleep(1);
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
1297
  proc->decoder_thread_available == 0;*/
1298 1299 1300 1301 1302 1303 1304

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

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

Ahmed's avatar
Ahmed committed
1314 1315 1316 1317
      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));
1318 1319

#ifdef DEBUG_DLSCH_DECODING
1320
      printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
Ahmed's avatar
Ahmed committed
1321 1322 1323 1324 1325 1326
      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]);
1327
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1328
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
1329 1330
  
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340

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

    uint32_t i,j;
    uint32_t k;

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

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

1378
    proc->decoder_thread_available = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1379 1380 1381 1382 1383 1384 1385 1386 1387 1388
    

#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;
1389
  uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bytes_F;
Hongzhi Wang's avatar
Hongzhi Wang committed
1390
  uint8_t crc_type;
1391 1392 1393 1394
  uint8_t C,Cprime;
  uint8_t Qm;
  uint8_t Nl;
  //uint32_t Er;
Hongzhi Wang's avatar
Hongzhi Wang committed
1395

1396 1397 1398 1399
  int eNB_id                = proc->eNB_id;
  int harq_pid              = proc->harq_pid;
  llr8_flag1                = proc->llr8_flag;
  int frame                 = proc->frame_rx;
1400 1401
  int slot                  = proc->nr_tti_rx;
  r               	    = proc->num_seg;
Ahmed's avatar
Ahmed committed
1402

1403 1404 1405 1406 1407 1408
  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;
1409
  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
1410

Hongzhi Wang's avatar
Hongzhi Wang committed
1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424

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

1425
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
1426 1427 1428

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

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

1431
  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, harq_process->Nl);
1432

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

1435

Hongzhi Wang's avatar
Hongzhi Wang committed
1436 1437
  ret = dlsch->max_ldpc_iterations;

1438
  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
1439
  G = harq_process->G;
1440

1441
  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);
1442

Francesco Mani's avatar
Francesco Mani committed
1443
  if ((harq_process->R)<1024)
1444 1445 1446
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
1447

1448 1449 1450 1451 1452 1453 1454 1455
  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
1456
      p_decParams->R = 13;
1457
      kc = 32;
Ahmed's avatar
Ahmed committed
1458
    }
1459 1460 1461 1462 1463 1464 1465 1466
    else {
      p_decParams->R = 23;
      kc = 17;
    }
  }
  else{
    p_decParams->BG = 1;
    if (Coderate < 0.6667){
Ahmed's avatar
Ahmed committed
1467
      p_decParams->R = 13;
1468 1469 1470 1471 1472 1473 1474 1475 1476 1477
      kc = 68;
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
      kc = 35;
    }
    else {
      p_decParams->R = 89;
      kc = 27;
    }
1478 1479
  }    

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

    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;

    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1500 1501
    
    //printf("round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
1502

1503

1504
  p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
1505
  p_decParams->outMode= 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516

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

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

Francesco Mani's avatar
Francesco Mani committed
1519 1520
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
1521 1522
    a_segments = a_segments/273;
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
1523

1524 1525
  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
1526 1527 1528 1529 1530 1531 1532 1533 1534
    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;
1535 1536 1537
  Nl=harq_process->Nl;
  //r_thread = harq_process->C/2-1;
  C= harq_process->C;
Hongzhi Wang's avatar
Hongzhi Wang committed
1538

1539
  Cprime = C; //assume CBGTI not present
Hongzhi Wang's avatar
Hongzhi Wang committed
1540

1541
  if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
Ahmed's avatar
Ahmed committed
1542
    r_offset = Nl*Qm*(G/(Nl*Qm*Cprime));
1543
  else
Ahmed's avatar
Ahmed committed
1544
    r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
Hongzhi Wang's avatar
Hongzhi Wang committed
1545

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

1551
  r_offset = r*r_offset;
Hongzhi Wang's avatar
Hongzhi Wang committed
1552

1553 1554 1555
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
  K_bytes_F = Kr_bytes-(harq_process->F>>3);
Hongzhi Wang's avatar
Hongzhi Wang committed
1556

1557
  E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
1558 1559 1560 1561 1562 1563 1564 1565 1566

#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);

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

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591
#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

1592 1593 1594 1595 1596
    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);

1597
    if (nr_rate_matching_ldpc_rx(Ilbrm,
1598 1599 1600 1601 1602 1603 1604 1605
                                 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,
1606 1607 1608
                                 E,
				 harq_process->F,
				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620
#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
    }

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

1624
    //r_offset += E;
1625

1626
#ifdef DEBUG_DLSCH_DECODING
Hongzhi Wang's avatar
Hongzhi Wang committed
1627 1628
    if (r==0) {
              write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
1629
              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
1630 1631
    }

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


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

1642
    if (harq_process->C == 1){
1643 1644 1645 1646 1647
    	if (A > 3824)
    	 	crc_type = CRC24_A;
    	else
    		crc_type = CRC16;

1648 1649 1650
      length_dec = harq_process->B;
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
1651
      crc_type = CRC24_B;
1652 1653
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1654 1655 1656

    if (err_flag == 0) {
/*
1657
        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
1658 1659 1660
                            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
1661 1662 1663 1664
      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
1665 1666 1667 1668
#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);
1669
/*
1670 1671 1672
        for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
              inv_d[cnt] = (1)*harq_process->d[r][cnt];
              }
1673
*/
Hongzhi Wang's avatar
Hongzhi Wang committed
1674

1675 1676 1677
        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
1678

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

1684 1685 1686 1687
        for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
        {
          pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
        }
1688

1689 1690 1691 1692
        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
1693

1694
        no_iteration_ldpc = nrLDPC_decoder(p_decParams,
Ahmed's avatar
Ahmed committed
1695 1696
               (int8_t*)&pl[0],
               llrProcBuf,
1697
                           p_nrLDPC_procBuf,                
Ahmed's avatar
Ahmed committed
1698
               p_procTime);
Hongzhi Wang's avatar
Hongzhi Wang committed
1699

1700 1701
        // 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)) {
1702
          LOG_D(PHY,"Segment %u CRC OK\n",r);
1703 1704 1705
          ret = 2;
        }
        else {
1706
          LOG_D(PHY,"Segment %u CRC NOK\n",r);
1707 1708 1709
          ret = 1+dlsch->max_ldpc_iterations;
        }

Ahmed's avatar
Ahmed committed
1710
    if (no_iteration_ldpc > 10)
1711
      LOG_D(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
Ahmed's avatar
Ahmed committed
1712 1713
    //else
      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);
Hongzhi Wang's avatar
Hongzhi Wang committed
1714

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

Ahmed's avatar
Ahmed committed
1720 1721 1722 1723
            /*for (int u=0; u < Kr>>3; u ++)
                            {
                      ullrProcBuf[u]= (uint8_t) llrProcBuf[u];
                            }
Hongzhi Wang's avatar
Hongzhi Wang committed
1724 1725


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

Ahmed's avatar
Ahmed committed
1728 1729
            for (int j=0; j < Kr>>3; j ++)
                                    {
Hongzhi Wang's avatar
Hongzhi Wang committed
1730

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

Ahmed's avatar
Ahmed committed
1733 1734 1735 1736 1737
                                    }
          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]);
1738
#endif 
Ahmed's avatar
Ahmed committed
1739
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750
#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;
    }
  //}

1751 1752 1753
  proc->decoder_thread_available = 1;
  //proc->decoder_main_available = 0;
}
Hongzhi Wang's avatar
Hongzhi Wang committed
1754

1755 1756 1757 1758 1759
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
1760 1761
  notifiedFIFO_elt_t *res_dl;
  initNotifiedFIFO_nothreadSafe(&freeBlocks_dl);
Hongzhi Wang's avatar
Hongzhi Wang committed
1762

Hongzhi Wang's avatar
Hongzhi Wang committed
1763
  for (int i=0; i<RX_NB_TH_DL+1; i++){
Hongzhi Wang's avatar
Hongzhi Wang committed
1764
    pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,
Hongzhi Wang's avatar
Hongzhi Wang committed
1765
                                  newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), 0,&nf,nr_dlsch_decoding_process));}
Hongzhi Wang's avatar
Hongzhi Wang committed
1766

1767
  while (!oai_exit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1768

1769
    notifiedFIFO_elt_t *res;
Hongzhi Wang's avatar
Hongzhi Wang committed
1770

1771
    while (nbDlProcessing >= RX_NB_TH_DL) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1772
      if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
1773
        nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData;
Hongzhi Wang's avatar
Hongzhi Wang committed
1774 1775
        //nbDlProcessing--;
        pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res);
1776
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1777

1778
      usleep(200);
Hongzhi Wang's avatar
Hongzhi Wang committed
1779
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1780 1781 1782 1783 1784
    
    res_dl=pullTpool(&nf, Tpool_dl);
    nbDlProcessing--;
	pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1785

1786 1787
    //msgToPush->key=0;
    //pushTpool(Tpool, msgToPush);
Hongzhi Wang's avatar
Hongzhi Wang committed
1788

1789
  } // while !oai_exit
Hongzhi Wang's avatar
Hongzhi Wang committed
1790

Hongzhi Wang's avatar
Hongzhi Wang committed
1791
  return NULL;
Hongzhi Wang's avatar
Hongzhi Wang committed
1792 1793 1794
}

#endif