nr_dlsch_decoding.c 56.7 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
#include "PHY/defs_nr_UE.h"
Sakthivel Velumani's avatar
Sakthivel Velumani committed
35
#include "SCHED_NR_UE/harq_nr.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
36 37 38 39
#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"
40
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
41
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
42
#include "SCHED_NR_UE/defs.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
43
#include "SIMULATION/TOOLS/sim.h"
laurent's avatar
laurent committed
44
#include "executables/nr-uesoftmodem.h"
45
#include "PHY/CODING/nrLDPC_extern.h"
cig's avatar
cig committed
46
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
47
//#define DEBUG_DLSCH_DECODING
48
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
Hongzhi Wang's avatar
Hongzhi Wang committed
49

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

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

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

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

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

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

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

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) {
laurent's avatar
laurent committed
78
          free16(dlsch->harq_processes[i]->b,a_segments*1056);
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
    free16(dlsch,sizeof(NR_UE_DLSCH_t));
    dlsch = NULL;
  }
}

116
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
117 118 119 120 121
{

  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

  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;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
137
    dlsch->number_harq_processes_for_pdsch = Mdlharq;
Hongzhi Wang's avatar
Hongzhi Wang committed
138
    dlsch->Nsoft = Nsoft;
139
    dlsch->Mlimit = 4;
Hongzhi Wang's avatar
Hongzhi Wang committed
140
    dlsch->max_ldpc_iterations = max_ldpc_iterations;
141
 
Hongzhi Wang's avatar
Hongzhi Wang committed
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));
Sakthivel Velumani's avatar
Sakthivel Velumani committed
148
        init_downlink_harq_status(dlsch->harq_processes[i]);
Hongzhi Wang's avatar
Hongzhi Wang committed
149
        dlsch->harq_processes[i]->first_tx=1;
150
        dlsch->harq_processes[i]->b = (uint8_t*)malloc16(dlsch_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
151 152

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

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

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

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

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

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

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

  return(NULL);
}

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

}

220
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
221 222 223 224 225 226 227 228 229 230
			   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
231 232 233 234 235 236 237 238 239 240
{

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

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

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

268
  uint8_t dmrs_Type = harq_process->dmrsConfigType;
269
  AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
270 271 272 273 274 275 276
  uint8_t nb_re_dmrs;
  if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) {
    nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
  }
  else {
    nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
  }
277
  uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
Raymond Knopp's avatar
Raymond Knopp committed
278
  AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length);
Hongzhi Wang's avatar
Hongzhi Wang committed
279 280 281 282 283

  uint32_t i,j;

  __m128i *pv = (__m128i*)&z;
  __m128i *pl = (__m128i*)&l;
Hongzhi Wang's avatar
Hongzhi Wang committed
284 285
  
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
286
  
287 288
  //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0];

Ahmed's avatar
Ahmed committed
289
  if (!dlsch_llr) {
Hongzhi Wang's avatar
Hongzhi Wang committed
290
    printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
291
    return(dlsch->max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
292 293 294 295
  }

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

299
  /*if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) {
Hongzhi Wang's avatar
Hongzhi Wang committed
300
    printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx);
301
    return(dlsch->max_ldpc_iterations + 1);
302
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
303

304
  /*if (harq_process->harq_ack.ack != 2) {
Hongzhi Wang's avatar
Hongzhi Wang committed
305 306
    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);
307
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
308 309 310 311 312 313

  //  nb_rb = dlsch->nb_rb;

  /*
  if (nb_rb > frame_parms->N_RB_DL) {
    printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
314
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
315 316 317 318 319
    }*/

  /*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);
320
    return(max_ldpc_iterations + 1);
Hongzhi Wang's avatar
Hongzhi Wang committed
321 322 323
  }
  */

324 325
  nb_rb = harq_process->nb_rb;

Hongzhi Wang's avatar
Hongzhi Wang committed
326 327
  harq_process->trials[harq_process->round]++;

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

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

Hongzhi Wang's avatar
Hongzhi Wang committed
332
  A = harq_process->TBS;
333
  ret = dlsch->max_ldpc_iterations + 1;
334
  dlsch->last_iteration_cnt = ret;
335
 
Raymond Knopp's avatar
Raymond Knopp committed
336
  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
337 338
  G = harq_process->G;

339
  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
340

Francesco Mani's avatar
Francesco Mani committed
341
  if ((harq_process->R)<1024)
342 343 344
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
345

Ahmed's avatar
Ahmed committed
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
  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;
    }
  }

