nr_dlsch_coding.c 20.1 KB
Newer Older
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 33 34 35 36 37
/*
 * 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/LTE_TRANSPORT/dlsch_coding.c
* \brief Top-level routines for implementing LDPC-coded (DLSCH) transport channels from 38-212, 15.2
* \author H.Wang
* \date 2018
* \version 0.1
* \company Eurecom
* \email:
* \note
* \warning
*/

#include "PHY/defs_gNB.h"
#include "PHY/phy_extern.h"
#include "PHY/CODING/coding_extern.h"
#include "PHY/CODING/coding_defs.h"
#include "PHY/CODING/lte_interleaver_inline.h"
38
#include "PHY/CODING/nrLDPC_extern.h"
cig's avatar
cig committed
39
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
40
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
41
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
42
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
43
#include "SCHED_NR/sched_nr.h"
44 45
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
46 47 48 49 50
#include <syscall.h>

//#define DEBUG_DLSCH_CODING
//#define DEBUG_DLSCH_FREE 1

51

cig's avatar
cig committed
52
void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB)
53 54 55 56
{
  int i;
  int r;

57
  NR_gNB_DLSCH_t *dlsch = *dlschptr;
58

59
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
60
  if (dlsch) {
61 62 63

    if (N_RB != 273) {
      a_segments = a_segments*N_RB;
64
      a_segments = a_segments/273 +1;
65 66 67 68
    }  



69
#ifdef DEBUG_DLSCH_FREE
70
    LOG_D(PHY,"Freeing dlsch %p\n",dlsch);
71 72 73 74
#endif

    for (i=0; i<dlsch->Mdlharq; i++) {
#ifdef DEBUG_DLSCH_FREE
75
      LOG_D(PHY,"Freeing dlsch process %d\n",i);
76 77 78 79
#endif

      if (dlsch->harq_processes[i]) {
#ifdef DEBUG_DLSCH_FREE
80
        LOG_D(PHY,"Freeing dlsch process %d (%p)\n",i,dlsch->harq_processes[i]);
81 82 83
#endif

        if (dlsch->harq_processes[i]->b) {
laurent's avatar
laurent committed
84
          free16(dlsch->harq_processes[i]->b,a_segments*1056);
85 86
          dlsch->harq_processes[i]->b = NULL;
#ifdef DEBUG_DLSCH_FREE
87
          LOG_D(PHY,"Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
88 89 90
#endif
        }

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
        if (dlsch->harq_processes[i]->e) {
          free16(dlsch->harq_processes[i]->e,14*N_RB*12*8);
          dlsch->harq_processes[i]->e = NULL;
#ifdef DEBUG_DLSCH_FREE
          printf("Freeing dlsch process %d e (%p)\n",i,dlsch->harq_processes[i]->e);
#endif
        }

        if (dlsch->harq_processes[i]->f) {
          free16(dlsch->harq_processes[i]->f,14*N_RB*12*8);
          dlsch->harq_processes[i]->f = NULL;
#ifdef DEBUG_DLSCH_FREE
          printf("Freeing dlsch process %d f (%p)\n",i,dlsch->harq_processes[i]->f);
#endif
        }

107
#ifdef DEBUG_DLSCH_FREE
108
        LOG_D(PHY,"Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c);
109 110
#endif

111
        for (r=0; r<a_segments; r++) {
112 113

#ifdef DEBUG_DLSCH_FREE
114
          LOG_D(PHY,"Freeing dlsch process %d c[%d] (%p)\n",i,r,dlsch->harq_processes[i]->c[r]);
115 116 117
#endif

          if (dlsch->harq_processes[i]->c[r]) {
118
            free16(dlsch->harq_processes[i]->c[r],1056);
119 120 121
            dlsch->harq_processes[i]->c[r] = NULL;
          }
          if (dlsch->harq_processes[i]->d[r]) {
122
            free16(dlsch->harq_processes[i]->d[r],3*8448);
123 124 125
            dlsch->harq_processes[i]->d[r] = NULL;
          }

yilmazt's avatar
yilmazt committed
126
	    }
127 128 129 130 131 132
	free16(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t));
	dlsch->harq_processes[i] = NULL;
      }
    }

    free16(dlsch,sizeof(NR_gNB_DLSCH_t));
cig's avatar
cig committed
133
    *dlschptr = NULL;
yilmazt's avatar
yilmazt committed
134
  }
135 136 137

}

138 139
NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
                              unsigned char Kmimo,
140 141
                              unsigned char Mdlharq,
                              uint32_t Nsoft,
142 143
                              uint8_t  abstraction_flag,
                              uint16_t N_RB)