378 379 380

  if (harq_process->round == 0) {
    // This is a new packet, so compute quantities regarding segmentation
381 382 383 384 385
	if (A > 3824)
	  harq_process->B = A+24;
	else
	  harq_process->B = A+16;

386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
    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
401
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
402 403 404 405

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

Ahmed's avatar
Ahmed committed
406 407 408 409
  //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
410 411 412 413

  err_flag = 0;
  r_offset = 0;

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

Francesco Mani's avatar
Francesco Mani committed
416 417
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
418
    a_segments = a_segments/273 +1;
419
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
420

421 422
  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
423 424
    return((1+dlsch->max_ldpc_iterations));
  }
Ahmed's avatar
Ahmed committed
425

Hongzhi Wang's avatar
Hongzhi Wang committed
426
#ifdef DEBUG_DLSCH_DECODING
427
  printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
Hongzhi Wang's avatar
Hongzhi Wang committed
428 429 430 431
#endif

  opp_enabled=1;

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

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

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

439
    //printf("start rx segment %d\n",r);
440 441 442 443 444
    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
445

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

448

449 450
    nr_deinterleaving_ldpc(E,
                           harq_process->Qm,
Ahmed's avatar
Ahmed committed
451
                           harq_process->w[r], // [hna] w is e
452 453
                           dlsch_llr+r_offset);

Hongzhi Wang's avatar
Hongzhi Wang committed
454
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
455

456
    //for (int i =0; i<16; i++)
Ahmed's avatar
Ahmed committed
457
    //          printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
458 459 460 461

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif
462

Hongzhi Wang's avatar
Hongzhi Wang committed
463 464 465 466
#if UE_TIMING_TRACE
    start_meas(dlsch_rate_unmatching_stats);
#endif

467 468
    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
469 470 471 472 473 474 475
          Kr*3,
          harq_process->TBS,
          harq_process->Qm,
          harq_process->nb_rb,
          harq_process->Nl,
          harq_process->rvidx,
          harq_process->round);
476

Hongzhi Wang's avatar
Hongzhi Wang committed
477

Hongzhi Wang's avatar
Hongzhi Wang committed
478
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
479

480
    if ((harq_process->Nl)<4)
Sakthivel Velumani's avatar
Sakthivel Velumani committed
481
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
482
    else
Sakthivel Velumani's avatar
Sakthivel Velumani committed
483
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
484

485

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

Hongzhi Wang's avatar
Hongzhi Wang committed
506 507 508 509 510
#if UE_TIMING_TRACE
      stop_meas(dlsch_rate_unmatching_stats);
#endif
    }

511

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

515
    r_offset += E;
516

Hongzhi Wang's avatar
Hongzhi Wang committed
517 518
#ifdef DEBUG_DLSCH_DECODING
    if (r==0) {
Ahmed's avatar
Ahmed committed
519
      write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
520
      write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0);
Hongzhi Wang's avatar
Hongzhi Wang committed
521 522
    }

523
    printf("decoder input(segment %u) :",r);
Ahmed's avatar
Ahmed committed
524
    int i;
525
    for (i=0;i<E;i++)
Hongzhi Wang's avatar
Hongzhi Wang committed
526
      printf("%d : %d\n",i,harq_process->d[r][i]);
Ahmed's avatar
Ahmed committed
527
    printf("\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
528 529 530 531 532 533
#endif

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

    //    printf("done\n");
534
    if (harq_process->C == 1){
535 536 537 538 539 540 541
    	if (A > 3824) 
    		crc_type = CRC24_A;
    	else
    		crc_type = CRC16;
    	
	length_dec = harq_process->B;

542 543
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
544
      crc_type = CRC24_B;
545 546
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
547 548 549 550

    if (err_flag == 0) {

#if UE_TIMING_TRACE
Ahmed's avatar
Ahmed committed
551
      start_meas(dlsch_turbo_decoding_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
552 553
#endif

554
      //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
555

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

Ahmed's avatar
Ahmed committed
558 559 560
      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
561

562

Ahmed's avatar
Ahmed committed
563 564 565 566
      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]));
      }
567 568 569 570
      // 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
571 572 573 574 575 576 577 578 579
      {
        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
580

Hongzhi Wang's avatar
Hongzhi Wang committed
581
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
582

Ahmed's avatar
Ahmed committed
583 584 585
      no_iteration_ldpc = nrLDPC_decoder(p_decParams,
                           (int8_t*)&pl[0],
                           llrProcBuf,
586
                           p_nrLDPC_procBuf[r],
587
                           p_procTime);
Hongzhi Wang's avatar
Hongzhi Wang committed
588
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
589

Ahmed's avatar
Ahmed committed
590 591
      // 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)) {
592
        LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
593 594 595
	if (r==0)
	  for (int i=0;i<10;i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t*)llrProcBuf)[i]);

596 597
        //Temporary hack
        no_iteration_ldpc = dlsch->max_ldpc_iterations;
598
        ret = no_iteration_ldpc;
Ahmed's avatar
Ahmed committed
599 600
      }
      else {
601
        LOG_D(PHY,"CRC NOK\n\033[0m");
602
        ret = 1 + dlsch->max_ldpc_iterations;
Ahmed's avatar
Ahmed committed
603 604
      }

605

Ahmed's avatar
Ahmed committed
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
      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
621

622
#ifdef DEBUG_DLSCH_DECODING
hongzhi wang's avatar
hongzhi wang committed
623
      //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
624
      for (int k=0;k<A>>3;k++)
Ahmed's avatar
Ahmed committed
625
        printf("output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
626
      printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
627
      //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
628
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
629 630 631 632 633 634


#if UE_TIMING_TRACE
      stop_meas(dlsch_turbo_decoding_stats);
#endif
    }
635 636
    
    
Hongzhi Wang's avatar
Hongzhi Wang committed
637 638 639 640 641 642 643 644 645 646

    /*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;
647
      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
648 649 650 651 652 653 654 655 656 657 658 659 660
      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) {
661
//#if UE_DEBUG_TRACE
662
    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
663
        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);
664
//#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
665 666 667 668 669
    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]++;

670
    //    printf("Rate: [UE %d] DLSCH: Setting NACK for slot %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round);
671
    if (harq_process->round >= dlsch->Mlimit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
672 673 674
      harq_process->status = SCH_IDLE;
      harq_process->round  = 0;
    }
675

Hongzhi Wang's avatar
Hongzhi Wang committed
676 677
    if(is_crnti)
    {
678
    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
679 680 681
               phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
    }

682
    return((1 + dlsch->max_ldpc_iterations));
Hongzhi Wang's avatar
Hongzhi Wang committed
683
  } else {
684
//#if UE_DEBUG_TRACE
685
    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",
686
	  phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
687
//#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
688 689 690 691 692 693

    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;
694
    
695
    //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
696 697 698 699
      //  phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);

    if(is_crnti)
    {
700
    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
701 702 703 704 705 706 707
    }
    //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
708 709
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
Hongzhi Wang's avatar
Hongzhi Wang committed
710 711 712 713 714 715

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

Hongzhi Wang's avatar
Hongzhi Wang committed
717
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN);
718

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

Hongzhi Wang's avatar
Hongzhi Wang committed
721
    memcpy(harq_process->b+offset,
722 723
	   harq_process->c[r],
	   Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
Hongzhi Wang's avatar
Hongzhi Wang committed
724 725 726
    offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));

#ifdef DEBUG_DLSCH_DECODING
727
    printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
Hongzhi Wang's avatar
Hongzhi Wang committed
728 729 730 731 732 733
    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]);
734 735 736 737 738

              /*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
739
#endif
740 741

#if defined(ENABLE_PHY_PAYLOAD_DEBUG)
742
           if (frame%100 == 0){
743
              LOG_I (PHY, "Printing 10 first payload bytes at frame: %d ", frame);
744
              for (int i = 0; i <10 ; i++){ //Kr_bytes
745
            	  LOG_I(PHY, "[%d] : %x ", i, harq_process->b[i]);
746 747
              }
          }
Hongzhi Wang's avatar
Hongzhi Wang committed
748 749
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
750 751
  }

Hongzhi Wang's avatar
Hongzhi Wang committed
752
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT);
753

Hongzhi Wang's avatar
Hongzhi Wang committed
754 755 756 757 758 759
  dlsch->last_iteration_cnt = ret;

  return(ret);
}

#ifdef UE_DLSCH_PARALLELISATION
760
uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
Ahmed's avatar
Ahmed committed
761 762 763 764 765 766 767 768 769 770 771 772
                                    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
773 774 775 776 777 778 779 780 781 782
{

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

816 817 818 819 820 821
  uint8_t nb_re_dmrs;
  if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
    nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
  else
    nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;

Raymond Knopp's avatar
Raymond Knopp committed
822
  uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos); 
Hongzhi Wang's avatar
Hongzhi Wang committed
823

824
  uint32_t i,j;
Hongzhi Wang's avatar
Hongzhi Wang committed
825
//  int nbDlProcessing =0;
Hongzhi Wang's avatar
Hongzhi Wang committed
826

827 828 829 830
  __m128i *pv = (__m128i*)&z;
  __m128i *pl = (__m128i*)&l;
  notifiedFIFO_t nf;
  initNotifiedFIFO(&nf);
Hongzhi Wang's avatar
Hongzhi Wang committed
831

Hongzhi Wang's avatar
Hongzhi Wang committed
832
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
Hongzhi Wang's avatar
Hongzhi Wang committed
833 834 835 836 837 838

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

839

Hongzhi Wang's avatar
Hongzhi Wang committed
840 841 842 843 844 845

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

846
 /* if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) {
Hongzhi Wang's avatar
Hongzhi Wang committed
847 848 849 850 851 852 853
    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);
854
  }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
855 856 857 858 859 860 861 862 863 864 865 866 867 868

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

869
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
870 871
  harq_process->trials[harq_process->round]++;

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

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

876
  A = harq_process->TBS;
Hongzhi Wang's avatar
Hongzhi Wang committed
877

Hongzhi Wang's avatar
Hongzhi Wang committed
878 879
  ret = dlsch->max_ldpc_iterations + 1;
  dlsch->last_iteration_cnt = ret;
Hongzhi Wang's avatar
Hongzhi Wang committed
880

881
  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
882 883 884

  G = harq_process->G;

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

Hongzhi Wang's avatar
Hongzhi Wang committed
887 888 889 890 891 892 893
  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
894
  if ((harq_process->R)<1024)
895 896 897
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
898

899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
  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
930

931 932
  if (harq_process->round == 0) {
      // This is a new packet, so compute quantities regarding segmentation
933 934 935 936 937
	  if (A > 3824)
	  	  harq_process->B = A+24;
	  else
	  	  harq_process->B = A+16;

938 939 940 941 942 943 944 945 946 947 948
      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
949 950
    
    p_decParams->Z = harq_process->Z;
951

952 953 954
  //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
955 956 957 958

  err_flag = 0;
  r_offset = 0;

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

Francesco Mani's avatar
Francesco Mani committed
961 962
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
963
    a_segments = a_segments/273 +1;
964
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
965

966 967
  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
968 969 970
    return((1+dlsch->max_ldpc_iterations));
  }
#ifdef DEBUG_DLSCH_DECODING
971
  printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
Hongzhi Wang's avatar
Hongzhi Wang committed
972 973
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
974
  notifiedFIFO_elt_t *res_dl;
Hongzhi Wang's avatar
Hongzhi Wang committed
975
  opp_enabled=1;
976 977
  if (harq_process->C>1) {
	for (int nb_seg =1 ; nb_seg<harq_process->C; nb_seg++){
Hongzhi Wang's avatar
Hongzhi Wang committed
978 979
	  if ( (res_dl=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
	          pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
980 981
	        }

Hongzhi Wang's avatar
Hongzhi Wang committed
982 983
	  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);
984
	  curMsg->UE=phy_vars_ue;
Hongzhi Wang's avatar
Hongzhi Wang committed
985 986 987
	  
	  nbDlProcessing++;

988 989 990 991 992 993 994 995 996 997

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

Ahmed's avatar
Ahmed committed
1001 1002 1003 1004
  /*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
1005

Ahmed's avatar
Ahmed committed
1006 1007
    Gp = G/Nl/Qm;
    GpmodC = Gp%C;
Hongzhi Wang's avatar
Hongzhi Wang committed
1008 1009


Ahmed's avatar
Ahmed committed
1010 1011 1012 1013 1014
    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
1015

Ahmed's avatar
Ahmed committed
1016
    printf("mthread instance_cnt_dlsch_td %d\n",  proc->instance_cnt_dlsch_td);*/