144 145 146
{

  NR_gNB_DLSCH_t *dlsch;
147
  unsigned char exit_flag = 0,i,r,aa,layer;
148
  int re;
149
  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
150

151 152
  if (N_RB != 273) {
    a_segments = a_segments*N_RB;
153
    a_segments = a_segments/273 +1;
154
  }  
155

156
  uint16_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
157

158
  
159 160 161 162 163 164 165 166 167
  dlsch = (NR_gNB_DLSCH_t *)malloc16(sizeof(NR_gNB_DLSCH_t));

  if (dlsch) {
    bzero(dlsch,sizeof(NR_gNB_DLSCH_t));
    dlsch->Kmimo = Kmimo;
    dlsch->Mdlharq = Mdlharq;
    dlsch->Mlimit = 4;
    dlsch->Nsoft = Nsoft;

168
    for (layer=0; layer<NR_MAX_NB_LAYERS; layer++) {
169
      dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*));
170

171
      for (aa=0; aa<64; aa++) {
172 173 174 175
         dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
         for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
           dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
         }
176
      }
177

178
      dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH/NR_MAX_NB_LAYERS)*sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH
179
    }
180

181
    for (int q=0; q<NR_MAX_NB_CODEWORDS; q++)
182
      dlsch->mod_symbs[q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH*sizeof(int32_t));
183

184 185
     dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(64*sizeof(int32_t*));
     for (aa=0; aa<64; aa++) {
186 187 188 189
       dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));

     }

190 191 192 193
    for (i=0; i<20; i++) {
      dlsch->harq_ids[0][i] = 0;
      dlsch->harq_ids[1][i] = 0;
    }
Guy De Souza's avatar
Guy De Souza committed
194

195 196
    for (i=0; i<Mdlharq; i++) {
      dlsch->harq_processes[i] = (NR_DL_gNB_HARQ_t *)malloc16(sizeof(NR_DL_gNB_HARQ_t));
197 198
      LOG_T(PHY, "Required mem size %d  dlsch->harq_processes[%d] %p\n",
    		  dlsch_bytes, i,dlsch->harq_processes[i]);
199 200 201 202

      if (dlsch->harq_processes[i]) {
        bzero(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t));
        //    dlsch->harq_processes[i]->first_tx=1;
203 204
        dlsch->harq_processes[i]->b = (unsigned char*)malloc16(dlsch_bytes);
        dlsch->harq_processes[i]->pdu = (uint8_t*)malloc16(dlsch_bytes);
Guy De Souza's avatar
Guy De Souza committed
205
        if (dlsch->harq_processes[i]->pdu) {
206 207
          bzero(dlsch->harq_processes[i]->pdu,dlsch_bytes);
          nr_emulate_dlsch_payload(dlsch->harq_processes[i]->pdu, (dlsch_bytes)>>3);
Guy De Souza's avatar
Guy De Souza committed
208
        } else {
209
          LOG_D(PHY,"Can't allocate PDU\n");
Guy De Souza's avatar
Guy De Souza committed
210 211
          exit_flag=1;
        }
212 213

        if (dlsch->harq_processes[i]->b) {
214
          bzero(dlsch->harq_processes[i]->b,dlsch_bytes);
215
        } else {
216
          LOG_D(PHY,"Can't get b\n");
217 218 219 220
          exit_flag=1;
        }

        if (abstraction_flag==0) {
221
          for (r=0; r<a_segments; r++) {
222
            // account for filler in first segment and CRCs for multiple segment case
Ahmed's avatar
Ahmed committed
223 224 225
            // [hna] 8448 is the maximum CB size in NR
            //       68*348 = 68*(maximum size of Zc)
            //       In section 5.3.2 in 38.212, the for loop is up to N + 2*Zc (maximum size of N is 66*Zc, therefore 68*Zc)
226
            dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448);
227
            dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output
228 229 230
            if (dlsch->harq_processes[i]->c[r]) {
              bzero(dlsch->harq_processes[i]->c[r],8448);
            } else {
231
              LOG_D(PHY,"Can't get c\n");
232 233 234 235 236
              exit_flag=2;
            }
            if (dlsch->harq_processes[i]->d[r]) {
              bzero(dlsch->harq_processes[i]->d[r],(3*8448));
            } else {
237
              LOG_D(PHY,"Can't get d\n");
238 239 240
              exit_flag=2;
            }
          }
241 242 243 244 245 246 247 248 249 250 251 252 253 254
          dlsch->harq_processes[i]->e = (uint8_t*)malloc16(14*N_RB*12*8);
          if (dlsch->harq_processes[i]->e) {
            bzero(dlsch->harq_processes[i]->e,14*N_RB*12*8);
          } else {
            printf("Can't get e\n");
            exit_flag=1;
          }
          dlsch->harq_processes[i]->f = (uint8_t*)malloc16(14*N_RB*12*8);
          if (dlsch->harq_processes[i]->f) {
            bzero(dlsch->harq_processes[i]->f,14*N_RB*12*8);
          } else {
            printf("Can't get f\n");
            exit_flag=1;
          }
255 256
        }
      } else {
257
        LOG_D(PHY,"Can't get harq_p %d\n",i);
258 259 260 261 262 263 264 265 266 267 268 269 270
        exit_flag=3;
      }
    }

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

      return(dlsch);
    }
  }