1017
	  }
Ahmed's avatar
Ahmed committed
1018 1019 1020 1021 1022
  //proc->decoder_main_available = 1;
  }

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

1024
    Kr = harq_process->K;
Hongzhi Wang's avatar
Hongzhi Wang committed
1025
    Kr_bytes = Kr>>3;
1026
    K_bytes_F = Kr_bytes-(harq_process->F>>3);
Hongzhi Wang's avatar
Hongzhi Wang committed
1027

1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
    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++)
1045
              printf("rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
1046 1047 1048 1049 1050 1051
#endif

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
#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

1068 1069 1070 1071
    // for tbslbrm calculation according to 5.4.2.1 of 38.212
    if (harq_process->Nl < Nl)
      Nl = harq_process->Nl;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
1072
    Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
1073

1074
    if (nr_rate_matching_ldpc_rx(Ilbrm,
1075 1076 1077 1078 1079 1080 1081 1082
                                 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,
1083 1084 1085
                                 E,
				 harq_process->F,
				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
#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
    }
1097 1098

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

1101
    //r_offset += E;
Hongzhi Wang's avatar
Hongzhi Wang committed
1102
    //printf("main thread r_offset %d\n",r_offset);
1103 1104 1105
 
#ifdef DEBUG_DLSCH_DECODING   
    for (int i =0; i<16; i++)
1106
      printf("rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset);
1107
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1108 1109

#ifdef DEBUG_DLSCH_DECODING
1110

Hongzhi Wang's avatar
Hongzhi Wang committed
1111
    if (r==0) {
Ahmed's avatar
Ahmed committed
1112 1113
      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
1114 1115
    }

1116
    printf("decoder input(segment %u) :",r);
1117 1118
    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
1119
    printf("\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
1120 1121 1122 1123 1124 1125 1126
#endif


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

    //    printf("done\n");
1127
    if (harq_process->C == 1){
1128 1129 1130 1131 1132
      if (A > 3824)
    	crc_type = CRC24_A;
      else
    	crc_type = CRC16;

1133 1134 1135
      length_dec = harq_process->B;
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
1136
      crc_type = CRC24_B;
1137 1138
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1139 1140

    //#ifndef __AVX2__
1141

Hongzhi Wang's avatar
Hongzhi Wang committed
1142 1143
    if (err_flag == 0) {
/*
1144
        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
1145 1146 1147
                            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);
*/
1148

Hongzhi Wang's avatar
Hongzhi Wang committed
1149
#if UE_TIMING_TRACE
Ahmed's avatar
Ahmed committed
1150
      start_meas(dlsch_turbo_decoding_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
1151
#endif
1152
      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
1153

1154
      /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
Ahmed's avatar
Ahmed committed
1155
        inv_d[cnt] = (1)*harq_process->d[r][cnt];
1156
      }*/
Ahmed's avatar
Ahmed committed
1157 1158 1159 1160 1161 1162

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


1163
      for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++)
Ahmed's avatar
Ahmed committed
1164
      {
1165
        pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
Ahmed's avatar
Ahmed committed
1166 1167
      }

Hongzhi Wang's avatar
Hongzhi Wang committed
1168 1169 1170
      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
1171
      {
1172
        pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
Ahmed's avatar
Ahmed committed
1173
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1174
      
Ahmed's avatar
Ahmed committed
1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194
      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;
      }

1195
      if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
1196
        printf("Segment %u CRC OK\n",r);
Ahmed's avatar
Ahmed committed
1197 1198 1199 1200 1201 1202 1203
        ret = 2;
      }
      else {
        printf("CRC NOK\n");
        ret = 1+dlsch->max_ldpc_iterations;
      }

Hongzhi Wang's avatar
Hongzhi Wang committed
1204 1205 1206
    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
1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231

    //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]);
1232
#ifdef DEBUG_DLSCH_DECODING
Ahmed's avatar
Ahmed committed
1233 1234
      for (int k=0;k<32;k++)
        printf("output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
1235
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246

#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;
    }
1247
  //} //loop r
Hongzhi Wang's avatar
Hongzhi Wang committed
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258

  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
1259
    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
1260 1261
        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
1262 1263 1264
    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
1265 1266 1267 1268 1269
    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);
1270
    if (harq_process->round >= dlsch->Mlimit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1271 1272 1273 1274 1275 1276
      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",
1277
               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
1278 1279 1280 1281 1282
    }

    return((1+dlsch->max_ldpc_iterations));
  } else {
#if UE_DEBUG_TRACE
1283
      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
1284 1285 1286 1287 1288
           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;
1289 1290 1291
    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
1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310
    //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
1311 1312 1313
  //uint32_t wait = 0;
  
  /* while((proc->decoder_thread_available == 0) )
Hongzhi Wang's avatar
Hongzhi Wang committed
1314 1315 1316
  {
          usleep(1);
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
1317
  proc->decoder_thread_available == 0;*/
1318 1319 1320 1321 1322 1323 1324

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

  proc->decoder_main_available = 0;
1329 1330
  Kr = harq_process->K; //to check if same K in all segments
  Kr_bytes = Kr>>3;
Hongzhi Wang's avatar
Hongzhi Wang committed
1331 1332 1333
  
  for (r=0; r<harq_process->C; r++) {

Ahmed's avatar
Ahmed committed
1334 1335 1336 1337
      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));
1338 1339

#ifdef DEBUG_DLSCH_DECODING
1340
      printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
Ahmed's avatar
Ahmed committed
1341 1342 1343 1344 1345 1346
      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]);
1347
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1348
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
1349 1350
  
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
1351 1352 1353 1354 1355 1356 1357 1358 1359 1360

  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
1361
void nr_dlsch_decoding_process(void *arg)
Hongzhi Wang's avatar
Hongzhi Wang committed
1362
{
1363 1364 1365
	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;
1366
    NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
Hongzhi Wang's avatar
Hongzhi Wang committed
1367
    int llr8_flag1;
1368
    int32_t no_iteration_ldpc,length_dec;
Hongzhi Wang's avatar
Hongzhi Wang committed
1369 1370 1371 1372
    t_nrLDPC_dec_params decParams;
    t_nrLDPC_dec_params* p_decParams = &decParams;
    t_nrLDPC_time_stats procTime;
    t_nrLDPC_time_stats* p_procTime =&procTime ;
1373
    int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
1374
    t_nrLDPC_procBuf* p_nrLDPC_procBuf; 
Hongzhi Wang's avatar
Hongzhi Wang committed
1375 1376 1377
    int16_t z [68*384];
    int8_t l [68*384];
    //__m128i l;
Hongzhi Wang's avatar
Hongzhi Wang committed
1378 1379
    //int16_t inv_d [68*384];
    //int16_t *p_invd =&inv_d;
1380
    uint8_t kb, kc;
1381
    uint8_t Ilbrm = 1;
1382 1383
    uint32_t Tbslbrm = 950984;
    uint16_t nb_rb = 30; //to update
1384
    double Coderate = 0.0;
1385 1386 1387
    uint16_t nb_symb_sch = 12;
    uint8_t nb_re_dmrs = 6;
    uint16_t length_dmrs = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1388 1389 1390 1391 1392 1393 1394 1395

    uint32_t i,j;
    uint32_t k;

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

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

1398
    proc->decoder_thread_available = 1;
Hongzhi Wang's avatar
Hongzhi Wang committed
1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
    

#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;
1409
  uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bytes_F;
Hongzhi Wang's avatar
Hongzhi Wang committed
1410
  uint8_t crc_type;
1411 1412 1413 1414
  uint8_t C,Cprime;
  uint8_t Qm;
  uint8_t Nl;
  //uint32_t Er;
Hongzhi Wang's avatar
Hongzhi Wang committed
1415

1416 1417 1418 1419
  int eNB_id                = proc->eNB_id;
  int harq_pid              = proc->harq_pid;
  llr8_flag1                = proc->llr8_flag;
  int frame                 = proc->frame_rx;
1420 1421
  int slot                  = proc->nr_tti_rx;
  r               	    = proc->num_seg;
Ahmed's avatar
Ahmed committed
1422

1423 1424 1425 1426 1427 1428
  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;
1429
  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
1430

Hongzhi Wang's avatar
Hongzhi Wang committed
1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444

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

1445
  nb_rb = harq_process->nb_rb;
Hongzhi Wang's avatar
Hongzhi Wang committed
1446 1447 1448

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

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

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

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

1455

Hongzhi Wang's avatar
Hongzhi Wang committed
1456 1457
  ret = dlsch->max_ldpc_iterations;

1458
  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
1459
  G = harq_process->G;
1460

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

Francesco Mani's avatar
Francesco Mani committed
1463
  if ((harq_process->R)<1024)
1464 1465 1466
    Coderate = (float) (harq_process->R) /(float) 1024;
  else
    Coderate = (float) (harq_process->R) /(float) 2048;
Hongzhi Wang's avatar
Hongzhi Wang committed
1467

1468 1469 1470 1471 1472 1473 1474 1475
  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
1476
      p_decParams->R = 13;
1477
      kc = 32;
Ahmed's avatar
Ahmed committed
1478
    }