271
  LOG_D(PHY,"new_gNB_dlsch exit flag %d, size of  %ld\n",
272
	exit_flag, sizeof(NR_gNB_DLSCH_t));
273

Francesco Mani's avatar
Francesco Mani committed
274
  free_gNB_dlsch(&dlsch,N_RB);
275

276
  return(NULL);
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291


}

void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
{

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

  if (dlsch) {
    Mdlharq = dlsch->Mdlharq;
    dlsch->rnti = 0;
    dlsch->active = 0;

292 293 294 295
    for (i=0; i<10; i++) {
      dlsch->harq_ids[0][i] = Mdlharq;
      dlsch->harq_ids[1][i] = Mdlharq;
    }
296 297 298
    for (i=0; i<Mdlharq; i++) {
      if (dlsch->harq_processes[i]) {
        //  dlsch->harq_processes[i]->Ndi    = 0;
299
        //dlsch->harq_processes[i]->status = 0;
300 301 302
        dlsch->harq_processes[i]->round  = 0;

	for (j=0; j<96; j++)
303
	  for (r=0; r<MAX_NUM_NR_DLSCH_SEGMENTS; r++)
304 305 306 307 308 309 310 311
	    if (dlsch->harq_processes[i]->d[r])
	      dlsch->harq_processes[i]->d[r][j] = NR_NULL;

      }
    }
  }
}