1479 1480 1481 1482 1483 1484 1485 1486
    else {
      p_decParams->R = 23;
      kc = 17;
    }
  }
  else{
    p_decParams->BG = 1;
    if (Coderate < 0.6667){
Ahmed's avatar
Ahmed committed
1487
      p_decParams->R = 13;
1488 1489 1490 1491 1492 1493 1494 1495 1496 1497
      kc = 68;
    }
    else if (Coderate <0.8889){
      p_decParams->R = 23;
      kc = 35;
    }
    else {
      p_decParams->R = 89;
      kc = 27;
    }
1498 1499
  }    

Hongzhi Wang's avatar
Hongzhi Wang committed
1500
  harq_process->round  =0;
magounak's avatar
magounak committed
1501
 // if (harq_process->round == 0) {
1502
    // This is a new packet, so compute quantities regarding segmentation
1503 1504 1505 1506
	if (A > 3824)
	  harq_process->B = A+24;
	else
	  harq_process->B = A+16;
1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518

    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
1519
   // }
Hongzhi Wang's avatar
Hongzhi Wang committed
1520 1521
    
    //printf("round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
1522

1523

1524
  p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
1525
  p_decParams->outMode= 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536

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

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

Francesco Mani's avatar
Francesco Mani committed
1539 1540
  if (nb_rb != 273) {
    a_segments = a_segments*nb_rb;
1541
    a_segments = a_segments/273 +1;
1542
  }  
Hongzhi Wang's avatar
Hongzhi Wang committed
1543

1544 1545
  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
1546 1547 1548 1549 1550 1551 1552 1553 1554
    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;
1555 1556 1557
  Nl=harq_process->Nl;
  //r_thread = harq_process->C/2-1;
  C= harq_process->C;
Hongzhi Wang's avatar
Hongzhi Wang committed
1558

1559
  Cprime = C; //assume CBGTI not present
Hongzhi Wang's avatar
Hongzhi Wang committed
1560

1561
  if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
Ahmed's avatar
Ahmed committed
1562
    r_offset = Nl*Qm*(G/(Nl*Qm*Cprime));
1563
  else
Ahmed's avatar
Ahmed committed
1564
    r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
Hongzhi Wang's avatar
Hongzhi Wang committed
1565

Ahmed's avatar
Ahmed committed
1566 1567
    //  printf("thread0 r_offset %d\n",r_offset);
           
Hongzhi Wang's avatar
Hongzhi Wang committed
1568
  //for (r=(harq_process->C/2); r<harq_process->C; r++) {
1569
     //    r=1; //(harq_process->C/2);
Hongzhi Wang's avatar
Hongzhi Wang committed
1570

1571
  r_offset = r*r_offset;
Hongzhi Wang's avatar
Hongzhi Wang committed
1572

1573 1574 1575
  Kr = harq_process->K;
  Kr_bytes = Kr>>3;
  K_bytes_F = Kr_bytes-(harq_process->F>>3);
Hongzhi Wang's avatar
Hongzhi Wang committed
1576

1577
  E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
1578 1579 1580 1581 1582 1583 1584 1585 1586

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

1587 1588
#ifdef DEBUG_DLSCH_DECODING
    for (int i =0; i<16; i++)
1589
              printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
1590
#endif
1591 1592 1593 1594 1595

#if UE_TIMING_TRACE
    stop_meas(dlsch_deinterleaving_stats);
#endif

Hongzhi Wang's avatar
Hongzhi Wang committed
1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611
#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

1612
    if (Nl<4)
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1613
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl);
1614
    else
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1615
      Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
1616

1617
    if (nr_rate_matching_ldpc_rx(Ilbrm,
1618 1619 1620 1621 1622 1623 1624 1625
                                 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,
1626 1627 1628
                                 E,
				 harq_process->F,
				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640
#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
    }

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

1644
    //r_offset += E;
1645

1646
#ifdef DEBUG_DLSCH_DECODING
Hongzhi Wang's avatar
Hongzhi Wang committed
1647 1648
    if (r==0) {
              write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
1649
              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
1650 1651
    }

1652
    printf("decoder input(segment %u) :",r);
Hongzhi Wang's avatar
Hongzhi Wang committed
1653
    int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
1654 1655
      printf("%d : %d\n",i,harq_process->d[r][i]);
      printf("\n");
Hongzhi Wang's avatar
Hongzhi Wang committed
1656 1657 1658 1659 1660 1661
#endif


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

1662
    if (harq_process->C == 1){
1663 1664 1665 1666 1667
    	if (A > 3824)
    	 	crc_type = CRC24_A;
    	else
    		crc_type = CRC16;

1668 1669 1670
      length_dec = harq_process->B;
    }
    else{
Hongzhi Wang's avatar
Hongzhi Wang committed
1671
      crc_type = CRC24_B;
1672 1673
      length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1674 1675 1676

    if (err_flag == 0) {
/*
1677
        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
1678 1679 1680
                            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
1681 1682 1683 1684
      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
1685 1686 1687 1688
#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);
1689
/*
1690 1691 1692
        for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
              inv_d[cnt] = (1)*harq_process->d[r][cnt];
              }
1693
*/
Hongzhi Wang's avatar
Hongzhi Wang committed
1694

1695 1696 1697
        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
1698

1699
        for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++)
Ahmed's avatar
Ahmed committed
1700
        {
1701
          pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
Ahmed's avatar
Ahmed committed
1702
        }
1703

Hongzhi Wang's avatar
Hongzhi Wang committed
1704 1705 1706
        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++)
1707
        {
Hongzhi Wang's avatar
Hongzhi Wang committed
1708
         pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
1709
        }
1710

1711 1712 1713 1714
        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
1715

1716
        no_iteration_ldpc = nrLDPC_decoder(p_decParams,
1717 1718 1719 1720
                                           (int8_t*)&pl[0],
                                           llrProcBuf,
                                           p_nrLDPC_procBuf,
                                           p_procTime);
Hongzhi Wang's avatar
Hongzhi Wang committed
1721

1722 1723
        // 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)) {
1724
          LOG_D(PHY,"Segment %u CRC OK\n",r);
1725 1726 1727
          ret = 2;
        }
        else {
1728
          LOG_D(PHY,"Segment %u CRC NOK\n",r);
1729 1730 1731
          ret = 1+dlsch->max_ldpc_iterations;
        }