312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 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 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
int nr_processDLSegment(void* args) {

  ldpcEncode_t *rdata = (ldpcEncode_t*) args;
  NR_DL_gNB_HARQ_t *dlsch_harq = rdata->dlsch_harq;
  encoder_implemparams_t impp = rdata->impp;
  
  int F = dlsch_harq->F;
  int Kr = dlsch_harq->K;
  int Z = rdata->Z;
  int rvIndex = rdata->rvIndex;
  int G = rdata->G;
  int r_offset = rdata->r_offset;
  int BG = rdata->BG;
  int Kb = rdata->Kb;
  int nrOfLayers = rdata->nrOfLayers;
  int Ilbrm = rdata->Ilbrm;
  int Tbslbrm = rdata->Tbslbrm;
  int mod_order = rdata->mod_order;
  int j = impp.macro_num;
  int E;
  int r;

  nrLDPC_encoder(dlsch_harq->c,dlsch_harq->d,Z,Kb,Kr,BG,&impp);

  int maxSeg = ((j+1)*8 > dlsch_harq->C) ? dlsch_harq->C : (j+1)*8;

  for (r=j*8; r<maxSeg; r++) {
    if (F>0) {
      for (int k=(Kr-F-2*(Z)); k<Kr-2*(Z); k++) {
	// writing into positions d[r][k-2Zc] as in clause 5.3.2 step 2) in 38.212
        dlsch_harq->d[r][k] = NR_NULL;
      }
    }

#ifdef DEBUG_DLSCH_CODING
  LOG_D(PHY,"rvidx in encoding = %d\n", rvIndex);
#endif

    E = nr_get_E(G, dlsch_harq->C, mod_order, nrOfLayers, r);

    //#ifdef DEBUG_DLSCH_CODING
    LOG_D(PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d)...\n",
	  r,
	  dlsch_harq->C,
	  G,
	  E,
	  F,
	  Kr-F-2*(Z),
	  mod_order);

    nr_rate_matching_ldpc(Ilbrm,
                          Tbslbrm,
                          BG,
                          Z,
                          dlsch_harq->d[r],
                          dlsch_harq->e+r_offset,
                          dlsch_harq->C,
                          F,
                          Kr-F-2*(Z),
                          rvIndex,
                          E);
#ifdef DEBUG_DLSCH_CODING
    for (int i =0; i<16; i++)
      printf("output ratematching e[%d]= %d r_offset %u\n", i,dlsch_harq->e[i+r_offset], r_offset);
#endif

    nr_interleaving_ldpc(E,
			 mod_order,
			 dlsch_harq->e+r_offset,
			 dlsch_harq->f+r_offset);

#ifdef DEBUG_DLSCH_CODING
    for (int i =0; i<16; i++)
      printf("output interleaving f[%d]= %d r_offset %u\n", i,dlsch_harq->f[i+r_offset], r_offset);

    if (r==dlsch_harq->C-1)
      write_output("enc_output.m","enc",dlsch_harq->f,G,1,4);
#endif

  r_offset += E;

  }
394 395
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_OUT);

396 397
}

398 399
int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
                      unsigned char *a,
yilmazt's avatar
yilmazt committed
400 401 402
                      int frame,
                      uint8_t slot,
                      NR_gNB_DLSCH_t *dlsch,
403 404 405 406
                      NR_DL_FRAME_PARMS* frame_parms,
		      time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput,
		      time_stats_t *dlsch_rate_matching_stats,time_stats_t *dlsch_interleaving_stats,
		      time_stats_t *dlsch_segmentation_stats)
407 408 409 410
{

  unsigned int G;
  unsigned int crc=1;
411
  uint8_t harq_pid = dlsch->harq_ids[frame%2][slot];
412
  AssertFatal(harq_pid<8 && harq_pid>=0,"illegal harq_pid %d\b",harq_pid);
Raymond Knopp's avatar
Raymond Knopp committed
413
  nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15;
Raymond Knopp's avatar
Raymond Knopp committed
414 415
  uint16_t nb_rb = rel15->rbSize;
  uint8_t nb_symb_sch = rel15->NrOfSymbols;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
416 417
  uint32_t A, Kb, F=0;
  static uint32_t Z = 0;
Francesco Mani's avatar
Francesco Mani committed
418
  uint32_t *Zc = &Z;
Raymond Knopp's avatar
Raymond Knopp committed
419
  uint8_t mod_order = rel15->qamModOrder[0];
Francesco Mani's avatar
Francesco Mani committed
420 421
  uint16_t Kr=0,r;
  uint32_t r_offset=0;
422
  uint8_t BG=1;
423
  uint32_t E;
424
  uint8_t Ilbrm = 1;
425
  uint32_t Tbslbrm = 950984; //max tbs
426
  uint8_t nb_re_dmrs;
427 428 429

  if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1)
    nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData;
430
  else
431 432
    nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;

Raymond Knopp's avatar
Raymond Knopp committed
433 434
  uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
  uint16_t R=rel15->targetCodeRate[0];
435
  float Coderate = 0.0;
436
  uint8_t Nl = 4;
437

438 439
  dlsch->harq_processes[harq_pid]->round = nr_rv_round_map[rel15->rvIndex[0]];

Rakesh's avatar
Rakesh committed
440
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
441

Raymond Knopp's avatar
Raymond Knopp committed
442
  A = rel15->TBSize[0]<<3;
443

Raymond Knopp's avatar
Raymond Knopp committed
444
  G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers);
445

446
  LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order);
447 448 449 450

  //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
#ifdef DEBUG_DLSCH_CODING
451
  LOG_D(PHY,"encoding thinks this is a new packet \n");
452
#endif
453
  /*    
454
    int i;
455
    LOG_D(PHY,"dlsch (tx): \n");
456
    for (i=0;i<(A>>3);i++)
457
      LOG_D(PHY,"%02x\n",a[i]);
458
    LOG_D(PHY,"\n");
459
  */
460

461 462 463 464 465 466 467 468 469 470 471
    if (A > 3824) {
      // Add 24-bit crc (polynomial A) to payload
      crc = crc24a(a,A)>>8;
      a[A>>3] = ((uint8_t*)&crc)[2];
      a[1+(A>>3)] = ((uint8_t*)&crc)[1];
      a[2+(A>>3)] = ((uint8_t*)&crc)[0];
      //printf("CRC %x (A %d)\n",crc,A);
      //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
  
      dlsch->harq_processes[harq_pid]->B = A+24;
      //    dlsch->harq_processes[harq_pid]->b = a;
472
   
473
      AssertFatal((A/8)+4 <= MAX_NR_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_NR_DLSCH_PAYLOAD_BYTES);
474

475 476 477 478 479 480 481 482 483 484 485 486 487
      memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);  // why is this +4 if the CRC is only 3 bytes?
    }
    else {
      // Add 16-bit crc (polynomial A) to payload
      crc = crc16(a,A)>>16;
      a[A>>3] = ((uint8_t*)&crc)[1];
      a[1+(A>>3)] = ((uint8_t*)&crc)[0];
      //printf("CRC %x (A %d)\n",crc,A);
      //printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
  
      dlsch->harq_processes[harq_pid]->B = A+16;
      //    dlsch->harq_processes[harq_pid]->b = a;
   
488
      AssertFatal((A/8)+3 <= MAX_NR_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,MAX_NR_DLSCH_PAYLOAD_BYTES);
489

490 491
      memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+3);  // using 3 bytes to mimic the case of 24 bit crc
    }
492 493 494 495
    if (R<1000)
      Coderate = (float) R /(float) 1024;
    else  // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools
      Coderate = (float) R /(float) 2048;
496

497
    if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
498
		BG = 2;
499
    else
500
		BG = 1;
501

502
    start_meas(dlsch_segmentation_stats);
Francesco Mani's avatar
Francesco Mani committed
503 504 505 506 507 508 509 510
    Kb = nr_segmentation(dlsch->harq_processes[harq_pid]->b,
		         dlsch->harq_processes[harq_pid]->c,
		         dlsch->harq_processes[harq_pid]->B,
		         &dlsch->harq_processes[harq_pid]->C,
		         &dlsch->harq_processes[harq_pid]->K,
		         Zc, 
		         &dlsch->harq_processes[harq_pid]->F,
                         BG);
511
    stop_meas(dlsch_segmentation_stats);
512
    F = dlsch->harq_processes[harq_pid]->F;
513 514

    Kr = dlsch->harq_processes[harq_pid]->K;
515 516 517 518 519

    if (rel15->nrOfLayers < Nl)
      Nl = rel15->nrOfLayers;

    Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
520 521
#ifdef DEBUG_DLSCH_CODING
    uint16_t Kr_bytes;
522
    Kr_bytes = Kr>>3;
523
#endif
524
    gNB->nbEncode = 0;
525

Francesco Mani's avatar
Francesco Mani committed
526
    //printf("segment Z %d k %d Kr %d BG %d C %d\n", *Zc,dlsch->harq_processes[harq_pid]->K,Kr,BG,dlsch->harq_processes[harq_pid]->C);