Ahmed's avatar
Ahmed committed
1732
    if (no_iteration_ldpc > 10)
1733
      LOG_D(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
Ahmed's avatar
Ahmed committed
1734 1735
    //else
      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);
Hongzhi Wang's avatar
Hongzhi Wang committed
1736

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

Ahmed's avatar
Ahmed committed
1742 1743 1744 1745
            /*for (int u=0; u < Kr>>3; u ++)
                            {
                      ullrProcBuf[u]= (uint8_t) llrProcBuf[u];
                            }
Hongzhi Wang's avatar
Hongzhi Wang committed
1746 1747


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

Ahmed's avatar
Ahmed committed
1750 1751
            for (int j=0; j < Kr>>3; j ++)
                                    {
Hongzhi Wang's avatar
Hongzhi Wang committed
1752

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

Ahmed's avatar
Ahmed committed
1755 1756 1757 1758 1759
                                    }
          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]);
1760
#endif 
Ahmed's avatar
Ahmed committed
1761
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772
#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;
    }
  //}

1773 1774 1775
  proc->decoder_thread_available = 1;
  //proc->decoder_main_available = 0;
}
Hongzhi Wang's avatar
Hongzhi Wang committed
1776

1777 1778 1779 1780 1781
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
1782 1783
  notifiedFIFO_elt_t *res_dl;
  initNotifiedFIFO_nothreadSafe(&freeBlocks_dl);
Hongzhi Wang's avatar
Hongzhi Wang committed
1784

Hongzhi Wang's avatar
Hongzhi Wang committed
1785
  for (int i=0; i<RX_NB_TH_DL+1; i++){
Hongzhi Wang's avatar
Hongzhi Wang committed
1786
    pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,
Hongzhi Wang's avatar
Hongzhi Wang committed
1787
                                  newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), 0,&nf,nr_dlsch_decoding_process));}
Hongzhi Wang's avatar
Hongzhi Wang committed
1788

1789
  while (!oai_exit) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1790

1791
    notifiedFIFO_elt_t *res;
Hongzhi Wang's avatar
Hongzhi Wang committed
1792

1793
    while (nbDlProcessing >= RX_NB_TH_DL) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1794
      if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
1795
        nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData;
Hongzhi Wang's avatar
Hongzhi Wang committed
1796 1797
        //nbDlProcessing--;
        pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res);
1798
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
1799

1800
      usleep(200);
Hongzhi Wang's avatar
Hongzhi Wang committed
1801
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
1802 1803 1804 1805 1806
    
    res_dl=pullTpool(&nf, Tpool_dl);
    nbDlProcessing--;
	pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
    
Hongzhi Wang's avatar
Hongzhi Wang committed
1807

1808 1809
    //msgToPush->key=0;
    //pushTpool(Tpool, msgToPush);
Hongzhi Wang's avatar
Hongzhi Wang committed
1810

1811
  } // while !oai_exit
Hongzhi Wang's avatar
Hongzhi Wang committed
1812

Hongzhi Wang's avatar
Hongzhi Wang committed
1813
  return NULL;
Hongzhi Wang's avatar
Hongzhi Wang committed
1814 1815 1816
}

#endif