527
    for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) {
528
      notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(ldpcEncode_t), 0, gNB->respEncode, nr_processDLSegment);
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
      ldpcEncode_t *rdata = (ldpcEncode_t *) NotifiedFifoData(req);

      rdata->impp.n_segments=dlsch->harq_processes[harq_pid]->C;
      rdata->impp.tprep = NULL;
      rdata->impp.tinput = NULL;
      rdata->impp.tparity = NULL;
      rdata->impp.toutput = NULL;
      rdata->impp.macro_num=j;
      rdata->Z = Z;
      rdata->rvIndex = rel15->rvIndex[0];
      rdata->dlsch_harq = dlsch->harq_processes[harq_pid];
      rdata->harq_pid = harq_pid;
      rdata->Ilbrm = Ilbrm;
      rdata->Tbslbrm = Tbslbrm;
      rdata->BG = BG;
      rdata->F = F;
      rdata->mod_order = mod_order;
      rdata->nrOfLayers = rel15->nrOfLayers;
      rdata->Kb = Kb;
548
      rdata->G = G;
549 550 551 552
      for (int cj=0; cj<j*8; cj++) {
        r_offset += nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15->nrOfLayers, r);
      }
      rdata->r_offset = r_offset;
553 554 555
      pushTpool(gNB->threadPool,req);
      gNB->nbEncode++;
      LOG_D(PHY,"Added a block to encode, in pipe: %d\n",gNB->nbEncode);
556
    }
557

558
  } else {
559 560 561
    F = dlsch->harq_processes[harq_pid]->F;

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

564
    if (F>0) {
Francesco Mani's avatar
Francesco Mani committed
565
      for (int k=(Kr-F-2*(*Zc)); k<Kr-2*(*Zc); k++) {
566
	// writing into positions d[r][k-2Zc] as in clause 5.3.2 step 2) in 38.212
567 568 569 570 571 572
        dlsch->harq_processes[harq_pid]->d[r][k] = NR_NULL;
	//if (k<(Kr-F+8))
	//printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]);
      }
    }

573

574 575

#ifdef DEBUG_DLSCH_CODING
Raymond Knopp's avatar
Raymond Knopp committed
576
  LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]);
577 578
#endif

Raymond Knopp's avatar
Raymond Knopp committed
579
    E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15->nrOfLayers, r);
580

581 582 583 584 585 586 587 588 589
    //#ifdef DEBUG_DLSCH_CODING
    LOG_D(PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n",
	  r,
	  dlsch->harq_processes[harq_pid]->C,
	  G,
	  E,
	  F,
	  Kr-F-2*(*Zc),
	  mod_order,nb_rb);
590

591
    // for tbslbrm calculation according to 5.4.2.1 of 38.212
Raymond Knopp's avatar
Raymond Knopp committed
592 593
    if (rel15->nrOfLayers < Nl)
      Nl = rel15->nrOfLayers;
594

Raymond Knopp's avatar
Raymond Knopp committed
595
    Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
596

597 598 599
    nr_rate_matching_ldpc(Ilbrm,
                          Tbslbrm,
                          BG,
Francesco Mani's avatar
Francesco Mani committed
600
                          *Zc,
601 602 603
                          dlsch->harq_processes[harq_pid]->d[r],
                          dlsch->harq_processes[harq_pid]->e+r_offset,
                          dlsch->harq_processes[harq_pid]->C,
604 605
                          F,
                          Kr-F-2*(*Zc),
Raymond Knopp's avatar
Raymond Knopp committed
606
                          rel15->rvIndex[0],
607
                          E);
608 609
#ifdef DEBUG_DLSCH_CODING
    for (int i =0; i<16; i++)
610
      printf("output ratematching e[%d]= %d r_offset %u\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset);
611
#endif
612

613 614 615 616
    nr_interleaving_ldpc(E,
			 mod_order,
			 dlsch->harq_processes[harq_pid]->e+r_offset,
			 dlsch->harq_processes[harq_pid]->f+r_offset);
617

618 619
#ifdef DEBUG_DLSCH_CODING
    for (int i =0; i<16; i++)
620
      printf("output interleaving f[%d]= %d r_offset %u\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset);
621 622

    if (r==dlsch->harq_processes[harq_pid]->C-1)
623
      write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->f,G,1,4);
624
#endif
625

626 627
      r_offset += E;
    }
628
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
629 630
  }

Khalid Ahmed's avatar
Khalid Ahmed committed
631
  return 0;
632
}