diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 4df0cc51e17d48bf400a22596d8a75b151be9135..fdd70ee79bc06b203d6a16d4971c54eec5ac506d 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1275,6 +1275,8 @@ set(PHY_SRC_UE
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
+  ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c
+  ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
@@ -1292,6 +1294,8 @@ set(PHY_SRC_UE
   ${OPENAIR1_DIR}/PHY/TOOLS/time_meas.c
   ${OPENAIR1_DIR}/PHY/TOOLS/lut.c
   ${OPENAIR1_DIR}/PHY/INIT/nr_init_ue.c
+  ${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c
+  #${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_common_ue.c
   )
 
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
new file mode 100755
index 0000000000000000000000000000000000000000..fd079b9f7bd74a7ee4850a6ffd7002c29c1ac01b
--- /dev/null
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -0,0 +1,6438 @@
+/*
+ * 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.1  (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/dci_nr.c
+ * \brief Implements PDCCH physical channel TX/RX procedures (36.211) and DCI encoding/decoding (36.212/36.213). Current LTE compliance V8.6 2009-03.
+ * \author R. Knopp, A. Mico Pereperez
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+#ifdef USER_MODE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+//#include "PHY/defs.h"
+#include "PHY/defs_nr_UE.h"
+//#include "PHY/extern.h"
+//#include "SCHED/defs.h"
+//#include "SIMULATION/TOOLS/defs.h" // for taus 
+#include "PHY/sse_intrin.h"
+
+#include "assertions.h" 
+#include "T.h"
+
+//#define DEBUG_DCI_ENCODING 1
+//#define DEBUG_DCI_DECODING 1
+//#define DEBUG_PHY
+
+//#define NR_LTE_PDCCH_DCI_SWITCH
+#define NR_PDCCH_DCI_RUN              // activates new nr functions
+#define NR_PDCCH_DCI_DEBUG            // activates NR_PDCCH_DCI_DEBUG logs
+#define NR_NBR_CORESET_ACT_BWP 3      // The number of CoreSets per BWP is limited to 3 (including initial CORESET: ControlResourceId 0)
+#define NR_NBR_SEARCHSPACE_ACT_BWP 10 // The number of SearSpaces per BWP is limited to 10 (including initial SEARCHSPACE: SearchSpaceId 0)
+
+//#undef ALL_AGGREGATION
+
+//extern uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3];
+//extern uint16_t pcfich_reg[4];
+
+/*uint32_t check_phich_reg(NR_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi)
+{
+
+  uint16_t i;
+  uint16_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
+  uint16_t mprime;
+  uint16_t *pcfich_reg = frame_parms->pcfich_reg;
+
+  if ((lprime>0) && (frame_parms->Ncp==0) )
+    return(0);
+
+  //  printf("check_phich_reg : mi %d\n",mi);
+
+  // compute REG based on symbol
+  if ((lprime == 0)||
+      ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)))
+    mprime = kprime/6;
+  else
+    mprime = kprime>>2;
+
+  // check if PCFICH uses mprime
+  if ((lprime==0) &&
+      ((mprime == pcfich_reg[0]) ||
+       (mprime == pcfich_reg[1]) ||
+       (mprime == pcfich_reg[2]) ||
+       (mprime == pcfich_reg[3]))) {
+#ifdef DEBUG_DCI_ENCODING
+    printf("[PHY] REG %d allocated to PCFICH\n",mprime);
+#endif
+    return(1);
+  }
+
+  // handle Special subframe case for TDD !!!
+
+  //  printf("Checking phich_reg %d\n",mprime);
+  if (mi > 0) {
+    if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
+      Ngroup_PHICH++;
+
+    if (frame_parms->Ncp == 1) {
+      Ngroup_PHICH<<=1;
+    }
+
+
+
+    for (i=0; i<Ngroup_PHICH; i++) {
+      if ((mprime == frame_parms->phich_reg[i][0]) ||
+          (mprime == frame_parms->phich_reg[i][1]) ||
+          (mprime == frame_parms->phich_reg[i][2]))  {
+#ifdef DEBUG_DCI_ENCODING
+        printf("[PHY] REG %d (lprime %d) allocated to PHICH\n",mprime,lprime);
+#endif
+        return(1);
+      }
+    }
+  }
+
+  return(0);
+}*/
+
+uint16_t extract_crc(uint8_t *dci,uint8_t dci_len)
+{
+
+  uint16_t crc16;
+  //  uint8_t i;
+
+  /*
+  uint8_t crc;
+  crc = ((uint16_t *)dci)[DCI_LENGTH>>4];
+  printf("crc1: %x, shift %d (DCI_LENGTH %d)\n",crc,DCI_LENGTH&0xf,DCI_LENGTH);
+  crc = (crc>>(DCI_LENGTH&0xf));
+  // clear crc bits
+  ((uint16_t *)dci)[DCI_LENGTH>>4] &= (0xffff>>(16-(DCI_LENGTH&0xf)));
+  printf("crc2: %x, dci0 %x\n",crc,((int16_t *)dci)[DCI_LENGTH>>4]);
+  crc |= (((uint16_t *)dci)[1+(DCI_LENGTH>>4)])<<(16-(DCI_LENGTH&0xf));
+  // clear crc bits
+  (((uint16_t *)dci)[1+(DCI_LENGTH>>4)]) = 0;
+  printf("extract_crc: crc %x\n",crc);
+  */
+#ifdef DEBUG_DCI_DECODING
+  LOG_I(PHY,"dci_crc (%x,%x,%x), dci_len&0x7=%d\n",dci[dci_len>>3],dci[1+(dci_len>>3)],dci[2+(dci_len>>3)],
+      dci_len&0x7);
+#endif
+
+  if ((dci_len&0x7) > 0) {
+    ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)]<<(dci_len&0x7) | dci[2+(dci_len>>3)]>>(8-(dci_len&0x7));
+    ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)]<<(dci_len&0x7) | dci[1+(dci_len>>3)]>>(8-(dci_len&0x7));
+  } else {
+    ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)];
+    ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)];
+  }
+
+#ifdef DEBUG_DCI_DECODING
+  LOG_I(PHY,"dci_crc =>%x\n",crc16);
+#endif
+
+  //  dci[(dci_len>>3)]&=(0xffff<<(dci_len&0xf));
+  //  dci[(dci_len>>3)+1] = 0;
+  //  dci[(dci_len>>3)+2] = 0;
+  return((uint16_t)crc16);
+  
+}
+
+
+
+static uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96];
+static uint8_t w[3*3*(MAX_DCI_SIZE_BITS+16)];
+
+void dci_encoding(uint8_t *a,
+                  uint8_t A,
+                  uint16_t E,
+                  uint8_t *e,
+                  uint16_t rnti)
+{
+
+
+  uint8_t D = (A + 16);
+  uint32_t RCC;
+
+#ifdef DEBUG_DCI_ENCODING
+  int32_t i;
+#endif
+  // encode dci
+
+#ifdef DEBUG_DCI_ENCODING
+  printf("Doing DCI encoding for %d bits, e %p, rnti %x\n",A,e,rnti);
+#endif
+
+  memset((void *)d,LTE_NULL,96);
+
+  ccodelte_encode(A,2,a,d+96,rnti);
+
+#ifdef DEBUG_DCI_ENCODING
+
+  for (i=0; i<16+A; i++)
+    printf("%d : (%d,%d,%d)\n",i,*(d+96+(3*i)),*(d+97+(3*i)),*(d+98+(3*i)));
+
+#endif
+
+#ifdef DEBUG_DCI_ENCODING
+  printf("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e);
+#endif
+  RCC = sub_block_interleaving_cc(D,d+96,w);
+
+#ifdef DEBUG_DCI_ENCODING
+  printf("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e);
+#endif
+  lte_rate_matching_cc(RCC,E,w,e);
+
+
+}
+
+
+uint8_t *generate_dci0(uint8_t *dci,
+                       uint8_t *e,
+                       uint8_t DCI_LENGTH,
+                       uint8_t aggregation_level,
+                       uint16_t rnti)
+{
+
+  uint16_t coded_bits;
+  uint8_t dci_flip[8];
+
+  if (aggregation_level>3) {
+    printf("dci.c: generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level);
+    return NULL;
+  }
+
+  coded_bits = 72 * (1<<aggregation_level);
+
+  /*
+
+  #ifdef DEBUG_DCI_ENCODING
+  for (i=0;i<1+((DCI_LENGTH+16)/8);i++)
+    printf("i %d : %x\n",i,dci[i]);
+  #endif
+  */
+  if (DCI_LENGTH<=32) {
+    dci_flip[0] = dci[3];
+    dci_flip[1] = dci[2];
+    dci_flip[2] = dci[1];
+    dci_flip[3] = dci[0];
+  } else {
+    dci_flip[0] = dci[7];
+    dci_flip[1] = dci[6];
+    dci_flip[2] = dci[5];
+    dci_flip[3] = dci[4];
+    dci_flip[4] = dci[3];
+    dci_flip[5] = dci[2];
+    dci_flip[6] = dci[1];
+    dci_flip[7] = dci[0];
+#ifdef DEBUG_DCI_ENCODING
+    printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
+        dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3],
+        dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]);
+#endif
+  }
+
+  dci_encoding(dci_flip,DCI_LENGTH,coded_bits,e,rnti);
+
+  return(e+coded_bits);
+}
+
+uint32_t Y;
+
+#define CCEBITS 72
+#define CCEPERSYMBOL 33  // This is for 1200 RE
+#define CCEPERSYMBOL0 22  // This is for 1200 RE
+#define DCI_BITS_MAX ((2*CCEPERSYMBOL+CCEPERSYMBOL0)*CCEBITS)
+#define Msymb (DCI_BITS_MAX/2)
+//#define Mquad (Msymb/4)
+
+static uint32_t bitrev_cc_dci[32] = {1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31,0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30};
+static int32_t wtemp[2][Msymb];
+
+void pdcch_interleaving(NR_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi)
+{
+
+  int32_t *wptr,*wptr2,*zptr;
+  uint32_t Mquad = get_nquad(n_symbols_pdcch,frame_parms,mi);
+  uint32_t RCC = (Mquad>>5), ND;
+  uint32_t row,col,Kpi,index;
+  int32_t i,k,a;
+#ifdef RM_DEBUG
+  int32_t nulled=0;
+#endif
+
+  //  printf("[PHY] PDCCH Interleaving Mquad %d (Nsymb %d)\n",Mquad,n_symbols_pdcch);
+  if ((Mquad&0x1f) > 0)
+    RCC++;
+
+  Kpi = (RCC<<5);
+  ND = Kpi - Mquad;
+
+  k=0;
+
+  for (col=0; col<32; col++) {
+    index = bitrev_cc_dci[col];
+
+    for (row=0; row<RCC; row++) {
+      //printf("col %d, index %d, row %d\n",col,index,row);
+      if (index>=ND) {
+        for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) {
+          //printf("a %d k %d\n",a,k);
+
+          wptr = &wtemp[a][k<<2];
+          zptr = &z[a][(index-ND)<<2];
+
+          //printf("wptr=%p, zptr=%p\n",wptr,zptr);
+
+          wptr[0] = zptr[0];
+          wptr[1] = zptr[1];
+          wptr[2] = zptr[2];
+          wptr[3] = zptr[3];
+        }
+
+        k++;
+      }
+
+      index+=32;
+    }
+  }
+
+  // permutation
+  for (i=0; i<Mquad; i++) {
+
+    for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) {
+
+      //wptr  = &wtemp[a][i<<2];
+      //wptr2 = &wbar[a][((i+frame_parms->Nid_cell)%Mquad)<<2];
+      wptr = &wtemp[a][((i+frame_parms->Nid_cell)%Mquad)<<2];
+      wptr2 = &wbar[a][i<<2];
+      wptr2[0] = wptr[0];
+      wptr2[1] = wptr[1];
+      wptr2[2] = wptr[2];
+      wptr2[3] = wptr[3];
+    }
+  }
+}
+
+
+
+#ifdef NR_PDCCH_DCI_RUN
+void nr_pdcch_demapping(uint16_t *llr, uint16_t *wbar,
+           NR_DL_FRAME_PARMS *frame_parms,
+           uint8_t coreset_time_dur, uint32_t coreset_nbr_rb) {
+/*
+ * LLR contains the PDCCH for the coreset_time_dur symbols in the following sequence:
+ * 
+ * The REGs have to be numbered in increasing order in a time-first manner,
+ * starting with 0 for the first OFDM symbol and the lowest-numbered resource
+ * block in the control resource set
+ *
+ * |   ...    |    ...    |   ...    |
+ * |  REG 3   |   REG 4   |  REG 5   |
+ * |  REG 0   |   REG 1   |  REG 2   |
+ * | symbol0  |  symbol1  | symbol2  |
+ *
+ * .................
+ * ___________REG 1+2l
+ * ___________REG 1+l
+ * symbol 1___REG 1
+ * .................
+ * ___________REG 2l
+ * ___________REG l
+ * symbol 0___REG 0
+ *
+ * WBAR will contain the PDCCH organized in REGx where x will be consecutive:
+ * REG 0
+ * REG 1
+ * REG 2
+ * ...
+ * REG l
+ * REG 1+l
+ * REG 2+l
+ * ...
+ *
+ */
+
+  uint32_t m,i,k,l;
+  uint32_t num_re_pdcch = 12 * coreset_nbr_rb;
+  i=0;
+  m=0;
+  for (k=0; k<num_re_pdcch; k++) {
+    for (l=0; l < coreset_time_dur ; l++) {
+      if ((k%12==1)||(k%12==5)||(k%12==9)){
+        #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping)-> k,l=(%d,%d) DM-RS PDCCH signal\n",k,l);
+        #endif
+      } else {
+        if ((m%9)==0 && (m !=0) && (l==0)) {
+          #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping)-> we have modified m: old_m=%d, new_m=%d\n",
+                  m,m+(9*(coreset_time_dur-1)));
+          #endif
+          m=m+(9*(coreset_time_dur-1)); // to avoid overwriting m+1 when a whole REG has been completed
+        }
+        wbar[(l*9)+m] = llr[(l*9*coreset_nbr_rb)+i];
+        #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping)-> k,l=(%d,%d) i,m=(%d,%d) REG (%d) > wbar(%d,%d) \t llr[%d]->wbar[%d]\n",
+                k,l,i,m, (m+(l*9)) / 9, *(char*) &wbar[m+(l*9)], *(1 + (char*) &wbar[m+(l*9)]),
+                (l*9*coreset_nbr_rb)+i,m+(l*9));
+        #endif
+        if (l==coreset_time_dur-1) {
+          i++;
+          m++;
+        }
+      }
+    }
+  }
+}
+#endif
+
+
+void pdcch_demapping(uint16_t *llr,uint16_t *wbar,NR_DL_FRAME_PARMS *frame_parms,uint8_t num_pdcch_symbols,uint8_t mi)
+{
+
+  uint32_t i, lprime;
+  uint16_t kprime,kprime_mod12,mprime,symbol_offset,tti_offset,tti_offset0;
+  int16_t re_offset,re_offset0;
+
+  // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5
+
+  int Msymb2;
+
+  switch (frame_parms->N_RB_DL) {
+  case 100:
+    Msymb2 = Msymb;
+    break;
+
+  case 75:
+    Msymb2 = 3*Msymb/4;
+    break;
+
+  case 50:
+    Msymb2 = Msymb>>1;
+    break;
+
+  case 25:
+    Msymb2 = Msymb>>2;
+    break;
+
+  case 15:
+    Msymb2 = Msymb*15/100;
+    break;
+
+  case 6:
+    Msymb2 = Msymb*6/100;
+    break;
+
+  default:
+    Msymb2 = Msymb>>2;
+    break;
+  }
+
+  mprime=0;
+
+
+  re_offset = 0;
+  re_offset0 = 0; // counter for symbol with pilots (extracted outside!)
+
+  for (kprime=0; kprime<frame_parms->N_RB_DL*12; kprime++) {
+    for (lprime=0; lprime<num_pdcch_symbols; lprime++) {
+
+      symbol_offset = (uint32_t)frame_parms->N_RB_DL*12*lprime;
+
+      tti_offset = symbol_offset + re_offset;
+      tti_offset0 = symbol_offset + re_offset0;
+
+      // if REG is allocated to PHICH, skip it
+      if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) {
+	//        printf("dci_demapping : skipping REG %d (RE %d)\n",(lprime==0)?kprime/6 : kprime>>2,kprime);
+	if ((lprime == 0)&&((kprime%6)==0))
+	  re_offset0+=4;
+      } else { // not allocated to PHICH/PCFICH
+	//        printf("dci_demapping: REG %d\n",(lprime==0)?kprime/6 : kprime>>2);
+        if (lprime == 0) {
+          // first symbol, or second symbol+4 TX antennas skip pilots
+          kprime_mod12 = kprime%12;
+
+          if ((kprime_mod12 == 0) || (kprime_mod12 == 6)) {
+            // kprime represents REG
+
+            for (i=0; i<4; i++) {
+              wbar[mprime] = llr[tti_offset0+i];
+#ifdef DEBUG_DCI_DECODING
+//              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset0+i,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
+#endif
+              mprime++;
+              re_offset0++;
+            }
+          }
+        } else if ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)) {
+          // LATER!!!!
+        } else { // no pilots in this symbol
+          kprime_mod12 = kprime%12;
+
+          if ((kprime_mod12 == 0) || (kprime_mod12 == 4) || (kprime_mod12 == 8)) {
+            // kprime represents REG
+            for (i=0; i<4; i++) {
+              wbar[mprime] = llr[tti_offset+i];
+#ifdef DEBUG_DCI_DECODING
+//              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset+i,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
+#endif
+              mprime++;
+            }
+          }  // is representative
+        } // no pilots case
+      } // not allocated to PHICH/PCFICH
+
+      // Stop when all REGs are copied in
+      if (mprime>=Msymb2)
+        break;
+    } //lprime loop
+
+    re_offset++;
+
+  } // kprime loop
+}
+
+static uint16_t wtemp_rx[Msymb];
+
+
+#ifdef NR_PDCCH_DCI_RUN
+void nr_pdcch_deinterleaving(NR_DL_FRAME_PARMS *frame_parms, uint16_t *z,
+          uint16_t *wbar, uint8_t coreset_time_dur, uint8_t reg_bundle_size_L,
+          uint8_t coreset_interleaver_size_R, uint8_t n_shift, uint32_t coreset_nbr_rb)
+{
+/*
+ * This function will perform deinterleaving described in 38.211 Section 7.3.2.2
+ * coreset_freq_dom (bit map 45 bits: each bit indicates 6 RB in CORESET -> 1 bit MSB indicates PRB 0..6 are part of CORESET)
+ * coreset_time_dur (1,2,3)
+ * coreset_CCE_REG_mapping_type (interleaved, non-interleaved)
+ * reg_bundle_size (2,3,6)
+ */
+#ifdef NR_PDCCH_DCI_DEBUG
+  printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_deinterleaving)-> coreset_nbr_rb=(%lld), reg_bundle_size_L=(%d)\n",
+		  coreset_nbr_rb,reg_bundle_size_L);
+#endif
+/*
+ * First verify that CORESET is interleaved or not interleaved depending on parameter cce-REG-MappingType
+ * To be done
+ * if non-interleaved then do nothing: wbar table stays as it is
+ * if interleaved then do this: wbar table has bundles interleaved. We have to de-interleave then
+ * following procedure described in 38.211 Section 7.3.2.2:
+  */
+  int coreset_interleaved = 1;
+  uint32_t bundle_id, bundle_interleaved, c=0 ,r=-1, k, l, i=0;
+  uint32_t coreset_C = (uint32_t)(coreset_nbr_rb / (coreset_interleaver_size_R*reg_bundle_size_L));
+  uint16_t *wptr;
+  wptr = &wtemp_rx[0];
+  z = &wtemp_rx[0];
+  bundle_id=0;
+  for (k=0 ; k<9*coreset_nbr_rb*coreset_time_dur; k++){
+#ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_deinterleaving)-> k=%d \t coreset_interleaved=%d reg_bundle_size_L=%d coreset_C=%d coreset_interleaver_R=%d",
+           k,coreset_interleaved,reg_bundle_size_L, coreset_C,coreset_interleaver_size_R);
+#endif
+    if (k%(9*reg_bundle_size_L)==0) {
+      // calculate offset properly
+      if (r==coreset_interleaver_size_R-1) {
+      //if (bundle_id>=(c+1)*coreset_interleaver_size_R) {
+        c++;
+        r=0;
+      } else{
+        r++;
+      }
+#ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t --> time to modify bundle_interleaved and bundle_id --> r=%d c=%d",r,c);
+#endif
+      bundle_id=c*coreset_interleaver_size_R+r;
+      bundle_interleaved=(r*coreset_C+c+n_shift)%(coreset_nbr_rb * coreset_time_dur/reg_bundle_size_L);
+    }
+    if (coreset_interleaved == 1){
+      //wptr[i+(bundle_interleaved-bundle_id)*9*reg_bundle_size_L]=wbar[i];
+#ifdef NR_PDCCH_DCI_DEBUG
+      printf("\n\t\t\t\t\t\t\t\t\t wptr[%d] <-> wbar[%d]",i,i+(bundle_interleaved-bundle_id)*9*reg_bundle_size_L);
+#endif
+      wptr[i]=wbar[i+(bundle_interleaved-bundle_id)*9*reg_bundle_size_L];
+#ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t\t bundle_id = %d \t bundle_interleaved = %d\n",bundle_id,bundle_interleaved);
+#endif
+      i++;
+    } else {
+      wptr[i]=wbar[i];
+      i++;
+    }
+    //bundle_id=c*coreset_interleaver_size_R+r;
+  }
+}
+#endif
+
+
+
+
+
+
+
+void pdcch_deinterleaving(NR_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t *wbar,uint8_t number_pdcch_symbols,uint8_t mi)
+{
+
+  uint16_t *wptr,*zptr,*wptr2;
+
+  uint16_t Mquad=get_nquad(number_pdcch_symbols,frame_parms,mi);
+  uint32_t RCC = (Mquad>>5), ND;
+  uint32_t row,col,Kpi,index;
+  int32_t i,k;
+
+
+  //  printf("Mquad %d, RCC %d\n",Mquad,RCC);
+
+  if (!z) {
+    printf("dci.c: pdcch_deinterleaving: FATAL z is Null\n");
+    return;
+  }
+
+  // undo permutation
+  for (i=0; i<Mquad; i++) {
+    wptr = &wtemp_rx[((i+frame_parms->Nid_cell)%Mquad)<<2];
+    wptr2 = &wbar[i<<2];
+
+    wptr[0] = wptr2[0];
+    wptr[1] = wptr2[1];
+    wptr[2] = wptr2[2];
+    wptr[3] = wptr2[3];
+    /*    
+    printf("pdcch_deinterleaving (%p,%p): quad %d (%d) -> (%d,%d %d,%d %d,%d %d,%d)\n",wptr,wptr2,i,(i+frame_parms->Nid_cell)%Mquad,
+	   ((char*)wptr2)[0],
+	   ((char*)wptr2)[1],
+	   ((char*)wptr2)[2],
+	   ((char*)wptr2)[3],
+	   ((char*)wptr2)[4],
+	   ((char*)wptr2)[5],
+	   ((char*)wptr2)[6],
+	   ((char*)wptr2)[7]);
+    */
+
+  }
+
+  if ((Mquad&0x1f) > 0)
+    RCC++;
+
+  Kpi = (RCC<<5);
+  ND = Kpi - Mquad;
+
+  k=0;
+
+  for (col=0; col<32; col++) {
+    index = bitrev_cc_dci[col];
+
+    for (row=0; row<RCC; row++) {
+      //      printf("row %d, index %d, Nd %d\n",row,index,ND);
+      if (index>=ND) {
+
+
+
+        wptr = &wtemp_rx[k<<2];
+        zptr = &z[(index-ND)<<2];
+
+        zptr[0] = wptr[0];
+        zptr[1] = wptr[1];
+        zptr[2] = wptr[2];
+        zptr[3] = wptr[3];
+
+	/*        
+        printf("deinterleaving ; k %d, index-Nd %d  => (%d,%d,%d,%d,%d,%d,%d,%d)\n",k,(index-ND),
+               ((int8_t *)wptr)[0],
+               ((int8_t *)wptr)[1],
+               ((int8_t *)wptr)[2],
+               ((int8_t *)wptr)[3],
+               ((int8_t *)wptr)[4],
+               ((int8_t *)wptr)[5],
+               ((int8_t *)wptr)[6],
+               ((int8_t *)wptr)[7]);
+	*/
+        k++;
+      }
+
+      index+=32;
+
+    }
+  }
+
+  for (i=0; i<Mquad; i++) {
+    zptr = &z[i<<2];
+    /*    
+    printf("deinterleaving ; quad %d  => (%d,%d,%d,%d,%d,%d,%d,%d)\n",i,
+     ((int8_t *)zptr)[0],
+     ((int8_t *)zptr)[1],
+     ((int8_t *)zptr)[2],
+     ((int8_t *)zptr)[3],
+     ((int8_t *)zptr)[4],
+     ((int8_t *)zptr)[5],
+     ((int8_t *)zptr)[6],
+     ((int8_t *)zptr)[7]);
+    */  
+  }
+
+}
+
+
+int32_t pdcch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
+                            int32_t **rxdataF_comp,
+                            int32_t **rxdataF_comp_i,
+                            int32_t **rho_i,
+                            int16_t *pdcch_llr16,
+                            int16_t *pdcch_llr8in,
+                            uint8_t symbol)
+{
+
+  int16_t *rxF=(int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
+  int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)];
+  int16_t *rho=(int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
+  int16_t *llr128;
+  int32_t i;
+  char *pdcch_llr8;
+  int16_t *pdcch_llr;
+  pdcch_llr8 = (char *)&pdcch_llr8in[symbol*frame_parms->N_RB_DL*12];
+  pdcch_llr = &pdcch_llr16[symbol*frame_parms->N_RB_DL*12];
+
+  //  printf("dlsch_qpsk_qpsk: symbol %d\n",symbol);
+
+  llr128 = (int16_t*)pdcch_llr;
+
+  if (!llr128) {
+    printf("dlsch_qpsk_qpsk_llr: llr is null, symbol %d\n",symbol);
+    return -1;
+  }
+
+  qpsk_qpsk(rxF,
+            rxF_i,
+            llr128,
+            rho,
+            frame_parms->N_RB_DL*12);
+
+  //prepare for Viterbi which accepts 8 bit, but prefers 4 bit, soft input.
+  for (i=0; i<(frame_parms->N_RB_DL*24); i++) {
+    if (*pdcch_llr>7)
+      *pdcch_llr8=7;
+    else if (*pdcch_llr<-8)
+      *pdcch_llr8=-8;
+    else
+      *pdcch_llr8 = (char)(*pdcch_llr);
+
+    pdcch_llr++;
+    pdcch_llr8++;
+  }
+
+  return(0);
+}
+
+
+#ifdef NR_PDCCH_DCI_RUN
+int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp,
+		char *pdcch_llr, uint8_t symbol,uint32_t coreset_nbr_rb) {
+
+	int16_t *rxF = (int16_t*) &rxdataF_comp[0][(symbol * frame_parms->N_RB_DL * 12)];
+	int32_t i;
+	char *pdcch_llr8;
+
+	pdcch_llr8 = &pdcch_llr[2 * symbol * frame_parms->N_RB_DL * 12];
+
+	if (!pdcch_llr8) {
+		printf("pdcch_qpsk_llr: llr is null, symbol %d\n", symbol);
+		return (-1);
+	}
+#ifdef NR_PDCCH_DCI_DEBUG
+	printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_llr)-> llr logs: pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llr8-pdcch_llr);
+#endif
+	//for (i = 0; i < (frame_parms->N_RB_DL * ((symbol == 0) ? 16 : 24)); i++) {
+	for (i = 0; i < (coreset_nbr_rb * ((symbol == 0) ? 18 : 18)); i++) {
+
+		if (*rxF > 31)
+			*pdcch_llr8 = 31;
+		else if (*rxF < -32)
+			*pdcch_llr8 = -32;
+		else
+			*pdcch_llr8 = (char) (*rxF);
+#ifdef NR_PDCCH_DCI_DEBUG
+		    printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_llr)-> llr logs: i=%d *rxF:%d => *pdcch_llr8:%d\n",i/18,i,*rxF,*pdcch_llr8);
+#endif
+		rxF++;
+		pdcch_llr8++;
+	}
+
+	return (0);
+
+}
+#endif
+
+
+
+int32_t pdcch_llr(NR_DL_FRAME_PARMS *frame_parms,
+                  int32_t **rxdataF_comp,
+                  char *pdcch_llr,
+                  uint8_t symbol)
+{
+
+  int16_t *rxF= (int16_t*) &rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
+  int32_t i;
+  char *pdcch_llr8;
+
+  pdcch_llr8 = &pdcch_llr[2*symbol*frame_parms->N_RB_DL*12];
+
+  if (!pdcch_llr8) {
+    printf("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol);
+    return(-1);
+  }
+
+  //    printf("pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llr8-pdcch_llr);
+
+  for (i=0; i<(frame_parms->N_RB_DL*((symbol==0) ? 16 : 24)); i++) {
+
+    if (*rxF>31)
+      *pdcch_llr8=31;
+    else if (*rxF<-32)
+      *pdcch_llr8=-32;
+    else
+      *pdcch_llr8 = (char)(*rxF);
+
+    //    printf("%d %d => %d\n",i,*rxF,*pdcch_llr8);
+    rxF++;
+    pdcch_llr8++;
+  }
+
+  return(0);
+
+}
+
+//__m128i avg128P;
+
+//compute average channel_level on each (TX,RX) antenna pair
+void pdcch_channel_level(int32_t **dl_ch_estimates_ext,
+                         NR_DL_FRAME_PARMS *frame_parms,
+                         int32_t *avg,
+                         uint8_t nb_rb)
+{
+
+  int16_t rb;
+  uint8_t aatx,aarx;
+#if defined(__x86_64__) || defined(__i386__)
+  __m128i *dl_ch128;
+  __m128i avg128P;
+#elif defined(__arm__)
+  int16x8_t *dl_ch128;
+  int32x4_t *avg128P;
+#endif
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
+    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+      //clear average level
+#if defined(__x86_64__) || defined(__i386__)
+      avg128P = _mm_setzero_si128();
+      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][0];
+#elif defined(__arm__)
+
+#endif
+      for (rb=0; rb<nb_rb; rb++) {
+
+#if defined(__x86_64__) || defined(__i386__)
+        avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
+        avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
+        avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
+#elif defined(__arm__)
+
+#endif
+        dl_ch128+=3;
+        /*
+          if (rb==0) {
+          print_shorts("dl_ch128",&dl_ch128[0]);
+          print_shorts("dl_ch128",&dl_ch128[1]);
+          print_shorts("dl_ch128",&dl_ch128[2]);
+          }
+        */
+      }
+
+      DevAssert( nb_rb );
+      avg[(aatx<<1)+aarx] = (((int32_t*)&avg128P)[0] +
+                             ((int32_t*)&avg128P)[1] +
+                             ((int32_t*)&avg128P)[2] +
+                             ((int32_t*)&avg128P)[3])/(nb_rb*12);
+
+      //            printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
+    }
+
+#if defined(__x86_64__) || defined(__i386__)
+  _mm_empty();
+  _m_empty();
+#endif
+
+}
+
+#if defined(__x86_64) || defined(__i386__)
+__m128i mmtmpPD0,mmtmpPD1,mmtmpPD2,mmtmpPD3;
+#elif defined(__arm__)
+
+#endif
+/*
+void pdcch_dual_stream_correlation(NR_DL_FRAME_PARMS *frame_parms,
+                                   uint8_t symbol,
+                                   int32_t **dl_ch_estimates_ext,
+                                   int32_t **dl_ch_estimates_ext_i,
+                                   int32_t **dl_ch_rho_ext,
+                                   uint8_t output_shift)
+{
+
+  uint16_t rb;
+#if defined(__x86_64__) || defined(__i386__)
+  __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128;
+#elif defined(__arm__)
+
+#endif
+  uint8_t aarx;
+
+  //  printf("dlsch_dual_stream_correlation: symbol %d\n",symbol);
+
+
+  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+
+#if defined(__x86_64__) || defined(__i386__)
+    dl_ch128          = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
+    dl_ch128i         = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12];
+    dl_ch_rho128      = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12];
+
+#elif defined(__arm__)
+
+#endif
+
+    for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
+      // multiply by conjugated channel
+#if defined(__x86_64__) || defined(__i386__)
+      mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]);
+      //  print_ints("re",&mmtmpPD0);
+
+      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+      mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
+      mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
+      mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]);
+      //  print_ints("im",&mmtmpPD1);
+      mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[0]);
+      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
+      mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
+      //  print_ints("re(shift)",&mmtmpPD0);
+      mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
+      //  print_ints("im(shift)",&mmtmpPD1);
+      mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
+      mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
+      //        print_ints("c0",&mmtmpPD2);
+      //  print_ints("c1",&mmtmpPD3);
+      dl_ch_rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
+
+      //print_shorts("rx:",dl_ch128_2);
+      //print_shorts("ch:",dl_ch128);
+      //print_shorts("pack:",rho128);
+
+      // multiply by conjugated channel
+      mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]);
+      // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+      mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
+      mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
+      mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate);
+      mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[1]);
+      // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+      mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
+      mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
+      mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
+      mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
+
+
+      dl_ch_rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3);
+      //print_shorts("rx:",dl_ch128_2+1);
+      //print_shorts("ch:",dl_ch128+1);
+      //print_shorts("pack:",rho128+1);
+      // multiply by conjugated channel
+      mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]);
+      // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+      mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
+      mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
+      mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate);
+      mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[2]);
+      // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+      mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
+      mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
+      mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
+      mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
+
+      dl_ch_rho128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
+      //print_shorts("rx:",dl_ch128_2+2);
+      //print_shorts("ch:",dl_ch128+2);
+      //print_shorts("pack:",rho128+2);
+
+      dl_ch128+=3;
+      dl_ch128i+=3;
+      dl_ch_rho128+=3;
+
+
+#elif defined(__arm__)
+
+#endif
+     }
+  }
+#if defined(__x86_64__) || defined(__i386__)
+  _mm_empty();
+  _m_empty();
+#endif
+
+}
+*/
+
+void pdcch_detection_mrc_i(NR_DL_FRAME_PARMS *frame_parms,
+                           int32_t **rxdataF_comp,
+                           int32_t **rxdataF_comp_i,
+                           int32_t **rho,
+                           int32_t **rho_i,
+                           uint8_t symbol)
+{
+
+  uint8_t aatx;
+
+#if defined(__x86_64__) || defined(__i386__)
+  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
+#elif defined(__arm__)
+  int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
+#endif
+  int32_t i;
+
+  if (frame_parms->nb_antennas_rx>1) {
+    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
+      //if (frame_parms->mode1_flag && (aatx>0)) break;
+
+#if defined(__x86_64__) || defined(__i386__)
+      rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
+      rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
+#elif defined(__arm__)
+      rxdataF_comp128_0   = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
+      rxdataF_comp128_1   = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
+#endif
+      // MRC on each re of rb on MF output
+      for (i=0; i<frame_parms->N_RB_DL*3; i++) {
+#if defined(__x86_64__) || defined(__i386__)
+        rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
+#elif defined(__arm__)
+        rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
+#endif
+      }
+    }
+
+#if defined(__x86_64__) || defined(__i386__)
+    rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
+    rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
+#elif defined(__arm__)
+    rho128_0 = (int16x8_t *) &rho[0][symbol*frame_parms->N_RB_DL*12];
+    rho128_1 = (int16x8_t *) &rho[1][symbol*frame_parms->N_RB_DL*12];
+#endif
+    for (i=0; i<frame_parms->N_RB_DL*3; i++) {
+#if defined(__x86_64__) || defined(__i386__)
+      rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
+#elif defined(__arm__)
+      rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]);
+#endif
+    }
+
+#if defined(__x86_64__) || defined(__i386__)
+    rho128_i0 = (__m128i *) &rho_i[0][symbol*frame_parms->N_RB_DL*12];
+    rho128_i1 = (__m128i *) &rho_i[1][symbol*frame_parms->N_RB_DL*12];
+    rxdataF_comp128_i0   = (__m128i *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
+    rxdataF_comp128_i1   = (__m128i *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
+#elif defined(__arm__)
+    rho128_i0 = (int16x8_t*) &rho_i[0][symbol*frame_parms->N_RB_DL*12];
+    rho128_i1 = (int16x8_t*) &rho_i[1][symbol*frame_parms->N_RB_DL*12];
+    rxdataF_comp128_i0   = (int16x8_t *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
+    rxdataF_comp128_i1   = (int16x8_t *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
+
+#endif
+    // MRC on each re of rb on MF and rho
+    for (i=0; i<frame_parms->N_RB_DL*3; i++) {
+#if defined(__x86_64__) || defined(__i386__)
+      rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1));
+      rho128_i0[i]          = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
+#elif defined(__arm__)
+      rxdataF_comp128_i0[i] = vhaddq_s16(rxdataF_comp128_i0[i],rxdataF_comp128_i1[i]);
+      rho128_i0[i]          = vhaddq_s16(rho128_i0[i],rho128_i1[i]);
+
+#endif
+    }
+  }
+
+#if defined(__x86_64__) || defined(__i386__)
+  _mm_empty();
+  _m_empty();
+#endif
+}
+
+
+#ifdef NR_PDCCH_DCI_RUN
+// This function will extract the mapped DM-RS PDCCH REs as per 38.211 Section 7.4.1.3.2 (Mapping to physical resources)
+void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
+                                 int32_t **dl_ch_estimates,
+                                 int32_t **rxdataF_ext,
+                                 int32_t **dl_ch_estimates_ext,
+                                 uint8_t symbol,
+                                 uint32_t high_speed_flag,
+                                 NR_DL_FRAME_PARMS *frame_parms,
+                                 uint64_t coreset_freq_dom,
+                                 uint32_t coreset_nbr_rb,
+                                 uint32_t n_BWP_start) {
+
+/*
+ * This function is demapping DM-RS PDCCH RE
+ * Implementing 38.211 Section 7.4.1.3.2 Mapping to physical resources
+ * PDCCH DM-RS signals are mapped on RE a_k_l where:
+ * k = 12*n + 4*kprime + 1
+ * n=0,1,..
+ * kprime=0,1,2
+ * According to this equations, DM-RS PDCCH are mapped on k where k%12==1 || k%12==5 || k%12==9
+ *
+ */
+  // the bitmap coreset_frq_domain contains 45 bits
+  #define CORESET_FREQ_DOMAIN_BITMAP_SIZE   45
+  // each bit is associated to 6 RBs
+  #define BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN  6
+  #define NBR_RE_PER_RB_WITH_DMRS           12
+  // after removing the 3 DMRS RE, the RB contains 9 RE with PDCCH
+  #define NBR_RE_PER_RB_WITHOUT_DMRS         9
+
+  uint16_t c_rb, c_rb_tmp, rb, nb_rb = 0;
+  // this variable will be incremented by 1 each time a bit set to '0' is found in coreset_freq_dom bitmap
+  uint16_t offset_discontiguous=0;
+  uint8_t rb_count_bit,i, j, aarx, bitcnt_coreset_freq_dom=0;
+  int32_t *dl_ch0, *dl_ch0_ext, *rxF, *rxF_ext;
+  int nushiftmod3 = frame_parms->nushift % 3;
+  uint8_t symbol_mod;
+
+  symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol;
+  c_rb = n_BWP_start; // c_rb is the common resource block: RB within the BWP
+  #ifdef DEBUG_DCI_DECODING
+    LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod);
+  #endif
+
+
+
+  for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
+    if (high_speed_flag == 1){
+      dl_ch0 = &dl_ch_estimates[aarx][5 + (symbol * (frame_parms->ofdm_symbol_size))];
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][5 + (symbol * (frame_parms->ofdm_symbol_size (%d))) = (%d)]\n",
+               aarx,frame_parms->ofdm_symbol_size,5 + (symbol * (frame_parms->ofdm_symbol_size)));
+        printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> why pointer is pointing to that position (what does '5' mean)?\n");
+      #endif
+    } else {
+      dl_ch0 = &dl_ch_estimates[aarx][5];
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][5]\n",aarx);
+      #endif
+    }
+
+    dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol * (frame_parms->N_RB_DL * NBR_RE_PER_RB_WITH_DMRS)];
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0_ext = &dl_ch_estimates_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 12) = (%d)]\n",
+             aarx,symbol * (frame_parms->N_RB_DL * 12));
+    #endif
+    rxF_ext = &rxdataF_ext[aarx][symbol * (frame_parms->N_RB_DL * NBR_RE_PER_RB_WITH_DMRS)];
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> rxF_ext = &rxdataF_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 12) = (%d)]\n",
+             aarx,symbol * (frame_parms->N_RB_DL * 12));
+      printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> (for symbol=%d, aarx=%d), symbol_mod=%d, nushiftmod3=%d \n",symbol,aarx,symbol_mod,nushiftmod3);
+    #endif
+
+/*
+ * The following for loop handles treatment of PDCCH contained in table rxdataF (in frequency domain)
+ * In NR the PDCCH IQ symbols are contained within RBs in the CORESET defined by higher layers which is located within the BWP
+ * Lets consider that the first RB to be considered as part of the CORESET and part of the PDCCH is n_BWP_start
+ * Several cases have to be handled differently as IQ symbols are situated in different parts of rxdataF:
+ * 1. Number of RBs in the system bandwidth is even
+ *    1.1 The RB is <  than the N_RB_DL/2 -> IQ symbols are in the second half of the rxdataF (from first_carrier_offset)
+ *    1.2 The RB is >= than the N_RB_DL/2 -> IQ symbols are in the first half of the rxdataF (from element 1)
+ * 2. Number of RBs in the system bandwidth is odd
+ * (particular case when the RB with DC as it is treated differently: it is situated in symbol borders of rxdataF)
+ *    2.1 The RB is <= than the N_RB_DL/2   -> IQ symbols are in the second half of the rxdataF (from first_carrier_offset)
+ *    2.2 The RB is >  than the N_RB_DL/2+1 -> IQ symbols are in the first half of the rxdataF (from element 1 + 2nd half RB containing DC)
+ *    2.3 The RB is == N_RB_DL/2+1          -> IQ symbols are in the lower border of the rxdataF for first 6 IQ element and the upper border of the rxdataF for the last 6 IQ elements
+ * If the first RB containing PDCCH within the UE BWP and within the CORESET is higher than half of the system bandwidth (N_RB_DL),
+ * then the IQ symbol is going to be found at the position 1+c_rb-N_RB_DL/2 in rxdataF and
+ * we have to point the pointer at (1+c_rb-N_RB_DL/2) in rxdataF
+ */
+
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> n_BWP_start=%d, coreset_nbr_rb=%d\n",n_BWP_start,coreset_nbr_rb);
+    #endif
+
+    for (c_rb = n_BWP_start; c_rb < (n_BWP_start + coreset_nbr_rb + (BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN * offset_discontiguous)); c_rb++) {
+      //c_rb_tmp = 0;
+      if (((c_rb - n_BWP_start) % BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN)==0) {
+        bitcnt_coreset_freq_dom ++;
+        while ((((coreset_freq_dom & 0x1FFFFFFFFFFF) >> (CORESET_FREQ_DOMAIN_BITMAP_SIZE - bitcnt_coreset_freq_dom)) & 0x1)== 0){ // 46 -> 45 is number of bits in coreset_freq_dom
+          // next 6 RB are not part of the CORESET within the BWP as bit in coreset_freq_dom is set to 0
+          bitcnt_coreset_freq_dom ++;
+          //c_rb_tmp = c_rb_tmp + 6;
+          c_rb = c_rb + BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN;
+          offset_discontiguous ++;
+          #ifdef NR_PDCCH_DCI_DEBUG
+            printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> we entered here as coreset_freq_dom=%llx (bit %d) is 0, coreset_freq_domain is discontiguous\n",coreset_freq_dom,(46 - bitcnt_coreset_freq_dom));
+          #endif
+        }
+      }
+      //c_rb = c_rb + c_rb_tmp;
+
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> c_rb=%d\n",c_rb);
+      #endif
+      // first we set initial conditions for pointer to rxdataF depending on the situation of the first RB within the CORESET (c_rb = n_BWP_start)
+      if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) {
+        //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): even case
+        rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))];
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
+                  c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
+        #endif
+      }
+      if ((c_rb >= (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) {
+        // number of RBs is even  and c_rb is higher than half system bandwidth (we don't skip DC)
+        // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF
+        rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
+               c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))));
+        #endif
+        //rxF = &rxdataF[aarx][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol
+        //#ifdef NR_PDCCH_DCI_DEBUG
+        //  printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
+        //         c_rb,aarx,(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))));
+        //#endif
+      }
+      if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)){
+        //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): odd case
+        rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))];
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
+                 c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
+        #endif
+      }
+      if ((c_rb > (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)){
+        // number of RBs is odd  and   c_rb is higher than half system bandwidth + 1
+        // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF just after the first IQ symbols of the RB containing DC
+        rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - frame_parms->N_RB_DL) - 5 + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
+                 c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size))));
+        #endif
+      }
+      if ((c_rb == (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)){ // treatment of RB containing the DC
+        // if odd number RBs in system bandwidth and first RB to be treated is higher than middle system bandwidth (around DC)
+        // we have to treat the RB in two parts: first part from i=0 to 5, the data is at the end of rxdataF (pointing at the end of the table)
+        rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))];
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
+                 c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
+        #endif
+        /*if (symbol_mod > 300) { // this if is going to be removed as DM-RS signals are present in all symbols of PDCCH
+          for (i = 0; i < 6; i++) {
+            dl_ch0_ext[i] = dl_ch0[i];
+            rxF_ext[i] = rxF[i];
+          }
+          rxF = &rxdataF[aarx][(symbol * (frame_parms->ofdm_symbol_size))]; // we point at the 1st part of the rxdataF in symbol
+          #ifdef NR_PDCCH_DCI_DEBUG
+            printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n",
+                   c_rb,aarx,(symbol * (frame_parms->ofdm_symbol_size)));
+          #endif
+          for (; i < 12; i++) {
+            dl_ch0_ext[i] = dl_ch0[i];
+            rxF_ext[i] = rxF[(1 + i - 6)];
+          }
+          nb_rb++;
+          dl_ch0_ext += 12;
+          rxF_ext += 12;
+          dl_ch0 += 12;
+          rxF += 7;
+          c_rb++;
+          } else {*/
+        j = 0;
+        for (i = 0; i < 6; i++) { //treating first part of the RB note that i=5 would correspond to DC. We treat it in NR
+          if ((i != 1) && (i != 5)) {
+            dl_ch0_ext[j] = dl_ch0[i];
+            rxF_ext[j++] = rxF[i];
+            //              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+          }
+        }
+        // then we point at the begining of the symbol part of rxdataF do process second part of RB
+        rxF = &rxdataF[aarx][((symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n",
+                 c_rb,aarx,(symbol * (frame_parms->ofdm_symbol_size)));
+        #endif
+        for (; i < 12; i++) {
+          if ((i != 9)) {
+            dl_ch0_ext[j] = dl_ch0[i];
+            rxF_ext[j++] = rxF[(1 + i - 6)];
+            //              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+          }
+        }
+        nb_rb++;
+        dl_ch0_ext += NBR_RE_PER_RB_WITHOUT_DMRS;
+        rxF_ext += NBR_RE_PER_RB_WITHOUT_DMRS;
+        dl_ch0 += 12;
+          //rxF += 7;
+          //c_rb++;
+          //n_BWP_start++; // We have to increment this variable here to be consequent in the for loop afterwards
+        //}
+      } else { // treatment of any RB that does not contain the DC
+        /*if (symbol_mod > 300) {
+          memcpy(dl_ch0_ext, dl_ch0, 12 * sizeof(int32_t));
+          for (i = 0; i < 12; i++) {
+            rxF_ext[i] = rxF[i];
+          }
+          nb_rb++;
+          dl_ch0_ext += 12;
+          rxF_ext += 12;
+          dl_ch0 += 12;
+          //rxF += 12;
+        } else {*/
+        j = 0;
+        for (i = 0; i < 12; i++) {
+          if ((i != 1) && (i != 5) && (i != 9)) {
+            rxF_ext[j] = rxF[i];
+            #ifdef NR_PDCCH_DCI_DEBUG
+              printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d)",
+                     c_rb, i, j, *(short *) &rxF_ext[j],*(1 + (short*) &rxF_ext[j]), i,
+                     *(short *) &rxF[i], *(1 + (short*) &rxF[i]));
+            #endif
+            dl_ch0_ext[j++] = dl_ch0[i];
+            //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> ch %d => dl_ch0(%d,%d)\n", i, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i]));
+            printf("\t-> ch %d => dl_ch0(%d,%d)\n", i, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i]));
+          } else {
+            #ifdef NR_PDCCH_DCI_DEBUG
+              printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d) \t\t <==> DM-RS PDCCH, this is a pilot symbol\n",
+                     c_rb, i, j, *(short *) &rxF_ext[j], *(1 + (short*) &rxF_ext[j]), i,
+                     *(short *) &rxF[i], *(1 + (short*) &rxF[i]));
+            #endif
+          }
+        }
+        nb_rb++;
+        dl_ch0_ext += NBR_RE_PER_RB_WITHOUT_DMRS;
+        rxF_ext += NBR_RE_PER_RB_WITHOUT_DMRS;
+        dl_ch0 += 12;
+          //rxF += 12;
+        //}
+      }
+    }
+  }
+}
+
+#endif
+#ifdef NR_PDCCH_DCI_RUN_bis
+// this function is just a second implementation of nr_pdcch_extract_rbs_single
+// the code modification is minimum but it can be slower in processing time
+// to be removed
+
+void nr_pdcch_extract_rbs_single_bis(int32_t **rxdataF, int32_t **dl_ch_estimates,
+  int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, uint8_t symbol,
+  uint32_t high_speed_flag, NR_DL_FRAME_PARMS *frame_parms, uint64_t coreset_freq_dom, uint32_t coreset_nbr_rb, uint32_t n_BWP_start) {
+
+  uint16_t rb, nb_rb = 0;
+  uint8_t i, j, aarx;
+  int32_t *dl_ch0, *dl_ch0_ext, *rxF, *rxF_ext;
+  int nushiftmod3 = frame_parms->nushift % 3;
+  uint8_t symbol_mod;
+
+  symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol;
+#ifdef DEBUG_DCI_DECODING
+  LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod);
+#endif
+  for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
+    if (high_speed_flag == 1){
+      dl_ch0 = &dl_ch_estimates[aarx][5 + (symbol * (frame_parms->ofdm_symbol_size))];
+      printf("\t\t### in function nr_pdcch_extract_rbs_single(), \t ### dl_ch0 = &dl_ch_estimates[aarx = (%d) ][5 + (symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n",
+             aarx,5 + (symbol * (frame_parms->ofdm_symbol_size)));
+    } else {
+      dl_ch0 = &dl_ch_estimates[aarx][5];
+      printf("\t\t### in function nr_pdcch_extract_rbs_single(), \t ### dl_ch0 = &dl_ch_estimates[aarx = (%d)][5]\n",aarx);
+    }
+    dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol * (frame_parms->N_RB_DL * 12)];
+    printf("\t\t### in function nr_pdcch_extract_rbs_single(), \t ### dl_ch0_ext = &dl_ch_estimates_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 12) = (%d)]\n",
+           aarx,symbol * (frame_parms->N_RB_DL * 12));
+    rxF_ext = &rxdataF_ext[aarx][symbol * (frame_parms->N_RB_DL * 12)];
+    printf("\t\t### in function nr_pdcch_extract_rbs_single(), \t ### rxF_ext = &rxdataF_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 12) = (%d)]\n",
+           aarx,symbol * (frame_parms->N_RB_DL * 12));
+    rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol * (frame_parms->ofdm_symbol_size)))];
+    printf("\t\t### in function nr_pdcch_extract_rbs_single(), \t ### rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
+           aarx,(frame_parms->first_carrier_offset + (symbol * (frame_parms->ofdm_symbol_size))));
+    printf("\t\t ###### in function pdcch_extract_rbs_single(for symbol=%d, aarx=%d), symbol_mod=%d, nushiftmod3=%d \n",symbol,aarx,symbol_mod,nushiftmod3);
+    printf("\t\t ###### rxF_ext = &rxdataF_ext[aarx(%d)][symbol(%d) * (frame_parms->N_RB_DL(%d) * 12)]\n",aarx,symbol,frame_parms->N_RB_DL);
+    printf("\t\t ###### rxF = &rxdataF[aarx(%d)][(frame_parms->first_carrier_offset(%d) + (symbol(%d) * (frame_parms->ofdm_symbol_size(%d))))]\n",
+           aarx,frame_parms->first_carrier_offset,symbol,frame_parms->ofdm_symbol_size);
+
+    if ((frame_parms->N_RB_DL & 1) == 0) { // even number of RBs
+      for (rb = 0; rb < frame_parms->N_RB_DL; rb++) {
+        printf("\t\t\t ###### rb=%d\n",rb);
+        if (rb == (frame_parms->N_RB_DL >> 1)) { // For second half of RBs skip DC carrier
+          rxF = &rxdataF[aarx][(1 + (symbol * (frame_parms->ofdm_symbol_size)))];
+          printf("\t\t\t ###### if rb (%d) is half N_RB_DL, skip DC carrier -> rxF = &rxdataF[aarx(%d)][(1 + (symbol(%d) * (frame_parms->ofdm_symbol_size(%d))))\n",
+                 rb,aarx,symbol,frame_parms->ofdm_symbol_size);
+          //dl_ch0++;
+        }
+        if (symbol_mod > 0) {
+          memcpy(dl_ch0_ext, dl_ch0, 12 * sizeof(int32_t));
+          for (i = 0; i < 12; i++) {
+            rxF_ext[i] = rxF[i];
+          }
+          nb_rb++;
+          dl_ch0_ext += 12;
+          rxF_ext += 12;
+          dl_ch0 += 12;
+          rxF += 12;
+        } else {
+          j = 0;
+          for (i = 0; i < 12; i++) {
+            if ((i != 1) && (i != 5) && (i != 9)) {
+              rxF_ext[j] = rxF[i];
+              printf("\textract rb %d \t re %d => rxF_ext[%d]=(%d,%d)", rb, i, j, *(short *) &rxF_ext[j], *(1 + (short*) &rxF_ext[j]));
+                     dl_ch0_ext[j++] = dl_ch0[i];
+              printf("\t\tch %d => dl_ch0(%d,%d)\n", i, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i]));
+            }
+          }
+          nb_rb++;
+          dl_ch0_ext += 9;
+          rxF_ext += 9;
+          dl_ch0 += 12;
+          rxF += 12;
+        }
+      }
+    } else { // Odd number of RBs
+      for (rb = 0; rb < frame_parms->N_RB_DL >> 1; rb++) {
+        printf("\t\t\t ###### rb=%d (Odd number of RBs, rb < half of band)\n",rb);
+          if (symbol_mod > 0) {
+            memcpy(dl_ch0_ext, dl_ch0, 12 * sizeof(int32_t));
+            for (i = 0; i < 12; i++)
+              rxF_ext[i] = rxF[i];
+            nb_rb++;
+            dl_ch0_ext += 12;
+            rxF_ext += 12;
+            dl_ch0 += 12;
+            rxF += 12;
+          } else {
+            j = 0;
+            for (i = 0; i < 12; i++) {
+              if ((i != 1) && (i != 5) && (i != 9)) {
+                rxF_ext[j] = rxF[i];
+                printf("\t\t\t\t ###### extract rb %d, re %d => rxF_ext[%d]=(%d,%d) rxF[%d]=(%d,%d)",
+                       rb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]),i,*(short *)&rxF[i],*(1+(short*)&rxF[i]));
+                dl_ch0_ext[j++] = dl_ch0[i];
+                printf("\t ###### extract rb %d, re %d => dl_ch0 []=(%d,%d)\n",rb,i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
+              } else {
+                printf("\t\t\t\t ###### THIS IS a pilot  rb %d \t re %d => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d) \t this is a pilot symbol\n",
+                       rb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]),i,*(short *)&rxF[i],*(1+(short*)&rxF[i]));
+              }
+            }
+            nb_rb++;
+            dl_ch0_ext += 9;
+            rxF_ext += 9;
+            dl_ch0 += 12;
+            rxF += 12;
+          }
+        }
+        // Do middle RB (around DC)
+        //printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
+        if (symbol_mod == 0) {
+          j = 0;
+          for (i = 0; i < 6; i++) {
+            if ((i != 1) && (i != 5)) {
+              dl_ch0_ext[j] = dl_ch0[i];
+              rxF_ext[j++] = rxF[i];
+              //printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+            }
+          }
+          rxF = &rxdataF[aarx][((symbol * (frame_parms->ofdm_symbol_size)))];
+          for (; i < 12; i++) {
+            if (i != 9) {
+              dl_ch0_ext[j] = dl_ch0[i];
+              rxF_ext[j++] = rxF[(1 + i - 6)];
+              //printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+            }
+          }
+          nb_rb++;
+          dl_ch0_ext += 9;
+          rxF_ext += 9;
+          dl_ch0 += 12;
+          rxF += 7;
+          rb++;
+        } else {
+          for (i = 0; i < 6; i++) {
+            dl_ch0_ext[i] = dl_ch0[i];
+            rxF_ext[i] = rxF[i];
+          }
+          rxF = &rxdataF[aarx][((symbol * (frame_parms->ofdm_symbol_size)))];
+          for (; i < 12; i++) {
+            dl_ch0_ext[i] = dl_ch0[i];
+            rxF_ext[i] = rxF[(1 + i - 6)];
+          }
+          nb_rb++;
+          dl_ch0_ext += 12;
+          rxF_ext += 12;
+          dl_ch0 += 12;
+          rxF += 7;
+          rb++;
+        }
+        for (; rb < frame_parms->N_RB_DL; rb++) {
+        printf("\t\t\t ###### rb=%d (Even number of RBs, rb > half of band)\n",rb);
+        if (symbol_mod > 0) {
+          memcpy(dl_ch0_ext, dl_ch0, 12 * sizeof(int32_t));
+          for (i = 0; i < 12; i++)
+            rxF_ext[i] = rxF[i];
+          nb_rb++;
+          dl_ch0_ext += 12;
+          rxF_ext += 12;
+          dl_ch0 += 12;
+          rxF += 12;
+        } else {
+          j = 0;
+          for (i = 0; i < 12; i++) {
+            if ((i != 1) && (i != 5) && (i != 9)) {
+              rxF_ext[j] = rxF[i];
+              printf("\t\t\t\t ###### extract rb %d, re %d => rxF_ext[]=(%d,%d)",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+              //printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+              dl_ch0_ext[j++] = dl_ch0[i];
+              printf("\t ###### extract rb %d, re %d => dl_ch0 []=(%d,%d)\n",rb,i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
+            } else {
+              printf("\t\t\t\t ###### THIS IS a RS at re %d\n",i);
+            }
+          }
+          nb_rb++;
+          dl_ch0_ext += 9;
+          rxF_ext += 9;
+          dl_ch0 += 12;
+          rxF += 12;
+        }
+      }
+    }
+  }
+
+// The function has created table rxdataF_ext with the contents of rxdataF and removing the pilots at positions 1,5,9 in every RB.
+// Now we need to check the contents of rxdataF_ext and keep only the values which correspond to our CORESET depending on variables:
+// - coreset_freq_dom (45 bit map)
+// - n_BWP_start (first RB within the active BWP and the CORESET)
+  j=0;
+  k=0;
+  rxF_ext = &rxdataF_ext[aarx][(symbol * (frame_parms->N_RB_DL * 12))];
+  printf("\t\t### in function nr_pdcch_extract_rbs_single(), \t ### rxF_ext = &rxdataF_ext[aarx = (%d)][n_BWP_start + (symbol * (frame_parms->N_RB_DL * 12)) = (%d)]\n",
+         aarx,(n_BWP_start + (symbol * (frame_parms->N_RB_DL * 12))));
+
+  int bitcnt_coreset_freq_dom = 1; // this variable will allow to check each bit of the 45 bitmap coreset_freq_dom.
+                                  //Eg: if bitcnt_coreset_freq_dom = 3, (46-3) we verify bit 43 starting from LSB
+  for (rb=0; rb<frame_parms->N_RB_DL;rb++) {
+    if (rb < n_BWP_start) {
+    // while rb is not within CORESET, then remove values
+      for (i=0; i<8; i++) {
+        //rxF_ext[i] = 0;
+        j++;
+      }
+      //rxF_ext = &rxdataF_ext[aarx][(j + (symbol * (frame_parms->N_RB_DL * 12)))];
+    } else if ((rb >= n_BWP_start) && (rb < (n_BWP_start + 6 * 45))) {
+    // rb is within CORESET, we need to verify now whether bit in coreset_freq_dom is set or not
+      if ((((coreset_freq_dom & 0x1FFFFFFFFFFF) >> (46 - bitcnt_coreset_freq_dom)) & 0x1)== 0){
+      // if bit is 0, next 6 consecutive RBs do not belong to CORESET
+        bitcnt_coreset_freq_dom ++;
+        rb = rb + 6;
+        for (i=0; i<(9*6); i++) {
+          //rxF_ext[i] = 0;
+          j++;
+        }
+        //rxF_ext = &rxdataF_ext[aarx][(j + (symbol * (frame_parms->N_RB_DL * 12)))];
+      } else {
+      // if bit is 1, next 6 consecutive RBs belong to CORESET
+        bitcnt_coreset_freq_dom ++;
+        rb = rb + 6;
+        for (i=0; i<(9*6); i++) {
+          rxF_ext[k] = rxF_ext[j];
+          k++;
+          j++;
+        }
+        //rxF_ext = &rxdataF_ext[aarx][(j + (symbol * (frame_parms->N_RB_DL * 12)))];
+      }
+    } else { // for the RBs that are in the upper side of the CORESET bitmap
+     for (i=0; i<8; i++) {
+        rxF_ext[k] = 0;
+        k++;
+        j++;
+      }
+      //rxF_ext = &rxdataF_ext[aarx][(j + (symbol * (frame_parms->N_RB_DL * 12)))];
+    }
+  }
+}
+
+#endif
+
+
+
+void pdcch_extract_rbs_single(int32_t **rxdataF,
+                              int32_t **dl_ch_estimates,
+                              int32_t **rxdataF_ext,
+                              int32_t **dl_ch_estimates_ext,
+                              uint8_t symbol,
+                              uint32_t high_speed_flag,
+                              NR_DL_FRAME_PARMS *frame_parms)
+{
+
+
+  uint16_t rb,nb_rb=0;
+  uint8_t i,j,aarx;
+  int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
+
+
+  int nushiftmod3 = frame_parms->nushift%3;
+  uint8_t symbol_mod;
+
+  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+#ifdef DEBUG_DCI_DECODING
+  LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod);
+#endif
+
+  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+
+    if (high_speed_flag == 1)
+      dl_ch0     = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
+    else
+      dl_ch0     = &dl_ch_estimates[aarx][5];
+
+    dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
+
+    rxF_ext   = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
+
+    rxF       = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
+
+    if ((frame_parms->N_RB_DL&1) == 0)  { // even number of RBs
+      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
+
+        // For second half of RBs skip DC carrier
+        if (rb==(frame_parms->N_RB_DL>>1)) {
+          rxF       = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
+
+          //dl_ch0++;
+        }
+
+        if (symbol_mod>0) {
+          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
+
+          for (i=0; i<12; i++) {
+
+            rxF_ext[i]=rxF[i];
+
+          }
+
+          nb_rb++;
+          dl_ch0_ext+=12;
+          rxF_ext+=12;
+
+          dl_ch0+=12;
+          rxF+=12;
+        } else {
+          j=0;
+
+          for (i=0; i<12; i++) {
+            if ((i!=nushiftmod3) &&
+                (i!=(nushiftmod3+3)) &&
+                (i!=(nushiftmod3+6)) &&
+                (i!=(nushiftmod3+9))) {
+              rxF_ext[j]=rxF[i];
+              //                        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+              dl_ch0_ext[j++]=dl_ch0[i];
+              //                printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
+            }
+          }
+
+          nb_rb++;
+          dl_ch0_ext+=8;
+          rxF_ext+=8;
+
+          dl_ch0+=12;
+          rxF+=12;
+        }
+      }
+    } else { // Odd number of RBs
+      for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
+
+        if (symbol_mod>0) {
+          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
+
+          for (i=0; i<12; i++)
+            rxF_ext[i]=rxF[i];
+
+          nb_rb++;
+          dl_ch0_ext+=12;
+          rxF_ext+=12;
+
+          dl_ch0+=12;
+          rxF+=12;
+        } else {
+          j=0;
+
+          for (i=0; i<12; i++) {
+            if ((i!=nushiftmod3) &&
+                (i!=(nushiftmod3+3)) &&
+                (i!=(nushiftmod3+6)) &&
+                (i!=(nushiftmod3+9))) {
+              rxF_ext[j]=rxF[i];
+              //                        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+              dl_ch0_ext[j++]=dl_ch0[i];
+              //                printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
+            }
+          }
+
+          nb_rb++;
+          dl_ch0_ext+=8;
+          rxF_ext+=8;
+
+          dl_ch0+=12;
+          rxF+=12;
+        }
+      }
+
+      // Do middle RB (around DC)
+      //  printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
+
+      if (symbol_mod==0) {
+        j=0;
+
+        for (i=0; i<6; i++) {
+          if ((i!=nushiftmod3) &&
+              (i!=(nushiftmod3+3))) {
+            dl_ch0_ext[j]=dl_ch0[i];
+            rxF_ext[j++]=rxF[i];
+            //              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+          }
+        }
+
+        rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
+
+        for (; i<12; i++) {
+          if ((i!=(nushiftmod3+6)) &&
+              (i!=(nushiftmod3+9))) {
+            dl_ch0_ext[j]=dl_ch0[i];
+            rxF_ext[j++]=rxF[(1+i-6)];
+            //              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+          }
+        }
+
+
+        nb_rb++;
+        dl_ch0_ext+=8;
+        rxF_ext+=8;
+        dl_ch0+=12;
+        rxF+=7;
+        rb++;
+      } else {
+        for (i=0; i<6; i++) {
+          dl_ch0_ext[i]=dl_ch0[i];
+          rxF_ext[i]=rxF[i];
+        }
+
+        rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
+
+        for (; i<12; i++) {
+          dl_ch0_ext[i]=dl_ch0[i];
+          rxF_ext[i]=rxF[(1+i-6)];
+        }
+
+
+        nb_rb++;
+        dl_ch0_ext+=12;
+        rxF_ext+=12;
+        dl_ch0+=12;
+        rxF+=7;
+        rb++;
+      }
+
+      for (; rb<frame_parms->N_RB_DL; rb++) {
+        if (symbol_mod > 0) {
+          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
+
+          for (i=0; i<12; i++)
+            rxF_ext[i]=rxF[i];
+
+          nb_rb++;
+          dl_ch0_ext+=12;
+          rxF_ext+=12;
+
+          dl_ch0+=12;
+          rxF+=12;
+        } else {
+          j=0;
+
+          for (i=0; i<12; i++) {
+            if ((i!=(nushiftmod3)) &&
+                (i!=(nushiftmod3+3)) &&
+                (i!=(nushiftmod3+6)) &&
+                (i!=(nushiftmod3+9))) {
+              rxF_ext[j]=rxF[i];
+              //                printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+              dl_ch0_ext[j++]=dl_ch0[i];
+            }
+          }
+
+          nb_rb++;
+          dl_ch0_ext+=8;
+          rxF_ext+=8;
+
+          dl_ch0+=12;
+          rxF+=12;
+        }
+      }
+    }
+  }
+}
+
+void pdcch_extract_rbs_dual(int32_t **rxdataF,
+                            int32_t **dl_ch_estimates,
+                            int32_t **rxdataF_ext,
+                            int32_t **dl_ch_estimates_ext,
+                            uint8_t symbol,
+                            uint32_t high_speed_flag,
+                            NR_DL_FRAME_PARMS *frame_parms)
+{
+
+
+  uint16_t rb,nb_rb=0;
+  uint8_t i,aarx,j;
+  int32_t *dl_ch0,*dl_ch0_ext,*dl_ch1,*dl_ch1_ext,*rxF,*rxF_ext;
+  uint8_t symbol_mod;
+  int nushiftmod3 = frame_parms->nushift%3;
+
+  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+#ifdef DEBUG_DCI_DECODING
+  LOG_I(PHY, "extract_rbs_dual: symbol_mod %d\n",symbol_mod);
+#endif
+
+  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+
+    if (high_speed_flag==1) {
+      dl_ch0     = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
+      dl_ch1     = &dl_ch_estimates[2+aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
+    } else {
+      dl_ch0     = &dl_ch_estimates[aarx][5];
+      dl_ch1     = &dl_ch_estimates[2+aarx][5];
+    }
+
+    dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
+    dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)];
+
+    //    printf("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12));
+    rxF_ext   = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
+
+    rxF       = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
+
+    if ((frame_parms->N_RB_DL&1) == 0)  // even number of RBs
+      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
+
+        // For second half of RBs skip DC carrier
+        if (rb==(frame_parms->N_RB_DL>>1)) {
+          rxF       = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
+          //    dl_ch0++;
+          //dl_ch1++;
+        }
+
+        if (symbol_mod>0) {
+          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
+          memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
+
+          /*
+            printf("rb %d\n",rb);
+            for (i=0;i<12;i++)
+            printf("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]);
+            printf("\n");
+          */
+          for (i=0; i<12; i++) {
+            rxF_ext[i]=rxF[i];
+            //      printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2,
+            //  ((int16_t*)&rxF[i<<1])[0],((int16_t*)&rxF[i<<1])[0]);
+          }
+
+          nb_rb++;
+          dl_ch0_ext+=12;
+          dl_ch1_ext+=12;
+          rxF_ext+=12;
+        } else {
+          j=0;
+
+          for (i=0; i<12; i++) {
+            if ((i!=nushiftmod3) &&
+                (i!=nushiftmod3+3) &&
+                (i!=nushiftmod3+6) &&
+                (i!=nushiftmod3+9)) {
+              rxF_ext[j]=rxF[i];
+              //                            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+              dl_ch0_ext[j]  =dl_ch0[i];
+              dl_ch1_ext[j++]=dl_ch1[i];
+            }
+          }
+
+          nb_rb++;
+          dl_ch0_ext+=8;
+          dl_ch1_ext+=8;
+          rxF_ext+=8;
+        }
+
+        dl_ch0+=12;
+        dl_ch1+=12;
+        rxF+=12;
+      }
+
+    else {  // Odd number of RBs
+      for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
+
+        //  printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
+
+        if (symbol_mod>0) {
+          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
+          memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
+
+          for (i=0; i<12; i++)
+            rxF_ext[i]=rxF[i];
+
+          nb_rb++;
+          dl_ch0_ext+=12;
+          dl_ch1_ext+=12;
+          rxF_ext+=12;
+
+          dl_ch0+=12;
+          dl_ch1+=12;
+          rxF+=12;
+
+        } else {
+          j=0;
+
+          for (i=0; i<12; i++) {
+            if ((i!=nushiftmod3) &&
+                (i!=nushiftmod3+3) &&
+                (i!=nushiftmod3+6) &&
+                (i!=nushiftmod3+9)) {
+              rxF_ext[j]=rxF[i];
+              //                        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+              dl_ch0_ext[j]=dl_ch0[i];
+              dl_ch1_ext[j++]=dl_ch1[i];
+              //                printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
+            }
+          }
+
+          nb_rb++;
+          dl_ch0_ext+=8;
+          dl_ch1_ext+=8;
+          rxF_ext+=8;
+
+
+          dl_ch0+=12;
+          dl_ch1+=12;
+          rxF+=12;
+        }
+      }
+
+      // Do middle RB (around DC)
+
+      if (symbol_mod > 0) {
+        for (i=0; i<6; i++) {
+          dl_ch0_ext[i]=dl_ch0[i];
+          dl_ch1_ext[i]=dl_ch1[i];
+          rxF_ext[i]=rxF[i];
+        }
+
+        rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
+
+        for (; i<12; i++) {
+          dl_ch0_ext[i]=dl_ch0[i];
+          dl_ch1_ext[i]=dl_ch1[i];
+          rxF_ext[i]=rxF[(1+i)];
+        }
+
+        nb_rb++;
+        dl_ch0_ext+=12;
+        dl_ch1_ext+=12;
+        rxF_ext+=12;
+
+        dl_ch0+=12;
+        dl_ch1+=12;
+        rxF+=7;
+        rb++;
+      } else {
+        j=0;
+
+        for (i=0; i<6; i++) {
+          if ((i!=nushiftmod3) &&
+              (i!=nushiftmod3+3)) {
+            dl_ch0_ext[j]=dl_ch0[i];
+            dl_ch1_ext[j]=dl_ch1[i];
+            rxF_ext[j++]=rxF[i];
+            //              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+          }
+        }
+
+        rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
+
+        for (; i<12; i++) {
+          if ((i!=nushiftmod3+6) &&
+              (i!=nushiftmod3+9)) {
+            dl_ch0_ext[j]=dl_ch0[i];
+            dl_ch1_ext[j]=dl_ch1[i];
+            rxF_ext[j++]=rxF[(1+i-6)];
+            //              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+          }
+        }
+
+
+        nb_rb++;
+        dl_ch0_ext+=8;
+        dl_ch1_ext+=8;
+        rxF_ext+=8;
+        dl_ch0+=12;
+        dl_ch1+=12;
+        rxF+=7;
+        rb++;
+      }
+
+      for (; rb<frame_parms->N_RB_DL; rb++) {
+
+        if (symbol_mod>0) {
+          //  printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
+          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
+          memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
+
+          for (i=0; i<12; i++)
+            rxF_ext[i]=rxF[i];
+
+          nb_rb++;
+          dl_ch0_ext+=12;
+          dl_ch1_ext+=12;
+          rxF_ext+=12;
+
+          dl_ch0+=12;
+          dl_ch1+=12;
+          rxF+=12;
+        } else {
+          j=0;
+
+          for (i=0; i<12; i++) {
+            if ((i!=nushiftmod3) &&
+                (i!=nushiftmod3+3) &&
+                (i!=nushiftmod3+6) &&
+                (i!=nushiftmod3+9)) {
+              rxF_ext[j]=rxF[i];
+              //                printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+              dl_ch0_ext[j]=dl_ch0[i];
+              dl_ch1_ext[j++]=dl_ch1[i];
+            }
+          }
+
+          nb_rb++;
+          dl_ch0_ext+=8;
+          dl_ch1_ext+=8;
+          rxF_ext+=8;
+
+          dl_ch0+=12;
+          dl_ch1+=12;
+          rxF+=12;
+        }
+      }
+    }
+  }
+}
+
+
+
+#ifdef NR_PDCCH_DCI_RUN
+void nr_pdcch_channel_compensation(int32_t **rxdataF_ext,
+                                   int32_t **dl_ch_estimates_ext,
+                                   int32_t **rxdataF_comp,
+                                   int32_t **rho,
+                                   NR_DL_FRAME_PARMS *frame_parms,
+                                   uint8_t symbol,
+                                   uint8_t output_shift,
+                                   uint32_t coreset_nbr_rb)
+{
+
+  uint16_t rb;
+  #if defined(__x86_64__) || defined(__i386__)
+    __m128i *dl_ch128, *rxdataF128, *rxdataF_comp128;
+    __m128i *dl_ch128_2, *rho128;
+  #elif defined(__arm__)
+  #endif
+  uint8_t aatx, aarx, pilots = 0;
+
+short conjugate[8]__attribute__((aligned(16)))  = {-1,1,-1,1,-1,1,-1,1};
+short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
+
+  #ifdef DEBUG_DCI_DECODING
+    LOG_I(PHY, "PDCCH comp: symbol %d\n",symbol);
+  #endif
+/*
+	if (symbol == 0)
+		pilots = 1;
+*/
+  for (aatx = 0; aatx < frame_parms->nb_antenna_ports_eNB; aatx++) {
+    //if (frame_parms->mode1_flag && aatx>0) break; //if mode1_flag is set then there is only one stream to extract, independent of nb_antenna_ports_eNB
+    for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
+      #if defined(__x86_64__) || defined(__i386__)
+        // dl_ch128 = (__m128i *) &dl_ch_estimates_ext[(aatx << 1) + aarx][symbol * frame_parms->N_RB_DL * 12];
+        // rxdataF128 = (__m128i *) &rxdataF_ext[aarx][symbol * frame_parms->N_RB_DL * 12];
+        // rxdataF_comp128 = (__m128i *) &rxdataF_comp[(aatx << 1) + aarx][symbol * frame_parms->N_RB_DL * 12];
+        dl_ch128 = (__m128i *) &dl_ch_estimates_ext[(aatx << 1) + aarx][symbol * coreset_nbr_rb * 12];
+        rxdataF128 = (__m128i *) &rxdataF_ext[aarx][symbol * coreset_nbr_rb * 12];
+        rxdataF_comp128 = (__m128i *) &rxdataF_comp[(aatx << 1) + aarx][symbol * coreset_nbr_rb * 12];
+      #elif defined(__arm__)
+      #endif
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> Total of RBs to be computed (%d), and number of RE (%d) (9 RE per RB)\n",coreset_nbr_rb,coreset_nbr_rb*9);
+      #endif
+      uint32_t k=0;
+      for (rb = 0; rb < coreset_nbr_rb; rb) { //FIXME this for loop risks an infinite loop if rb is not increased by 1 inside the loop
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rb=%d\n", rb);
+        #endif
+        #if defined(__x86_64__) || defined(__i386__)
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        // multiply by conjugated channel
+        mmtmpPD0 = _mm_madd_epi16(dl_ch128[0], rxdataF128[0]); // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+        // print_ints("re",&mmtmpPD0);
+        mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0], _MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1, _MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_sign_epi16(mmtmpPD1, *(__m128i * )&conjugate[0]);
+        // print_ints("im",&mmtmpPD1);
+        mmtmpPD1 = _mm_madd_epi16(mmtmpPD1, rxdataF128[0]); // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+        mmtmpPD0 = _mm_srai_epi32(mmtmpPD0, output_shift);
+        // print_ints("re(shift)",&mmtmpPD0);
+        mmtmpPD1 = _mm_srai_epi32(mmtmpPD1, output_shift);
+        // print_ints("im(shift)",&mmtmpPD1);
+        mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0, mmtmpPD1);
+        mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0, mmtmpPD1);
+        // print_ints("c0",&mmtmpPD2);
+        // print_ints("c1",&mmtmpPD3);
+        rxdataF_comp128[0] = _mm_packs_epi32(mmtmpPD2, mmtmpPD3);
+        // print_shorts("rx:",rxdataF128);
+        // print_shorts("ch:",dl_ch128);
+        // print_shorts("pack:",rxdataF_comp128);
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        // multiply by conjugated channel
+        mmtmpPD0 = _mm_madd_epi16(dl_ch128[1], rxdataF128[1]); // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+        mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1], _MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1, _MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_sign_epi16(mmtmpPD1, *(__m128i * )conjugate);
+        mmtmpPD1 = _mm_madd_epi16(mmtmpPD1, rxdataF128[1]); // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+        mmtmpPD0 = _mm_srai_epi32(mmtmpPD0, output_shift);
+        mmtmpPD1 = _mm_srai_epi32(mmtmpPD1, output_shift);
+        mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0, mmtmpPD1);
+        mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0, mmtmpPD1);
+        rxdataF_comp128[1] = _mm_packs_epi32(mmtmpPD2, mmtmpPD3);
+        // print_shorts("rx:",rxdataF128+1);
+        // print_shorts("ch:",dl_ch128+1);
+        // print_shorts("pack:",rxdataF_comp128+1);
+        // multiply by conjugated channel
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF x dl_ch -> RB[%d] RE[%d]\n",rb,k);
+        #endif
+        k++;
+        if (k%9 == 0) rb++;
+        mmtmpPD0 = _mm_madd_epi16(dl_ch128[2], rxdataF128[2]); // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+        mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1, _MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_sign_epi16(mmtmpPD1, *(__m128i * )conjugate);
+        mmtmpPD1 = _mm_madd_epi16(mmtmpPD1, rxdataF128[2]); // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+        mmtmpPD0 = _mm_srai_epi32(mmtmpPD0, output_shift);
+        mmtmpPD1 = _mm_srai_epi32(mmtmpPD1, output_shift);
+        mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0, mmtmpPD1);
+        mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0, mmtmpPD1);
+        rxdataF_comp128[2] = _mm_packs_epi32(mmtmpPD2, mmtmpPD3);
+        // We compute the third part of 4 symbols contained in one entire RB = 12 RE
+        //if (rb < 6 || rb > 95) {
+        #ifdef NR_PDCCH_DCI_DEBUG
+          print_shorts("\t\trxdataF_ext:", rxdataF128);
+          print_shorts("\t\tdl_ch:", dl_ch128);
+          print_shorts("\t\trxdataF_comp:", rxdataF_comp128);
+          print_shorts("\t\trxdataF_ext:", rxdataF128 + 1);
+          print_shorts("\t\tdl_ch:", dl_ch128 + 1);
+          print_shorts("\t\trxdataF_comp:", rxdataF_comp128 + 1);
+          print_shorts("\t\ttrxdataF_ext:", rxdataF128 + 2);
+          print_shorts("\t\tdl_ch:", dl_ch128 + 2);
+          print_shorts("\t\trxdataF_comp:", rxdataF_comp128 + 2);
+        #endif
+        //}
+        dl_ch128 += 3;
+        rxdataF128 += 3;
+        rxdataF_comp128 += 3;
+        //if ((rb + 1) % 4 == 3)
+        //rb++;
+        // if rxdataF_comp does contains pilot DM-RS PDCCH, as in previous code rxdataF_comp128 is a set of 4 consecutive outputs (32-bit)
+        // the computation of third part of 4 symbols contains last 9th symbol of the current rb + 3 first symbols of the next rb
+        // so rb computing must be take this into consideration, and every 4 rb, rb must be increased twice
+        //}
+
+// This code will replace the code below for nr
+//#else
+/*
+				if (pilots == 0) {
+					mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
+					// mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+					mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
+					mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
+					mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate);
+					mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[2]);
+					// mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+					mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
+					mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
+					mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
+					mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
+
+					rxdataF_comp128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
+				}
+
+				print_shorts("rx:",rxdataF128);
+				print_shorts("ch:",dl_ch128);
+				print_shorts("pack:",rxdataF_comp128);
+				print_shorts("\trx:",rxdataF128+1);
+				print_shorts("\tch:",dl_ch128+1);
+				print_shorts("\tpack:",rxdataF_comp128+1);
+				print_shorts("\t\trx:",rxdataF128+2);
+				print_shorts("\t\tch:",dl_ch128+2);
+				print_shorts("\t\tpack:",rxdataF_comp128+2);
+
+				if (pilots==0) {
+					dl_ch128+=3;
+					rxdataF128+=3;
+					rxdataF_comp128+=3;
+				} else {
+					dl_ch128+=2;
+					rxdataF128+=2;
+					rxdataF_comp128+=2;
+				}
+
+*/
+//#endif
+
+#elif defined(__arm__)
+
+#endif
+      }
+    }
+  }
+
+	if (rho) {
+
+		for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
+
+#if defined(__x86_64__) || defined(__i386__)
+			rho128 = (__m128i *) &rho[aarx][symbol * frame_parms->N_RB_DL * 12];
+			dl_ch128 = (__m128i *) &dl_ch_estimates_ext[aarx][symbol
+					* frame_parms->N_RB_DL * 12];
+			dl_ch128_2 = (__m128i *) &dl_ch_estimates_ext[2 + aarx][symbol
+					* frame_parms->N_RB_DL * 12];
+
+#elif defined(__arm__)
+
+#endif
+
+//for (rb = 0; rb < frame_parms->N_RB_DL; rb++) {
+for (rb = 0; rb < coreset_nbr_rb; rb++) {
+#if defined(__x86_64__) || defined(__i386__)
+
+				// multiply by conjugated channel
+				mmtmpPD0 = _mm_madd_epi16(dl_ch128[0], dl_ch128_2[0]);
+				//  print_ints("re",&mmtmpD0);
+
+				// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+				mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],
+						_MM_SHUFFLE(2,3,0,1));
+				mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1, _MM_SHUFFLE(2,3,0,1));
+				mmtmpPD1 = _mm_sign_epi16(mmtmpPD1, *(__m128i * )&conjugate[0]);
+				//  print_ints("im",&mmtmpPD1);
+				mmtmpPD1 = _mm_madd_epi16(mmtmpPD1, dl_ch128_2[0]);
+				// mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+				mmtmpPD0 = _mm_srai_epi32(mmtmpPD0, output_shift);
+				//  print_ints("re(shift)",&mmtmpD0);
+				mmtmpPD1 = _mm_srai_epi32(mmtmpPD1, output_shift);
+				//  print_ints("im(shift)",&mmtmpD1);
+				mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0, mmtmpPD1);
+				mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0, mmtmpPD1);
+				//        print_ints("c0",&mmtmpPD2);
+				//  print_ints("c1",&mmtmpPD3);
+				rho128[0] = _mm_packs_epi32(mmtmpPD2, mmtmpPD3);
+
+				//print_shorts("rx:",dl_ch128_2);
+				//print_shorts("ch:",dl_ch128);
+				//print_shorts("pack:",rho128);
+
+				// multiply by conjugated channel
+				mmtmpPD0 = _mm_madd_epi16(dl_ch128[1], dl_ch128_2[1]);
+				// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+				mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],
+						_MM_SHUFFLE(2,3,0,1));
+				mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1, _MM_SHUFFLE(2,3,0,1));
+				mmtmpPD1 = _mm_sign_epi16(mmtmpPD1, *(__m128i * )conjugate);
+				mmtmpPD1 = _mm_madd_epi16(mmtmpPD1, dl_ch128_2[1]);
+				// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
+				mmtmpPD0 = _mm_srai_epi32(mmtmpPD0, output_shift);
+				mmtmpPD1 = _mm_srai_epi32(mmtmpPD1, output_shift);
+				mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0, mmtmpPD1);
+				mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0, mmtmpPD1);
+
+				rho128[1] = _mm_packs_epi32(mmtmpPD2, mmtmpPD3);
+				//print_shorts("rx:",dl_ch128_2+1);
+				//print_shorts("ch:",dl_ch128+1);
+				//print_shorts("pack:",rho128+1);
+				// multiply by conjugated channel
+				mmtmpPD0 = _mm_madd_epi16(dl_ch128[2], dl_ch128_2[2]);
+				// mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+				mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],
+						_MM_SHUFFLE(2,3,0,1));
+				mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1, _MM_SHUFFLE(2,3,0,1));
+				mmtmpPD1 = _mm_sign_epi16(mmtmpPD1, *(__m128i * )conjugate);
+				mmtmpPD1 = _mm_madd_epi16(mmtmpPD1, dl_ch128_2[2]);
+				// mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+				mmtmpPD0 = _mm_srai_epi32(mmtmpPD0, output_shift);
+				mmtmpPD1 = _mm_srai_epi32(mmtmpPD1, output_shift);
+				mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0, mmtmpPD1);
+				mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0, mmtmpPD1);
+
+				rho128[2] = _mm_packs_epi32(mmtmpPD2, mmtmpPD3);
+				//print_shorts("rx:",dl_ch128_2+2);
+				//print_shorts("ch:",dl_ch128+2);
+				//print_shorts("pack:",rho128+2);
+
+				dl_ch128 += 3;
+				dl_ch128_2 += 3;
+				rho128 += 3;
+
+#elif defined(__arm_)
+
+#endif
+			}
+		}
+
+	}
+
+#if defined(__x86_64__) || defined(__i386__)
+	_mm_empty();
+	_m_empty();
+#endif
+}
+
+#endif
+
+/*
+void pdcch_channel_compensation(int32_t **rxdataF_ext,
+                                int32_t **dl_ch_estimates_ext,
+                                int32_t **rxdataF_comp,
+                                int32_t **rho,
+                                NR_DL_FRAME_PARMS *frame_parms,
+                                uint8_t symbol,
+                                uint8_t output_shift)
+{
+
+  uint16_t rb;
+#if defined(__x86_64__) || defined(__i386__)
+  __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
+  __m128i *dl_ch128_2, *rho128;
+#elif defined(__arm__)
+
+#endif
+  uint8_t aatx,aarx,pilots=0;
+
+
+
+
+#ifdef DEBUG_DCI_DECODING
+  LOG_I(PHY, "PDCCH comp: symbol %d\n",symbol);
+#endif
+
+  if (symbol==0)
+    pilots=1;
+
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
+    //if (frame_parms->mode1_flag && aatx>0) break; //if mode1_flag is set then there is only one stream to extract, independent of nb_antenna_ports_eNB
+
+    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+
+#if defined(__x86_64__) || defined(__i386__)
+      dl_ch128          = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
+      rxdataF128        = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
+      rxdataF_comp128   = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
+#elif defined(__arm__)
+
+#endif
+
+      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
+
+#if defined(__x86_64__) || defined(__i386__)
+        // multiply by conjugated channel
+        mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
+        //  print_ints("re",&mmtmpPD0);
+
+        // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+        mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]);
+        //  print_ints("im",&mmtmpPD1);
+        mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[0]);
+        // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+        mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
+        //  print_ints("re(shift)",&mmtmpPD0);
+        mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
+        //  print_ints("im(shift)",&mmtmpPD1);
+        mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
+        mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
+        //        print_ints("c0",&mmtmpPD2);
+        //  print_ints("c1",&mmtmpPD3);
+        rxdataF_comp128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
+        //  print_shorts("rx:",rxdataF128);
+        //  print_shorts("ch:",dl_ch128);
+        //  print_shorts("pack:",rxdataF_comp128);
+
+        // multiply by conjugated channel
+        mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
+        // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+        mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate);
+        mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[1]);
+        // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+        mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
+        mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
+        mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
+        mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
+
+        rxdataF_comp128[1] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
+
+        //  print_shorts("rx:",rxdataF128+1);
+        //  print_shorts("ch:",dl_ch128+1);
+        //  print_shorts("pack:",rxdataF_comp128+1);
+        // multiply by conjugated channel
+        if (pilots == 0) {
+          mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
+          // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+          mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
+          mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
+          mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate);
+          mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[2]);
+          // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+          mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
+          mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
+          mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
+          mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
+
+          rxdataF_comp128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
+        }
+
+        //  print_shorts("rx:",rxdataF128+2);
+        //  print_shorts("ch:",dl_ch128+2);
+        //        print_shorts("pack:",rxdataF_comp128+2);
+
+        if (pilots==0) {
+          dl_ch128+=3;
+          rxdataF128+=3;
+          rxdataF_comp128+=3;
+        } else {
+          dl_ch128+=2;
+          rxdataF128+=2;
+          rxdataF_comp128+=2;
+        }
+#elif defined(__arm__)
+
+#endif
+      }
+    }
+  }
+
+
+  if (rho) {
+
+    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+
+#if defined(__x86_64__) || defined(__i386__)
+      rho128        = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
+      dl_ch128      = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
+      dl_ch128_2    = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
+
+#elif defined(__arm__)
+      
+#endif
+      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
+#if defined(__x86_64__) || defined(__i386__)
+
+        // multiply by conjugated channel
+        mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]);
+        //  print_ints("re",&mmtmpD0);
+
+        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+        mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]);
+        //  print_ints("im",&mmtmpPD1);
+        mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[0]);
+        // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+        mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
+        //  print_ints("re(shift)",&mmtmpD0);
+        mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
+        //  print_ints("im(shift)",&mmtmpD1);
+        mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
+        mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
+        //        print_ints("c0",&mmtmpPD2);
+        //  print_ints("c1",&mmtmpPD3);
+        rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
+
+        //print_shorts("rx:",dl_ch128_2);
+        //print_shorts("ch:",dl_ch128);
+        //print_shorts("pack:",rho128);
+
+        // multiply by conjugated channel
+        mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]);
+        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+        mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate);
+        mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[1]);
+        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
+        mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
+        mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
+        mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
+        mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
+
+
+        rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3);
+        //print_shorts("rx:",dl_ch128_2+1);
+        //print_shorts("ch:",dl_ch128+1);
+        //print_shorts("pack:",rho128+1);
+        // multiply by conjugated channel
+        mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]);
+        // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
+        mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
+        mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate);
+        mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[2]);
+        // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
+        mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
+        mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
+        mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
+        mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
+
+        rho128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
+        //print_shorts("rx:",dl_ch128_2+2);
+        //print_shorts("ch:",dl_ch128+2);
+        //print_shorts("pack:",rho128+2);
+
+        dl_ch128+=3;
+        dl_ch128_2+=3;
+        rho128+=3;
+
+#elif defined(__arm_)
+
+
+#endif
+      }
+    }
+
+  }
+
+#if defined(__x86_64__) || defined(__i386__)
+  _mm_empty();
+  _m_empty();
+#endif
+}
+*/
+void pdcch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
+                         int32_t **rxdataF_comp,
+                         uint8_t symbol)
+{
+
+  uint8_t aatx;
+
+#if defined(__x86_64__) || defined(__i386__)
+  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1;
+#elif defined(__arm__)
+ int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1;
+#endif
+  int32_t i;
+
+  if (frame_parms->nb_antennas_rx>1) {
+    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
+#if defined(__x86_64__) || defined(__i386__)
+      rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
+      rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
+#elif defined(__arm__)
+      rxdataF_comp128_0   = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
+      rxdataF_comp128_1   = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
+#endif
+      // MRC on each re of rb
+      for (i=0; i<frame_parms->N_RB_DL*3; i++) {
+#if defined(__x86_64__) || defined(__i386__)
+        rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
+#elif defined(__arm__)
+        rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
+#endif
+      }
+    }
+  }
+
+#if defined(__x86_64__) || defined(__i386__)
+  _mm_empty();
+  _m_empty();
+#endif
+
+}
+
+void pdcch_siso(NR_DL_FRAME_PARMS *frame_parms,
+                int32_t **rxdataF_comp,
+                uint8_t l)
+{
+
+
+  uint8_t rb,re,jj,ii;
+
+  jj=0;
+  ii=0;
+
+  for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
+
+    for (re=0; re<12; re++) {
+
+      rxdataF_comp[0][jj++] = rxdataF_comp[0][ii];
+      ii++;
+    }
+  }
+}
+
+
+void pdcch_alamouti(NR_DL_FRAME_PARMS *frame_parms,
+                    int32_t **rxdataF_comp,
+                    uint8_t symbol)
+{
+
+
+  int16_t *rxF0,*rxF1;
+  uint8_t rb,re;
+  int32_t jj=(symbol*frame_parms->N_RB_DL*12);
+
+  rxF0     = (int16_t*)&rxdataF_comp[0][jj];  //tx antenna 0  h0*y
+  rxF1     = (int16_t*)&rxdataF_comp[2][jj];  //tx antenna 1  h1*y
+
+  for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
+
+    for (re=0; re<12; re+=2) {
+
+      // Alamouti RX combining
+
+      rxF0[0] = rxF0[0] + rxF1[2];
+      rxF0[1] = rxF0[1] - rxF1[3];
+
+      rxF0[2] = rxF0[2] - rxF1[0];
+      rxF0[3] = rxF0[3] + rxF1[1];
+
+      rxF0+=4;
+      rxF1+=4;
+    }
+  }
+
+
+}
+
+int32_t avgP[4];
+
+
+
+
+#ifdef NR_PDCCH_DCI_RUN
+int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
+                    uint32_t frame,
+                    uint8_t nr_tti_rx,
+                    uint8_t eNB_id,
+                    MIMO_mode_t mimo_mode,
+                    uint32_t high_speed_flag,
+                    uint8_t is_secondary_ue,
+                    int nb_coreset_active,
+                    uint16_t symbol_mon,
+                    int do_common) {
+
+	#ifdef MU_RECEIVER
+	uint8_t eNB_id_i=eNB_id+1; //add 1 to eNB_id to separate from wanted signal, chosen as the B/F'd pilots from the SeNB are shifted by 1
+#endif
+
+  NR_UE_COMMON *common_vars      = &ue->common_vars;
+  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  NR_UE_PDCCH **pdcch_vars       = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]];
+  NR_UE_PDCCH *pdcch_vars2       = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id];
+
+  uint8_t log2_maxh, aatx, aarx;
+  int32_t avgs;
+  uint8_t n_pdcch_symbols;
+  // the variable mi can be removed for NR
+  uint8_t mi = get_mi(frame_parms, nr_tti_rx);
+
+/*
+ * The following variables have been extracted from higher layer parameters
+ * MIB1 => pdcchConfigSIB1
+ * ControlResourceSet IE
+ * pdcch-Config
+ * pdcch-ConfigCommon
+ */
+
+/*
+ * initialize this values for testing
+ */
+#if 0
+        pdcch_vars2->coreset[nb_coreset_active].frequencyDomainResources                  = 0x1FFF2FF00000;
+        //pdcch_vars2->coreset[nb_coreset_active].frequencyDomainResources                  = 0x1E0000000000;
+        pdcch_vars2->coreset[nb_coreset_active].duration                                  = 2;
+        pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.shiftIndex            = 0;
+        pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.reg_bundlesize        = bundle_n6;
+        pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.interleaversize       = interleave_n2;
+        pdcch_vars2->coreset[nb_coreset_active].pdcchDMRSScramblingID                     = 1;
+        for (int i=0; i < NR_NBR_SEARCHSPACE_ACT_BWP; i++){
+          pdcch_vars[eNB_id]->searchSpace[i].nrofCandidates_aggrlevel1                      = 7;
+          pdcch_vars[eNB_id]->searchSpace[i].nrofCandidates_aggrlevel2                      = 6;
+          pdcch_vars[eNB_id]->searchSpace[i].nrofCandidates_aggrlevel4                      = 4;
+          pdcch_vars[eNB_id]->searchSpace[i].nrofCandidates_aggrlevel8                      = 3;
+          pdcch_vars[eNB_id]->searchSpace[i].nrofCandidates_aggrlevel16                     = 1;
+          pdcch_vars[eNB_id]->searchSpace[i].searchSpaceType.sfi_nrofCandidates_aggrlevel1  = 7;
+          pdcch_vars[eNB_id]->searchSpace[i].searchSpaceType.sfi_nrofCandidates_aggrlevel2  = 6;
+          pdcch_vars[eNB_id]->searchSpace[i].searchSpaceType.sfi_nrofCandidates_aggrlevel4  = 4;
+          pdcch_vars[eNB_id]->searchSpace[i].searchSpaceType.sfi_nrofCandidates_aggrlevel8  = 3;
+          pdcch_vars[eNB_id]->searchSpace[i].searchSpaceType.sfi_nrofCandidates_aggrlevel16 = 1;
+        }
+#endif //(0)
+/*
+ * to be removed after testing
+ */
+
+  // number of RB (1 symbol) or REG (12 RE) in one CORESET: higher-layer parameter CORESET-freq-dom
+  // (bit map 45 bits: each bit indicates 6 RB in CORESET -> 1 bit MSB indicates PRB 0..6 are part of CORESET)
+  uint64_t coreset_freq_dom                                 = pdcch_vars2->coreset[nb_coreset_active].frequencyDomainResources;
+  // number of symbols in CORESET: higher-layer parameter CORESET-time-dur {1,2,3}
+  int coreset_time_dur                                      = pdcch_vars2->coreset[nb_coreset_active].duration;
+  // depends on higher-layer parameter CORESET-shift-index {0,1,...,274}
+  int n_shift                                               = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.shiftIndex;
+  // higher-layer parameter CORESET-REG-bundle-size (for non-interleaved L = 6 / for interleaved L {2,6})
+  NR_UE_CORESET_REG_bundlesize_t reg_bundle_size_L          = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.reg_bundlesize;
+  // higher-layer parameter CORESET-interleaver-size {2,3,6}
+  NR_UE_CORESET_interleaversize_t coreset_interleaver_size_R= pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.interleaversize;
+  NR_UE_CORESET_precoder_granularity_t precoder_granularity = pdcch_vars2->coreset[nb_coreset_active].precoderGranularity;
+  int tci_statesPDCCH                                       = pdcch_vars2->coreset[nb_coreset_active].tciStatesPDCCH;
+  int tci_present                                           = pdcch_vars2->coreset[nb_coreset_active].tciPresentInDCI;
+  uint16_t pdcch_DMRS_scrambling_id                         = pdcch_vars2->coreset[nb_coreset_active].pdcchDMRSScramblingID;
+
+  // The UE can be assigned 4 different BWP but only one active at a time.
+  // For each BWP the number of CORESETs is limited to 3 (including initial CORESET Id=0 -> ControlResourceSetId (0..maxNrofControlReourceSets-1) (0..12-1)
+  uint32_t n_BWP_start = 0;
+  // start time position for CORESET
+  // parameter symbol_mon is a 14 bits bitmap indicating monitoring symbols within a slot
+  uint8_t start_symbol = 0;
+
+  // at the moment we are considering that the PDCCH is always starting at symbol 0 of current slot
+  // the following code to initialize start_symbol must be activated once we implement PDCCH demapping on symbol not equal to 0 (considering symbol_mon)
+  /*for (int i=0; i < 14; i++) {
+    if (symbol_mon >> (13-i) != 0) {
+      start_symbol = i;
+      i=14;
+    }
+  }*/
+
+  //
+  // according to 38.213 v15.1.0: a PDCCH monitoring pattern within a slot,
+  // indicating first symbol(s) of the control resource set within a slot
+  // for PDCCH monitoring, by higher layer parameter monitoringSymbolsWithinSlot
+  //
+  // at the moment we do not implement this and start_symbol is always 0
+  // note that the bitmap symbol_mon may indicate several monitoring times within a same slot (symbols 0..13)
+  // this may lead to a modification in ue scheduler
+
+  // indicates the number of active CORESETs for the current BWP to decode PDCCH: max is 3 (this variable is not useful here, to be removed)
+  uint8_t  coreset_nbr_act;
+  // indicates the number of REG contained in the PDCCH (number of RBs * number of symbols, in CORESET)
+  uint8_t  coreset_nbr_reg;
+  uint32_t coreset_C;
+  uint32_t coreset_nbr_rb = 0;
+
+  // for (int j=0; j < coreset_nbr_act; j++) {
+  // for each active CORESET (max number of active CORESETs in a BWP is 3),
+  // we calculate the number of RB for each CORESET bitmap
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%lld)\n",coreset_freq_dom);
+  #endif
+  int i; //for each bit in the coreset_freq_dom bitmap
+  for (i = 0; i < 45; i++) {
+    // this loop counts each bit of the bit map coreset_freq_dom, and increments nbr_RB_coreset for each bit set to '1'
+    if (((coreset_freq_dom & 0x1FFFFFFFFFFF) >> i) & 0x1) coreset_nbr_rb++;
+  }
+  coreset_nbr_rb = 6 * coreset_nbr_rb; // coreset_nbr_rb has to be multiplied by 6 to indicate the number of PRB or REG(=12 RE) within the CORESET
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%lld,%llx), coreset_nbr_rb=%d\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb);
+  #endif
+  coreset_nbr_reg = coreset_time_dur * coreset_nbr_rb;
+  coreset_C = (uint32_t)(coreset_nbr_reg / (reg_bundle_size_L * coreset_interleaver_size_R));
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_nbr_rb=%d, coreset_nbr_reg=%d, coreset_C=(%d/(%d*%d))=%d\n",
+            coreset_nbr_rb, coreset_nbr_reg, coreset_nbr_reg, reg_bundle_size_L,coreset_interleaver_size_R, coreset_C);
+  #endif
+
+  for (int s = start_symbol; s < (start_symbol + coreset_time_dur); s++) {
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter process pdcch ofdm symbol s=%d where coreset_time_dur=%d\n",s,coreset_time_dur);
+
+	if (is_secondary_ue == 1) {
+		pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF,
+				common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
+				pdcch_vars[eNB_id]->rxdataF_ext,
+				pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+				0,
+				high_speed_flag,
+				frame_parms);
+#ifdef MU_RECEIVER
+		pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF,
+				common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id_i - 1], //subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
+				pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
+				pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna
+				0,
+				high_speed_flag,
+				frame_parms);
+#endif //MU_RECEIVER
+	} else if (frame_parms->nb_antenna_ports_eNB>1) {
+		pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF,
+				common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id],
+				pdcch_vars[eNB_id]->rxdataF_ext,
+				pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+				0,
+				high_speed_flag,
+				frame_parms);
+	} else {
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_extract_rbs_single(is_secondary_ue=%d) to remove DM-RS PDCCH\n",
+              is_secondary_ue);
+    #endif
+    nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF,
+                                common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id],
+                                pdcch_vars[eNB_id]->rxdataF_ext,
+                                pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+                                s,
+                                high_speed_flag,
+                                frame_parms,
+                                coreset_freq_dom,
+                                coreset_nbr_rb,
+                                n_BWP_start);
+/*
+	printf("\t### in nr_rx_pdcch() function we enter pdcch_extract_rbs_single(is_secondary_ue=%d) to remove DM-RS PDCCH\n",is_secondary_ue);
+	pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF,
+			common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id],
+			pdcch_vars[eNB_id]->rxdataF_ext,
+			pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+			0,
+			high_speed_flag,
+			frame_parms);
+*/
+
+}
+
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",avgP);
+    #endif
+    // compute channel level based on ofdm symbol 0
+    pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+                        frame_parms,
+                        avgP,
+                        frame_parms->N_RB_DL);
+    avgs = 0;
+    for (aatx = 0; aatx < frame_parms->nb_antenna_ports_eNB; aatx++)
+      for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
+        avgs = cmax(avgs, avgP[(aarx << 1) + aatx]);
+    log2_maxh = (log2_approx(avgs) / 2) + 5;  //+frame_parms->nb_antennas_rx;
+#ifdef UE_DEBUG_TRACE
+LOG_D(PHY,"nr_tti_rx %d: pdcch log2_maxh = %d (%d,%d)\n",nr_tti_rx,log2_maxh,avgP[0],avgs);
+#endif
+
+#if T_TRACER
+T(T_UE_PHY_PDCCH_ENERGY, T_INT(eNB_id), T_INT(0), T_INT(frame%1024), T_INT(nr_tti_rx),
+  T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3]));
+#endif
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh);
+    #endif
+    // compute LLRs for ofdm symbol 0 only
+    nr_pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
+                                  pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+                                  pdcch_vars[eNB_id]->rxdataF_comp,
+                                  (aatx > 1) ? pdcch_vars[eNB_id]->rho : NULL,
+                                  frame_parms,
+                                  s,
+                                  log2_maxh,
+                                  coreset_nbr_rb); // log2_maxh+I0_shift
+
+/*
+printf("\t### in nr_rx_pdcch() function we enter pdcch_channel_compensation(log2_maxh=%d) => compute LLRs for ofdm symbol 0 only, pdcch_vars[eNB_id]->rxdataF_ext ---> pdcch_vars[eNB_id]->rxdataF_comp\n",log2_maxh);
+
+			// compute LLRs for ofdm symbol 0 only
+			pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
+					pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+					pdcch_vars[eNB_id]->rxdataF_comp,
+					(aatx>1) ? pdcch_vars[eNB_id]->rho : NULL,
+					frame_parms,
+					0,
+					log2_maxh);// log2_maxh+I0_shift
+*/
+
+
+#ifdef DEBUG_PHY
+
+	if (nr_tti_rx==5)
+	write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+
+#endif
+
+#ifdef MU_RECEIVER
+
+	if (is_secondary_ue) {
+		//get MF output for interfering stream
+		pdcch_channel_compensation(pdcch_vars[eNB_id_i]->rxdataF_ext,
+				pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
+				pdcch_vars[eNB_id_i]->rxdataF_comp,
+				(aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL,
+				frame_parms,
+				0,
+				log2_maxh);// log2_maxh+I0_shift
+#ifdef DEBUG_PHY
+		write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+#endif
+		pdcch_dual_stream_correlation(frame_parms,
+				0,
+				pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+				pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
+				pdcch_vars[eNB_id]->dl_ch_rho_ext,
+				log2_maxh);
+	}
+
+#endif //MU_RECEIVER
+
+    if (frame_parms->nb_antennas_rx > 1) {
+#ifdef MU_RECEIVER
+
+		if (is_secondary_ue) {
+			pdcch_detection_mrc_i(frame_parms,
+					pdcch_vars[eNB_id]->rxdataF_comp,
+					pdcch_vars[eNB_id_i]->rxdataF_comp,
+					pdcch_vars[eNB_id]->rho,
+					pdcch_vars[eNB_id]->dl_ch_rho_ext,
+					0);
+#ifdef DEBUG_PHY
+			write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+			write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+#endif
+		} else
+#endif //MU_RECEIVER
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n",
+                frame_parms->nb_antennas_rx);
+      #endif
+      pdcch_detection_mrc(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp,s);
+    }
+    if (mimo_mode == SISO) {
+      #ifdef NR_PDCCH_DCI_DEBUG
+       printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter pdcch_siso(for symbol 0) ---> pdcch_vars[eNB_id]->rxdataF_comp\n");
+      #endif
+      pdcch_siso(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp,s);
+    } else pdcch_alamouti(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp,s);
+
+#ifdef MU_RECEIVER
+
+	if (is_secondary_ue) {
+		pdcch_qpsk_qpsk_llr(frame_parms,
+				pdcch_vars[eNB_id]->rxdataF_comp,
+				pdcch_vars[eNB_id_i]->rxdataF_comp,
+				pdcch_vars[eNB_id]->dl_ch_rho_ext,
+				pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder)
+				pdcch_vars[eNB_id]->llr,
+				0);
+		/*
+		 #ifdef DEBUG_PHY
+		 if (subframe==5) {
+		 write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
+		 write_output("llr16_seq.m","llr16",&pdcch_vars[eNB_id]->llr16[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
+		 }
+		 #endif*/
+	} else {
+#endif //MU_RECEIVER
+
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s);
+    #endif
+    nr_pdcch_llr(frame_parms,
+                 pdcch_vars[eNB_id]->rxdataF_comp,
+                 (char *) pdcch_vars[eNB_id]->llr,
+                 s,
+                 coreset_nbr_rb);
+    /*
+    printf("\t### in nr_rx_pdcch() function we enter pdcch_llr(for symbol 0), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n");
+    pdcch_llr(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp,(char *) pdcch_vars[eNB_id]->llr, 0);
+    */
+    /*#ifdef DEBUG_PHY
+    write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
+    #endif*/
+
+#ifdef MU_RECEIVER
+}
+#endif //MU_RECEIVER
+
+#if T_TRACER
+T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL),
+  T_INT(n_pdcch_symbols),
+  T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4));
+#endif
+
+    /* We do not enter this function: in NR the number of PDCCH symbols is determined by higher layers parameter CORESET-time-dur
+    /*/
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we do not enter function rx_pcfich()\n as the number of PDCCH symbols is determined by higher layers parameter CORESET-time-dur and n_pdcch_symbols=%d\n",n_pdcch_symbols);
+    /*
+    // decode pcfich here and find out pdcch ofdm symbol number
+    n_pdcch_symbols = rx_pcfich(frame_parms, nr_tti_rx, pdcch_vars[eNB_id],mimo_mode);
+    if (n_pdcch_symbols > 3) n_pdcch_symbols = 1;
+    */
+#ifdef DEBUG_DCI_DECODING
+	printf("demapping: nr_tti_rx %d, mi %d, tdd_config %d\n",nr_tti_rx,get_mi(frame_parms,nr_tti_rx),frame_parms->tdd_config);
+#endif
+
+  }
+
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_demapping()\n");
+  #endif
+  nr_pdcch_demapping(pdcch_vars[eNB_id]->llr,
+                     pdcch_vars[eNB_id]->wbar,
+                     frame_parms,
+                     coreset_time_dur,
+                     coreset_nbr_rb);
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_deinterleaving()\n");
+  #endif
+  nr_pdcch_deinterleaving(frame_parms,
+                          (uint16_t*) pdcch_vars[eNB_id]->e_rx,
+                          pdcch_vars[eNB_id]->wbar,
+                          coreset_time_dur,
+                          reg_bundle_size_L,
+                          coreset_interleaver_size_R,
+                          n_shift,
+                          coreset_nbr_rb);
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_unscrambling()\n");
+  #endif
+  nr_pdcch_unscrambling(pdcch_vars[eNB_id]->crnti,
+                        frame_parms,
+                        nr_tti_rx,
+                        pdcch_vars[eNB_id]->e_rx,
+                        coreset_time_dur*coreset_nbr_rb*9*2,
+                        // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72,
+                        pdcch_DMRS_scrambling_id,
+                        do_common);
+/*
+	printf("\t### in nr_rx_pdcch() function we enter pdcch_demapping()\n");
+
+	pdcch_demapping(pdcch_vars[eNB_id]->llr,
+			pdcch_vars[eNB_id]->wbar,
+			frame_parms,
+			n_pdcch_symbols,
+			get_mi(frame_parms,nr_tti_rx));
+
+	printf("\t### in nr_rx_pdcch() function we enter pdcch_deinterleaving()\n");
+
+	pdcch_deinterleaving(frame_parms,
+			(uint16_t*)pdcch_vars[eNB_id]->e_rx,
+			pdcch_vars[eNB_id]->wbar,
+			n_pdcch_symbols,
+			mi);
+
+	printf("\t### in nr_rx_pdcch() function we enter pdcch_unscrambling()\n");
+
+	pdcch_unscrambling(frame_parms,
+			nr_tti_rx,
+			pdcch_vars[eNB_id]->e_rx,
+			get_nCCE(n_pdcch_symbols,frame_parms,mi)*72);
+*/
+
+	pdcch_vars[eNB_id]->num_pdcch_symbols = n_pdcch_symbols;
+
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> Ending nr_rx_pdcch() function\n");
+  #endif
+  return (0);
+}
+#endif
+
+
+
+void pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms,
+                      uint8_t nr_tti_rx,
+                      uint8_t *e,
+                      uint32_t length)
+{
+  int i;
+  uint8_t reset;
+  uint32_t x1, x2, s=0;
+
+  reset = 1;
+  // x1 is set in lte_gold_generic
+
+  x2 = (nr_tti_rx<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2
+
+  for (i=0; i<length; i++) {
+    if ((i&0x1f)==0) {
+      s = lte_gold_generic(&x1, &x2, reset);
+      //printf("lte_gold[%d]=%x\n",i,s);
+      reset = 0;
+    }
+
+    //    printf("scrambling %d : e %d, c %d\n",i,e[i],((s>>(i&0x1f))&1));
+    if (e[i] != 2) // <NIL> element is 2
+      e[i] = (e[i]&1) ^ ((s>>(i&0x1f))&1);
+  }
+}
+
+
+#ifdef NR_PDCCH_DCI_RUN
+
+void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t nr_tti_rx,
+		int8_t* llr, uint32_t length, uint16_t pdcch_DMRS_scrambling_id, int do_common) {
+
+	int i;
+	uint8_t reset;
+	uint32_t x1, x2, s = 0;
+  uint16_t n_id; //{0,1,...,65535}
+  uint32_t n_rnti;
+
+	reset = 1;
+	// x1 is set in first call to lte_gold_generic
+	//do_common=1;
+if (do_common){
+  n_id = frame_parms->Nid_cell;
+  n_rnti = 0;
+} else {
+  n_id = pdcch_DMRS_scrambling_id;
+  n_rnti = (uint32_t)crnti;
+}
+//x2 = ((n_rnti * (1 << 16)) + n_id)%(1 << 31);
+//uint32_t puissance_2_16 = ((1<<16)*n_rnti)+n_id;
+//uint32_t puissance_2_31= (1<<30)*2;
+//uint32_t calc_x2=puissance_2_16%puissance_2_31;
+    x2 = (((1<<16)*n_rnti)+n_id)%((1<<30)*2); //this is c_init in 38.211 v15.1.0 Section 7.3.2.3
+//	x2 = (nr_tti_rx << 9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2
+#ifdef NR_PDCCH_DCI_DEBUG
+printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)->  (c_init=%d, n_id=%d, n_rnti=%d)\n",x2,n_id,n_rnti);
+#endif
+	for (i = 0; i < length; i++) {
+		if ((i & 0x1f) == 0) {
+			s = lte_gold_generic(&x1, &x2, reset);
+			//      printf("lte_gold[%d]=%x\n",i,s);
+			reset = 0;
+		}
+
+		//    printf("unscrambling %d : e %d, c %d => ",i,llr[i],((s>>(i&0x1f))&1));
+		if (((s >> (i % 32)) & 1) == 0)
+			llr[i] = -llr[i];
+		//    printf("%d\n",llr[i]);
+
+	}
+}
+
+
+#endif
+
+
+
+
+void pdcch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
+                        uint8_t nr_tti_rx,
+                        int8_t* llr,
+                        uint32_t length)
+{
+
+  int i;
+  uint8_t reset;
+  uint32_t x1, x2, s=0;
+
+  reset = 1;
+  // x1 is set in first call to lte_gold_generic
+
+  x2 = (nr_tti_rx<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2
+
+  for (i=0; i<length; i++) {
+    if ((i&0x1f)==0) {
+      s = lte_gold_generic(&x1, &x2, reset);
+      //      printf("lte_gold[%d]=%x\n",i,s);
+      reset = 0;
+    }
+
+    
+    //    printf("unscrambling %d : e %d, c %d => ",i,llr[i],((s>>(i&0x1f))&1));
+    if (((s>>(i%32))&1)==0)
+      llr[i] = -llr[i];
+    //    printf("%d\n",llr[i]);
+
+  }
+}
+
+
+/*uint8_t get_num_pdcch_symbols(uint8_t num_dci,
+                              DCI_ALLOC_t *dci_alloc,
+                              NR_DL_FRAME_PARMS *frame_parms,
+                              uint8_t nr_tti_rx)
+{
+
+  uint16_t numCCE = 0;
+  uint8_t i;
+  uint8_t nCCEmin = 0;
+  uint16_t CCE_max_used_index = 0;
+  uint16_t firstCCE_max = dci_alloc[0].firstCCE;
+  uint8_t  L = dci_alloc[0].L;
+
+  // check pdcch duration imposed by PHICH duration (Section 6.9 of 36-211)
+  if (frame_parms->Ncp==1) { // extended prefix
+    if ((frame_parms->frame_type == TDD) &&
+        ((frame_parms->tdd_config<3)||(frame_parms->tdd_config==6)) &&
+        ((nr_tti_rx==1) || (nr_tti_rx==6))) // subframes 1 and 6 (S-subframes) for 5ms switching periodicity are 2 symbols
+      nCCEmin = 2;
+    else {   // 10ms switching periodicity is always 3 symbols, any DL-only subframe is 3 symbols
+      nCCEmin = 3;
+    }
+  }
+
+  // compute numCCE
+  for (i=0; i<num_dci; i++) {
+    //     printf("dci %d => %d\n",i,dci_alloc[i].L);
+    numCCE += (1<<(dci_alloc[i].L));
+
+    if(firstCCE_max < dci_alloc[i].firstCCE) {
+      firstCCE_max = dci_alloc[i].firstCCE;
+      L            = dci_alloc[i].L;
+    }
+  }
+  CCE_max_used_index = firstCCE_max + (1<<L) - 1;
+
+  //if ((9*numCCE) <= (frame_parms->N_RB_DL*2))
+  if (CCE_max_used_index < get_nCCE(1, frame_parms, get_mi(frame_parms, nr_tti_rx)))
+    return(cmax(1,nCCEmin));
+  //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 4 : 5)))
+  else if (CCE_max_used_index < get_nCCE(2, frame_parms, get_mi(frame_parms, nr_tti_rx)))
+    return(cmax(2,nCCEmin));
+  //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 7 : 8)))
+  else if (CCE_max_used_index < get_nCCE(3, frame_parms, get_mi(frame_parms, nr_tti_rx)))
+    return(cmax(3,nCCEmin));
+  else if (frame_parms->N_RB_DL<=10) {
+    if (frame_parms->Ncp == 0) { // normal CP
+      printf("numCCE %d, N_RB_DL = %d : should be returning 4 PDCCH symbols (%d,%d,%d)\n",numCCE,frame_parms->N_RB_DL,
+             get_nCCE(1, frame_parms, get_mi(frame_parms, nr_tti_rx)),
+             get_nCCE(2, frame_parms, get_mi(frame_parms, nr_tti_rx)),
+             get_nCCE(3, frame_parms, get_mi(frame_parms, nr_tti_rx)));
+
+      if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 10 : 11)))
+        return(4);
+    } else { // extended CP
+      if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 9 : 10)))
+        return(4);
+    }
+  }
+
+
+  LOG_D(PHY," dci.c: get_num_pdcch_symbols nr_tti_rx %d FATAL, illegal numCCE %d (num_dci %d)\n",nr_tti_rx,numCCE,num_dci);
+  //for (i=0;i<num_dci;i++) {
+  //  printf("dci_alloc[%d].L = %d\n",i,dci_alloc[i].L);
+  //}
+  //exit(-1);
+  return(0);
+}
+
+uint8_t generate_dci_top(int num_dci,
+                         DCI_ALLOC_t *dci_alloc,
+                         uint32_t n_rnti,
+                         int16_t amp,
+                         NR_DL_FRAME_PARMS *frame_parms,
+                         int32_t **txdataF,
+                         uint32_t nr_tti_rx)
+{
+
+  uint8_t *e_ptr,num_pdcch_symbols;
+  uint32_t i, lprime;
+  uint32_t gain_lin_QPSK,kprime,kprime_mod12,mprime,nsymb,symbol_offset,tti_offset;
+  int16_t re_offset;
+  uint8_t mi = get_mi(frame_parms,nr_tti_rx);
+  static uint8_t e[DCI_BITS_MAX];
+  static int32_t yseq0[Msymb],yseq1[Msymb],wbar0[Msymb],wbar1[Msymb];
+
+  int32_t *y[2];
+  int32_t *wbar[2];
+
+  int nushiftmod3 = frame_parms->nushift%3;
+
+  int Msymb2;
+  int split_flag=0;
+
+  switch (frame_parms->N_RB_DL) {
+  case 100:
+    Msymb2 = Msymb;
+    break;
+
+  case 75:
+    Msymb2 = 3*Msymb/4;
+    break;
+
+  case 50:
+    Msymb2 = Msymb>>1;
+    break;
+
+  case 25:
+    Msymb2 = Msymb>>2;
+    break;
+
+  case 15:
+    Msymb2 = Msymb*15/100;
+    break;
+
+  case 6:
+    Msymb2 = Msymb*6/100;
+    break;
+
+  default:
+    Msymb2 = Msymb>>2;
+    break;
+  }
+
+  num_pdcch_symbols = get_num_pdcch_symbols(num_dci,dci_alloc,frame_parms,nr_tti_rx);
+  //  printf("nr_tti_rx %d in generate_dci_top num_pdcch_symbols = %d, num_dci %d\n",
+  //     nr_tti_rx,num_pdcch_symbols,num_dci);
+  generate_pcfich(num_pdcch_symbols,
+                  amp,
+                  frame_parms,
+                  txdataF,
+                  nr_tti_rx);
+  wbar[0] = &wbar0[0];
+  wbar[1] = &wbar1[0];
+  y[0] = &yseq0[0];
+  y[1] = &yseq1[0];
+
+  // reset all bits to <NIL>, here we set <NIL> elements as 2
+  // memset(e, 2, DCI_BITS_MAX);
+  // here we interpret NIL as a random QPSK sequence. That makes power estimation easier.
+  for (i=0; i<DCI_BITS_MAX; i++)
+    e[i]=taus()&1;
+
+  e_ptr = e;
+
+  // generate DCIs
+  for (i=0; i<num_dci; i++) {
+#ifdef DEBUG_DCI_ENCODING
+    printf("Generating %s DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x)\n",
+           dci_alloc[i].search_space == DCI_COMMON_SPACE ? "common" : "UE",
+           i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,1<<dci_alloc[i].L,
+          *(unsigned int*)dci_alloc[i].dci_pdu);
+    dump_dci(frame_parms,&dci_alloc[i]);
+#endif
+
+    if (dci_alloc[i].firstCCE>=0) {
+      e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
+                            e+(72*dci_alloc[i].firstCCE),
+                            dci_alloc[i].dci_length,
+                            dci_alloc[i].L,
+                            dci_alloc[i].rnti);
+    }
+  }
+
+  // Scrambling
+  //  printf("pdcch scrambling\n");
+  pdcch_scrambling(frame_parms,
+                   nr_tti_rx,
+                   e,
+                   8*get_nquad(num_pdcch_symbols, frame_parms, mi));
+  //72*get_nCCE(num_pdcch_symbols,frame_parms,mi));
+
+
+
+
+  // Now do modulation
+  if (frame_parms->mode1_flag==1)
+    gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
+  else
+    gain_lin_QPSK = amp/2;
+
+  e_ptr = e;
+
+#ifdef DEBUG_DCI_ENCODING
+  printf(" PDCCH Modulation, Msymb %d, Msymb2 %d,gain_lin_QPSK %d\n",Msymb,Msymb2,gain_lin_QPSK);
+#endif
+
+
+  if (frame_parms->mode1_flag) { //SISO
+
+
+    for (i=0; i<Msymb2; i++) {
+      
+      //((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+      //((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+      ((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+      ((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+      e_ptr++;
+      //((int16_t*)(&(y[0][i])))[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+      //((int16_t*)(&(y[1][i])))[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+      ((int16_t*)(&(y[0][i])))[1] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+      ((int16_t*)(&(y[1][i])))[1] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+
+      e_ptr++;
+    }
+  } else { //ALAMOUTI
+
+
+    for (i=0; i<Msymb2; i+=2) {
+
+#ifdef DEBUG_DCI_ENCODING
+      printf(" PDCCH Modulation (TX diversity): REG %d\n",i>>2);
+#endif
+      // first antenna position n -> x0
+      ((int16_t*)&y[0][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+      e_ptr++;
+      ((int16_t*)&y[0][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+      e_ptr++;
+
+      // second antenna position n -> -x1*
+      ((int16_t*)&y[1][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK;
+      e_ptr++;
+      ((int16_t*)&y[1][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+      e_ptr++;
+
+      // fill in the rest of the ALAMOUTI precoding
+      ((int16_t*)&y[0][i+1])[0] = -((int16_t*)&y[1][i])[0];
+      ((int16_t*)&y[0][i+1])[1] = ((int16_t*)&y[1][i])[1];
+      ((int16_t*)&y[1][i+1])[0] = ((int16_t*)&y[0][i])[0];
+      ((int16_t*)&y[1][i+1])[1] = -((int16_t*)&y[0][i])[1];
+
+    }
+  }
+
+
+#ifdef DEBUG_DCI_ENCODING
+  printf(" PDCCH Interleaving\n");
+#endif
+
+  //  printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]);
+  // This is the interleaving procedure defined in 36-211, first part of Section 6.8.5
+  pdcch_interleaving(frame_parms,&y[0],&wbar[0],num_pdcch_symbols,mi);
+
+  mprime=0;
+  nsymb = (frame_parms->Ncp==0) ? 14:12;
+  re_offset = frame_parms->first_carrier_offset;
+
+  // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5
+  //  printf("DCI (SF %d) : txdataF %p (0 %p)\n",subframe,&txdataF[0][512*14*subframe],&txdataF[0][0]);
+  for (kprime=0; kprime<frame_parms->N_RB_DL*12; kprime++) {
+    for (lprime=0; lprime<num_pdcch_symbols; lprime++) {
+
+      symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(lprime+(nr_tti_rx*nsymb));
+
+
+
+      tti_offset = symbol_offset + re_offset;
+
+      (re_offset==(frame_parms->ofdm_symbol_size-2)) ? (split_flag=1) : (split_flag=0);
+
+      //            printf("kprime %d, lprime %d => REG %d (symbol %d)\n",kprime,lprime,(lprime==0)?(kprime/6) : (kprime>>2),symbol_offset);
+      // if REG is allocated to PHICH, skip it
+      if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) {
+#ifdef DEBUG_DCI_ENCODING
+        printf("generate_dci: skipping REG %d (kprime %d, lprime %d)\n",(lprime==0)?(kprime/6) : (kprime>>2),kprime,lprime);
+#endif
+      } else {
+        // Copy REG to TX buffer
+
+        if ((lprime == 0)||
+            ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) {
+          // first symbol, or second symbol+4 TX antennas skip pilots
+
+          kprime_mod12 = kprime%12;
+
+          if ((kprime_mod12 == 0) || (kprime_mod12 == 6)) {
+            // kprime represents REG
+
+            for (i=0; i<6; i++) {
+              if ((i!=(nushiftmod3))&&(i!=(nushiftmod3+3))) {
+                txdataF[0][tti_offset+i] = wbar[0][mprime];
+
+                if (frame_parms->nb_antenna_ports_eNB > 1)
+                  txdataF[1][tti_offset+i] = wbar[1][mprime];
+
+#ifdef DEBUG_DCI_ENCODING
+                printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+#endif
+
+                mprime++;
+              }
+            }
+          }
+        } else { // no pilots in this symbol
+          kprime_mod12 = kprime%12;
+
+          if ((kprime_mod12 == 0) || (kprime_mod12 == 4) || (kprime_mod12 == 8)) {
+            // kprime represents REG
+            if (split_flag==0) {
+              for (i=0; i<4; i++) {
+                txdataF[0][tti_offset+i] = wbar[0][mprime];
+
+                if (frame_parms->nb_antenna_ports_eNB > 1)
+                  txdataF[1][tti_offset+i] = wbar[1][mprime];
+
+#ifdef DEBUG_DCI_ENCODING
+                LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+#endif
+                mprime++;
+              }
+            } else {
+              txdataF[0][tti_offset+0] = wbar[0][mprime];
+
+              if (frame_parms->nb_antenna_ports_eNB > 1)
+                txdataF[1][tti_offset+0] = wbar[1][mprime];
+
+#ifdef DEBUG_DCI_ENCODING
+              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+#endif
+              mprime++;
+              txdataF[0][tti_offset+1] = wbar[0][mprime];
+
+              if (frame_parms->nb_antenna_ports_eNB > 1)
+                txdataF[1][tti_offset+1] = wbar[1][mprime];
+
+#ifdef DEBUG_DCI_ENCODING
+              printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+#endif
+              mprime++;
+              txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[0][mprime];
+
+              if (frame_parms->nb_antenna_ports_eNB > 1)
+                txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[1][mprime];
+
+#ifdef DEBUG_DCI_ENCODING
+              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short*)&wbar[0][mprime],
+                    *(1+(short*)&wbar[0][mprime]));
+#endif
+              mprime++;
+              txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[0][mprime];
+
+              if (frame_parms->nb_antenna_ports_eNB > 1)
+                txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[1][mprime];
+
+#ifdef DEBUG_DCI_ENCODING
+              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short*)&wbar[0][mprime],
+                    *(1+(short*)&wbar[0][mprime]));
+#endif
+              mprime++;
+
+            }
+          }
+        }
+
+        if (mprime>=Msymb2)
+          return(num_pdcch_symbols);
+      } // check_phich_reg
+
+    } //lprime loop
+
+    re_offset++;
+
+    if (re_offset == (frame_parms->ofdm_symbol_size))
+      re_offset = 1;
+  } // kprime loop
+
+  return(num_pdcch_symbols);
+}
+*/
+#ifdef PHY_ABSTRACTION
+uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB,
+                              int num_dci,
+                              DCI_ALLOC_t *dci_alloc,
+                              uint8_t subframe)
+{
+  int n_dci, n_dci_dl;
+  uint8_t ue_id;
+  LTE_eNB_DLSCH_t *dlsch_eNB;
+  int num_ue_spec_dci;
+  int num_common_dci;
+  int i;
+  uint8_t num_pdcch_symbols = get_num_pdcch_symbols(num_dci,
+                              dci_alloc,
+                              &phy_vars_eNB->frame_parms,
+                              subframe);
+  eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.cfi=num_pdcch_symbols;
+
+  num_ue_spec_dci = 0;
+  num_common_dci = 0;
+  for (i = 0; i < num_dci; i++) {
+    /* TODO: maybe useless test, to remove? */
+    if (!(dci_alloc[i].firstCCE>=0)) abort();
+    if (dci_alloc[i].search_space == DCI_COMMON_SPACE)
+      num_common_dci++;
+    else
+      num_ue_spec_dci++;
+  }
+
+  memcpy(phy_vars_eNB->dci_alloc[subframe&1],dci_alloc,sizeof(DCI_ALLOC_t)*(num_dci));
+  phy_vars_eNB->num_ue_spec_dci[subframe&1]=num_ue_spec_dci;
+  phy_vars_eNB->num_common_dci[subframe&1]=num_common_dci;
+  eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_ue_spec_dci = num_ue_spec_dci;
+  eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_common_dci = num_common_dci;
+
+  LOG_D(PHY,"[eNB %d][DCI][EMUL] CC id %d:  num spec dci %d num comm dci %d num PMCH %d \n",
+        phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, num_ue_spec_dci,num_common_dci,
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_pmch);
+
+  if (eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.pmch_flag == 1 )
+    n_dci_dl = eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_pmch;
+  else
+    n_dci_dl = 0;
+
+  for (n_dci =0 ;
+       n_dci < (eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_ue_spec_dci+ eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_common_dci);
+       n_dci++) {
+
+    if (dci_alloc[n_dci].format > 0) { // exclude the uplink dci
+
+      if (dci_alloc[n_dci].rnti == SI_RNTI) {
+        dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch_SI;
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 0;//SI;
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = 0;
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[0]->TBS>>3;
+        LOG_D(PHY,"[DCI][EMUL]SI tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl,
+              eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]);
+      } else if (dci_alloc[n_dci_dl].ra_flag == 1) {
+        dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch_ra;
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 1;//RA;
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = 0;
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[0]->TBS>>3;
+        LOG_D(PHY,"[DCI][EMUL] RA  tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl,
+              eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]);
+      } else {
+        ue_id = find_ue(dci_alloc[n_dci_dl].rnti,PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]);
+        DevAssert( ue_id != (uint8_t)-1 );
+        dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch[ue_id][0];
+
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 2;//TB0;
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = dlsch_eNB->current_harq_pid;
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].ue_id[n_dci_dl] = ue_id;
+        eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[dlsch_eNB->current_harq_pid]->TBS>>3;
+        LOG_D(PHY,"[DCI][EMUL] TB1 tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl,
+              eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]);
+        // check for TB1 later
+
+      }
+    }
+
+    n_dci_dl++;
+  }
+
+  memcpy((void *)&eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dci_alloc,
+         (void *)dci_alloc,
+         n_dci*sizeof(DCI_ALLOC_t));
+
+  return(num_pdcch_symbols);
+}
+#endif
+
+
+void dci_decoding(uint8_t DCI_LENGTH,
+                  uint8_t aggregation_level,
+                  int8_t *e,
+                  uint8_t *decoded_output)
+{
+
+  uint8_t dummy_w_rx[3*(MAX_DCI_SIZE_BITS+16+64)];
+  int8_t w_rx[3*(MAX_DCI_SIZE_BITS+16+32)],d_rx[96+(3*(MAX_DCI_SIZE_BITS+16))];
+
+  uint16_t RCC;
+
+  uint16_t D=(DCI_LENGTH+16+64);
+  uint16_t coded_bits;
+#ifdef DEBUG_DCI_DECODING
+  int32_t i;
+#endif
+
+  if (aggregation_level>3) {
+    LOG_I(PHY," dci.c: dci_decoding FATAL, illegal aggregation_level %d\n",aggregation_level);
+    return;
+  }
+
+  coded_bits = 72 * (1<<aggregation_level);
+
+#ifdef DEBUG_DCI_DECODING
+  LOG_I(PHY," Doing DCI decoding for %d bits, DCI_LENGTH %d,coded_bits %d, e %p\n",3*(DCI_LENGTH+16),DCI_LENGTH,coded_bits,e);
+#endif
+
+  // now do decoding
+  memset((void*)dummy_w_rx,0,3*D);
+  RCC = generate_dummy_w_cc(DCI_LENGTH+16,
+                            dummy_w_rx);
+
+
+
+#ifdef DEBUG_DCI_DECODING
+  LOG_I(PHY," Doing DCI Rate Matching RCC %d, w %p\n",RCC,w);
+#endif
+
+  lte_rate_matching_cc_rx(RCC,coded_bits,w_rx,dummy_w_rx,e);
+
+  sub_block_deinterleaving_cc((uint32_t)(DCI_LENGTH+16),
+                              &d_rx[96],
+                              &w_rx[0]);
+
+#ifdef DEBUG_DCI_DECODING
+
+  for (i=0; i<16+DCI_LENGTH; i++)
+    LOG_I(PHY," DCI %d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i)));
+
+#endif
+  memset(decoded_output,0,2+((16+DCI_LENGTH)>>3));
+
+#ifdef DEBUG_DCI_DECODING
+  printf("Before Viterbi\n");
+
+  for (i=0; i<16+DCI_LENGTH; i++)
+    printf("%d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i)));
+
+#endif
+  //debug_printf("Doing DCI Viterbi \n");
+  phy_viterbi_lte_sse2(d_rx+96,decoded_output,16+DCI_LENGTH);
+  //debug_printf("Done DCI Viterbi \n");
+}
+
+
+static uint8_t dci_decoded_output[RX_NB_TH][(MAX_DCI_SIZE_BITS+64)/8];
+
+/*uint16_t get_nCCE(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi)
+{
+  return(get_nquad(num_pdcch_symbols,frame_parms,mi)/9);
+}
+
+uint16_t get_nquad(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi)
+{
+
+  uint16_t Nreg=0;
+  uint8_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
+
+  if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
+    Ngroup_PHICH++;
+
+  if (frame_parms->Ncp == 1) {
+    Ngroup_PHICH<<=1;
+  }
+
+  Ngroup_PHICH*=mi;
+
+  if ((num_pdcch_symbols>0) && (num_pdcch_symbols<4))
+    switch (frame_parms->N_RB_DL) {
+    case 6:
+      Nreg=12+(num_pdcch_symbols-1)*18;
+      break;
+
+    case 25:
+      Nreg=50+(num_pdcch_symbols-1)*75;
+      break;
+
+    case 50:
+      Nreg=100+(num_pdcch_symbols-1)*150;
+      break;
+
+    case 100:
+      Nreg=200+(num_pdcch_symbols-1)*300;
+      break;
+
+    default:
+      return(0);
+    }
+
+  //   printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH));
+  return(Nreg - 4 - (3*Ngroup_PHICH));
+}
+
+uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int nr_tti_rx)
+{
+
+  // check for eNB only !
+  return(get_nCCE(num_pdcch_symbols,
+		  &PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,
+		  get_mi(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,nr_tti_rx)));
+}
+*/
+
+int get_nCCE_offset_l1(int *CCE_table,
+		       const unsigned char L, 
+		       const int nCCE, 
+		       const int common_dci, 
+		       const unsigned short rnti, 
+		       const unsigned char nr_tti_rx)
+{
+
+  int search_space_free,m,nb_candidates = 0,l,i;
+  unsigned int Yk;
+   /*
+    printf("CCE Allocation: ");
+    for (i=0;i<nCCE;i++)
+    printf("%d.",CCE_table[i]);
+    printf("\n");
+  */
+  if (common_dci == 1) {
+    // check CCE(0 ... L-1)
+    nb_candidates = (L==4) ? 4 : 2;
+    nb_candidates = min(nb_candidates,nCCE/L);
+
+    //    printf("Common DCI nb_candidates %d, L %d\n",nb_candidates,L);
+
+    for (m = nb_candidates-1 ; m >=0 ; m--) {
+
+      search_space_free = 1;
+      for (l=0; l<L; l++) {
+
+	//	printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]);
+        if (CCE_table[(m*L) + l] == 1) {
+          search_space_free = 0;
+          break;
+        }
+      }
+     
+      if (search_space_free == 1) {
+
+	//	printf("returning %d\n",m*L);
+
+        for (l=0; l<L; l++)
+          CCE_table[(m*L)+l]=1;
+        return(m*L);
+      }
+    }
+
+    return(-1);
+
+  } else { // Find first available in ue specific search space
+    // according to procedure in Section 9.1.1 of 36.213 (v. 8.6)
+    // compute Yk
+    Yk = (unsigned int)rnti;
+
+    for (i=0; i<=nr_tti_rx; i++)
+      Yk = (Yk*39827)%65537;
+
+    Yk = Yk % (nCCE/L);
+
+
+    switch (L) {
+    case 1:
+    case 2:
+      nb_candidates = 6;
+      break;
+
+    case 4:
+    case 8:
+      nb_candidates = 2;
+      break;
+
+    default:
+      DevParam(L, nCCE, rnti);
+      break;
+    }
+
+
+    LOG_D(MAC,"rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n",rnti,Yk,nCCE,nCCE/L,nb_candidates);
+
+    for (m = 0 ; m < nb_candidates ; m++) {
+      search_space_free = 1;
+
+      for (l=0; l<L; l++) {
+        int cce = (((Yk+m)%(nCCE/L))*L) + l;
+        if (cce >= nCCE || CCE_table[cce] == 1) {
+          search_space_free = 0;
+          break;
+        }
+      }
+
+      if (search_space_free == 1) {
+        for (l=0; l<L; l++)
+          CCE_table[(((Yk+m)%(nCCE/L))*L)+l]=1;
+
+        return(((Yk+m)%(nCCE/L))*L);
+      }
+    }
+
+    return(-1);
+  }
+}
+
+
+
+
+#ifdef NR_PDCCH_DCI_RUN
+void nr_dci_decoding_procedure0(int s,
+                                int p,
+                                NR_UE_PDCCH **pdcch_vars,
+                                int do_common,
+                                //dci_detect_mode_t mode,
+                                uint8_t nr_tti_rx,
+                                NR_DCI_ALLOC_t *dci_alloc,
+                                // uint8_t nr_tti_rx, NR_DCI_ALLOC_t *dci_alloc,
+                                int16_t eNB_id,
+                                uint8_t current_thread_id,
+                                NR_DL_FRAME_PARMS *frame_parms,
+                                uint8_t mi,
+                                uint16_t si_rnti,
+                                uint16_t ra_rnti,
+                                uint16_t p_rnti,
+                                uint16_t tc_rnti,
+                                uint16_t int_rnti,
+                                uint16_t sfi_rnti,
+                                uint16_t tpc_pusch_rnti,
+                                uint16_t tpc_pucch_rnti,
+                                uint16_t tpc_srs_rnti,
+                                uint8_t L,
+                                uint8_t format_si,
+                                uint8_t format_p,
+                                uint8_t format_ra,
+                                uint8_t format_c,
+                                uint8_t sizeof_bits,
+                                uint8_t sizeof_bytes,
+                                uint8_t *dci_cnt,
+                                uint8_t *format0_found,
+                                uint8_t *format_c_found,
+                                uint32_t *CCEmap0,
+                                uint32_t *CCEmap1,
+                                uint32_t *CCEmap2) {
+
+  uint16_t crc, CCEind, nCCE[3];
+  uint32_t *CCEmap = NULL, CCEmap_mask = 0;
+  int L2 = (1 << L);
+  unsigned int Yk, nb_candidates = 0, i, m;
+  unsigned int CCEmap_cand;
+
+  // A[p], p is the current active CORESET
+  uint16_t A[3]={39827,39829,39839};
+  //Table 10.1-2: Maximum number of PDCCH candidates    per slot and per serving cell as a function of the subcarrier spacing value 2^mu*15 KHz, mu {0,1,2,3}
+  uint8_t m_max_slot_pdcch_Table10_1_2 [4] = {44,36,22,20};
+  //Table 10.1-3: Maximum number of non-overlapped CCEs per slot and per serving cell as a function of the subcarrier spacing value 2^mu*15 KHz, mu {0,1,2,3}
+  uint8_t cce_max_slot_pdcch_Table10_1_3 [4] = {56,56,48,32};
+
+  int coreset_nbr_cce_per_symbol=0;
+
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> \n");
+  #endif
+
+//  if (mode == NO_DCI) {
+//    #ifdef NR_PDCCH_DCI_DEBUG
+//      printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> skip DCI decoding: expect no DCIs at nr_tti_rx %d in current searchSpace\n", nr_tti_rx);
+//    #endif
+//    return;
+//  }
+
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> frequencyDomainResources=%llx, duration=%d\n",
+            pdcch_vars[eNB_id]->coreset[p].frequencyDomainResources, pdcch_vars[eNB_id]->coreset[p].duration);
+  #endif
+
+  // nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols, frame_parms, mi);
+  for (int i = 0; i < 45; i++) {
+    // this loop counts each bit of the bit map coreset_freq_dom, and increments nbr_RB_coreset for each bit set to '1'
+    if (((pdcch_vars[eNB_id]->coreset[p].frequencyDomainResources & 0x1FFFFFFFFFFF) >> i) & 0x1) coreset_nbr_cce_per_symbol++;
+  }
+  nCCE[p] = pdcch_vars[eNB_id]->coreset[p].duration*coreset_nbr_cce_per_symbol; // 1 CCE = 6 RB
+  // p is the current CORESET we are currently monitoring (among the 3 possible CORESETs in a BWP)
+  // the number of CCE in the current CORESET is:
+  //   the number of symbols in the CORESET (pdcch_vars[eNB_id]->coreset[p].duration)
+  //   multiplied by the number of bits set to '1' in the frequencyDomainResources bitmap
+  //   (1 bit set to '1' corresponds to 6 RB and 1 CCE = 6 RB)
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> nCCE[%d]=%d\n",p,nCCE[p]);
+  #endif
+
+/*	if (nCCE > get_nCCE(3, frame_parms, 1)) {
+		LOG_D(PHY,
+				"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n",
+				nCCE, get_nCCE(3, frame_parms, 1));
+		return;
+	}
+
+	if (nCCE < L2) {
+		LOG_D(PHY, "skip DCI decoding: nCCE=%d < L2=%d\n", nCCE, L2);
+		return;
+	}
+
+	if (mode == NO_DCI) {
+		LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_tti_rx %d\n",
+				nr_tti_rx);
+		return;
+	}
+*/
+  if (do_common == 1) {
+    Yk = 0;
+    if (pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.common_dci_formats == cformat2_0) {
+        // for dci_format_2_0, the nb_candidates is obtained from a different variable
+        switch (L2) {
+        case 1:
+          nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.sfi_nrofCandidates_aggrlevel1;
+          break;
+        case 2:
+          nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.sfi_nrofCandidates_aggrlevel2;
+          break;
+        case 4:
+          nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.sfi_nrofCandidates_aggrlevel4;
+          break;
+        case 8:
+          nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.sfi_nrofCandidates_aggrlevel8;
+          break;
+        case 16:
+          nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.sfi_nrofCandidates_aggrlevel16;
+          break;
+        default:
+          break;
+        }
+    } else if (pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.common_dci_formats == cformat2_3) {
+        // for dci_format_2_3, the nb_candidates is obtained from a different variable
+        nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.srs_nrofCandidates;
+    } else {
+      nb_candidates = (L2 == 4) ? 4 : ((L2 == 8)? 2 : 1); // according to Table 10.1-1 (38.213 section 10.1)
+    }
+  } else {
+    switch (L2) {
+    case 1:
+      nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].nrofCandidates_aggrlevel1;
+      break;
+    case 2:
+      nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].nrofCandidates_aggrlevel2;
+      break;
+    case 4:
+      nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].nrofCandidates_aggrlevel4;
+      break;
+    case 8:
+      nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].nrofCandidates_aggrlevel8;
+      break;
+    case 16:
+      nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].nrofCandidates_aggrlevel16;
+      break;
+    default:
+      break;
+    }
+    // Find first available in ue specific search space
+    // according to procedure in Section 10.1 of 38.213
+    // compute Yk
+    Yk = (unsigned int) pdcch_vars[eNB_id]->crnti;
+    for (i = 0; i <= nr_tti_rx; i++)
+      Yk = (Yk * A[p]) % 65537;
+  }
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> L2(%d) | nCCE[%d](%d) | Yk(%d) | nb_candidates(%d)\n",L2,p,nCCE[p],Yk,nb_candidates);
+  #endif
+  /*  for (CCEind=0;
+	 CCEind<nCCE2;
+	 CCEind+=(1<<L)) {*/
+//	if (nb_candidates * L2 > nCCE[p])
+//		nb_candidates = nCCE[p] / L2;
+
+// In the next code line there is maybe a bug. The spec is not comparing Table 10.1-2 with nb_candidates, but with total number of candidates for all s and all p
+  int m_p_s_L_max = (m_max_slot_pdcch_Table10_1_2[L]<=nb_candidates ? m_max_slot_pdcch_Table10_1_2[L] : nb_candidates);
+  if (L==4) m_p_s_L_max=1; // Table 10.1-2 is not defined for L=4
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> m_max_slot_pdcch_Table10_1_2(%d)=%d\n",L,m_max_slot_pdcch_Table10_1_2[L]);
+  #endif
+  for (m = 0; m < nb_candidates; m++) {
+    int n_ci = 0;
+    int debug1 = nCCE[p] / L2;
+    int debug2 = L2*m_p_s_L_max;
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> debug1(%d)=nCCE[p]/L2 | nCCE[%d](%d) | L2(%d)\n",debug1,p,nCCE[p],L2);
+      printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> debug2(%d)=L2*m_p_s_L_max | L2(%d) | m_p_s_L_max(%d)\n",debug2,L2,m_p_s_L_max);
+    #endif
+    CCEind = (((Yk + ((m*nCCE[p])/(L2*m_p_s_L_max)) + n_ci) % (nCCE[p] / L2)) * L2);
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> CCEind(%d) = (((Yk(%d) + ((m(%d)*nCCE[p](%d))/(L2(%d)*m_p_s_L_max(%d)))) % (nCCE[p] / L2)) * L2)\n",
+               CCEind,Yk,m,nCCE[p],L2,m_p_s_L_max);
+      printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> n_candidate(m)=%d | CCEind=%d |",m,CCEind);
+    #endif
+    if (CCEind < 32)
+      CCEmap = CCEmap0;
+    else if (CCEind < 64)
+      CCEmap = CCEmap1;
+    else if (CCEind < 96)
+      CCEmap = CCEmap2;
+    else {
+      LOG_E(PHY, "Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind, Yk, m, nCCE, L2);
+      //mac_xface->macphy_exit("Illegal CCEind\n");
+      return; // not reached
+    }
+
+    switch (L2) {
+      case 1:
+        CCEmap_mask = (1 << (CCEind & 0x1f));
+        break;
+      case 2:
+        CCEmap_mask = (3 << (CCEind & 0x1f));
+        break;
+      case 4:
+        CCEmap_mask = (0xf << (CCEind & 0x1f));
+        break;
+      case 8:
+        CCEmap_mask = (0xff << (CCEind & 0x1f));
+        break;
+      case 16:
+        CCEmap_mask = (0xfff << (CCEind & 0x1f));
+        break;
+      default:
+        LOG_E(PHY, "Illegal L2 value %d\n", L2);
+        //mac_xface->macphy_exit("Illegal L2\n");
+        return; // not reached
+    }
+    CCEmap_cand = (*CCEmap) & CCEmap_mask;
+    // CCE is not allocated yet
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> CCEmap_cand=%d \n",CCEmap_cand);
+    #endif
+
+    if (CCEmap_cand == 0) {
+      #ifdef DEBUG_DCI_DECODING
+        if (do_common == 1)
+          LOG_I(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",
+                    pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);
+        else
+          LOG_I(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n",
+                    pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c);
+      #endif
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we enter function dci_decoding(sizeof_bits=%d L=%d) -----\n",sizeof_bits,L);
+        printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we have to replace this part of the code by polar decoding\n");
+      #endif
+      dci_decoding(sizeof_bits, L, &pdcch_vars[eNB_id]->e_rx[CCEind * 72], &dci_decoded_output[current_thread_id][0]);
+      /*
+      for (i=0;i<3+(sizeof_bits>>3);i++)
+      printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]);
+      */
+      crc = (crc16(&dci_decoded_output[current_thread_id][0], sizeof_bits) >> 16) ^ extract_crc(&dci_decoded_output[current_thread_id][0], sizeof_bits);
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we end function dci_decoding() with crc=%d\n",crc);
+        printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we have to replace this part of the code by polar decoding\n");
+      #endif
+      #ifdef DEBUG_DCI_DECODING
+        printf("crc =>%x\n",crc);
+      #endif //uint16_t tc_rnti, uint16_t int_rnti, uint16_t sfi_rnti, uint16_t tpc_pusch_rnti, uint16_t tpc_pucch_rnti, uint16_t tpc_srs__rnti
+
+      if ((crc == si_rnti) || (crc == p_rnti) || (crc == ra_rnti) || (crc == tc_rnti)
+        || (crc == int_rnti) || (crc == sfi_rnti) || (crc == tpc_pusch_rnti) || (crc == tpc_pucch_rnti) || (crc == tpc_srs_rnti)
+        || (crc == pdcch_vars[eNB_id]->crnti)) {
+/*			if (((L > 1) && ((crc == si_rnti) || (crc == p_rnti) || (crc == ra_rnti)))
+					|| (crc == pdcch_vars[eNB_id]->crnti)) {*/
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> rnti matches -> DCI FOUND !!! crc =>%x, sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes);
+        #endif
+        dci_alloc[*dci_cnt].dci_length = sizeof_bits;
+        dci_alloc[*dci_cnt].rnti = crc;
+        dci_alloc[*dci_cnt].L = L;
+        dci_alloc[*dci_cnt].firstCCE = CCEind;
+        if (sizeof_bytes <= 4) {
+          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][0];
+          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][1];
+          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][2];
+          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][3];
+#ifdef DEBUG_DCI_DECODING
+					printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[current_thread_id][0],
+							dci_decoded_output[current_thread_id][1],
+							dci_decoded_output[current_thread_id][2],
+							dci_decoded_output[current_thread_id][3]);
+#endif
+        } else {
+          dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[current_thread_id][0];
+          dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[current_thread_id][1];
+          dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[current_thread_id][2];
+          dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[current_thread_id][3];
+          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][4];
+          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][5];
+          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][7];
+          // format2_0, format2_1 can be longer than 8 bytes. FIXME
+#ifdef DEBUG_DCI_DECODING
+					printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
+							dci_decoded_output[current_thread_id][0],dci_decoded_output[current_thread_id][1],dci_decoded_output[current_thread_id][2],dci_decoded_output[current_thread_id][3],
+							dci_decoded_output[current_thread_id][4],dci_decoded_output[current_thread_id][5],dci_decoded_output[current_thread_id][6],dci_decoded_output[current_thread_id][7]);
+#endif
+        }
+        if (crc == si_rnti) {
+          dci_alloc[*dci_cnt].format = format1_0;
+          *dci_cnt = *dci_cnt + 1;
+        } else if (crc == p_rnti) {
+          dci_alloc[*dci_cnt].format = format1_0;
+          *dci_cnt = *dci_cnt + 1;
+        } else if (crc == ra_rnti) {
+          dci_alloc[*dci_cnt].format = format1_0;
+          *dci_cnt = *dci_cnt + 1;
+        } else if (crc == tc_rnti) {
+          dci_alloc[*dci_cnt].format = cformat0_0_and_1_0; // this tc-rnti scrambled crc can contain formats 0_0 or 0_1. FIXME
+          *dci_cnt = *dci_cnt + 1;
+        } else if (crc == int_rnti) {
+          dci_alloc[*dci_cnt].format = format2_1;
+          *dci_cnt = *dci_cnt + 1;
+        } else if (crc == sfi_rnti) {
+          dci_alloc[*dci_cnt].format = format2_0;
+          *dci_cnt = *dci_cnt + 1;
+        } else if (crc == tpc_pusch_rnti) {
+          dci_alloc[*dci_cnt].format = format2_2;
+          *dci_cnt = *dci_cnt + 1;
+        } else if (crc == tpc_pucch_rnti) {
+          dci_alloc[*dci_cnt].format = format2_2;
+          *dci_cnt = *dci_cnt + 1;
+        } else if (crc == tpc_srs_rnti) {
+          dci_alloc[*dci_cnt].format = format2_3;
+          *dci_cnt = *dci_cnt + 1;
+        } else if (crc == pdcch_vars[eNB_id]->crnti) {
+          dci_alloc[*dci_cnt].format = uformat0_0_and_1_0; // or uformat0_1_and_1_1. FIXME
+          *dci_cnt = *dci_cnt + 1;
+        }
+/*				if (crc == si_rnti) {
+					dci_alloc[*dci_cnt].format = format_si;
+					*dci_cnt = *dci_cnt + 1;
+				} else if (crc == p_rnti) {
+					dci_alloc[*dci_cnt].format = format_p;
+					*dci_cnt = *dci_cnt + 1;
+				} else if (crc == ra_rnti) {
+					dci_alloc[*dci_cnt].format = format_ra;
+					// store first nCCE of group for PUCCH transmission of ACK/NAK
+					pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind;
+					*dci_cnt = *dci_cnt + 1;
+				} else if (crc == pdcch_vars[eNB_id]->crnti) {
+
+					if ((mode & UL_DCI) && (format_c == format0)
+							&& ((dci_decoded_output[current_thread_id][0] & 0x80)
+									== 0)) { // check if pdu is format 0 or 1A
+						if (*format0_found == 0) {
+							dci_alloc[*dci_cnt].format = format0;
+							*format0_found = 1;
+							*dci_cnt = *dci_cnt + 1;
+							pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind;
+						}
+					} else if (format_c == format0) { // this is a format 1A DCI
+						dci_alloc[*dci_cnt].format = format1A;
+						*dci_cnt = *dci_cnt + 1;
+						pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind;
+					} else {
+						// store first nCCE of group for PUCCH transmission of ACK/NAK
+						if (*format_c_found == 0) {
+							dci_alloc[*dci_cnt].format = format_c;
+							*dci_cnt = *dci_cnt + 1;
+							*format_c_found = 1;
+							pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind;
+						}
+					}
+				}*/
+				//LOG_I(PHY,"DCI decoding CRNTI  [format: %d, nCCE[nr_tti_rx: %d]: %d ], AggregationLevel %d \n",format_c, nr_tti_rx, pdcch_vars[eNB_id]->nCCE[nr_tti_rx],L2);
+				//  memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes);
+        switch (1 << L) {
+          case 1:
+            *CCEmap |= (1 << (CCEind & 0x1f));
+            break;
+          case 2:
+            *CCEmap |= (1 << (CCEind & 0x1f));
+            break;
+          case 4:
+            *CCEmap |= (1 << (CCEind & 0x1f));
+            break;
+          case 8:
+            *CCEmap |= (1 << (CCEind & 0x1f));
+            break;
+          case 16:
+            *CCEmap |= (1 << (CCEind & 0x1f));
+            break;
+        }
+
+#ifdef DEBUG_DCI_DECODING
+				LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %s in CCE %d (CCEmap %x) candidate %d / %d \n",
+						*dci_cnt,crc,1<<L,sizeof_bits,dci_format_strings[dci_alloc[*dci_cnt-1].format],CCEind,*CCEmap,m,nb_candidates );
+				dump_dci(frame_parms,&dci_alloc[*dci_cnt-1]);
+
+#endif
+        return;
+      } // rnti match
+    } else { // CCEmap_cand == 0
+      printf("\n");
+    }
+/*
+		 if ( agregationLevel != 0xFF &&
+		 (format_c == format0 && m==0 && si_rnti != SI_RNTI))
+		 {
+		 //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0.
+		 return;
+		 }
+		 */
+  } // candidate loop
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> end candidate loop\n");
+  #endif
+}
+
+#endif
+
+
+
+
+/*void dci_decoding_procedure0(NR_UE_PDCCH **pdcch_vars,
+                             int do_common,
+                             dci_detect_mode_t mode,
+                             uint8_t nr_tti_rx,
+                             DCI_ALLOC_t *dci_alloc,
+                             int16_t eNB_id,
+                             uint8_t current_thread_id,
+                             NR_DL_FRAME_PARMS *frame_parms,
+                             uint8_t mi,
+                             uint16_t si_rnti,
+                             uint16_t ra_rnti,
+                             uint16_t p_rnti,
+                             uint8_t L,
+                             uint8_t format_si,
+                             uint8_t format_p,
+                             uint8_t format_ra,
+                             uint8_t format_c,
+                             uint8_t sizeof_bits,
+                             uint8_t sizeof_bytes,
+                             uint8_t *dci_cnt,
+                             uint8_t *format0_found,
+                             uint8_t *format_c_found,
+                             uint32_t *CCEmap0,
+                             uint32_t *CCEmap1,
+                             uint32_t *CCEmap2)
+{
+
+  uint16_t crc,CCEind,nCCE;
+  uint32_t *CCEmap=NULL,CCEmap_mask=0;
+  int L2=(1<<L);
+  unsigned int Yk,nb_candidates = 0,i,m;
+  unsigned int CCEmap_cand;
+#ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_DEBUG (dci_decoding_procedure0)-> \n");
+#endif
+  nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols,frame_parms,mi);
+
+  if (nCCE > get_nCCE(3,frame_parms,1)) {
+    LOG_D(PHY,"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", nCCE, get_nCCE(3,frame_parms,1));
+    return;
+  }
+
+  if (nCCE<L2) {
+    LOG_D(PHY,"skip DCI decoding: nCCE=%d < L2=%d\n", nCCE, L2);
+    return;
+  }
+
+  if (mode == NO_DCI) {
+    LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_tti_rx %d\n", nr_tti_rx);
+    return;
+  }
+
+  if (do_common == 1) {
+    nb_candidates = (L2==4) ? 4 : 2;
+    Yk=0;
+  } else {
+    // Find first available in ue specific search space
+    // according to procedure in Section 9.1.1 of 36.213 (v. 8.6)
+    // compute Yk
+    Yk = (unsigned int)pdcch_vars[eNB_id]->crnti;
+
+    for (i=0; i<=nr_tti_rx; i++)
+      Yk = (Yk*39827)%65537;
+
+    Yk = Yk % (nCCE/L2);
+
+    switch (L2) {
+    case 1:
+    case 2:
+      nb_candidates = 6;
+      break;
+
+    case 4:
+    case 8:
+      nb_candidates = 2;
+      break;
+
+    default:
+      DevParam(L2, do_common, eNB_id);
+      break;
+    }
+  }
+
+  //  for (CCEind=0;
+  //     CCEind<nCCE2;
+  //     CCEind+=(1<<L)) {
+
+  if (nb_candidates*L2 > nCCE)
+    nb_candidates = nCCE/L2;
+
+  for (m=0; m<nb_candidates; m++) {
+
+    CCEind = (((Yk+m)%(nCCE/L2))*L2);
+
+    if (CCEind<32)
+      CCEmap = CCEmap0;
+    else if (CCEind<64)
+      CCEmap = CCEmap1;
+    else if (CCEind<96)
+      CCEmap = CCEmap2;
+    else {
+      LOG_E(PHY,"Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind,Yk,m,nCCE,L2);
+      mac_xface->macphy_exit("Illegal CCEind\n");
+      return; // not reached
+    }
+
+    switch (L2) {
+    case 1:
+      CCEmap_mask = (1<<(CCEind&0x1f));
+      break;
+
+    case 2:
+      CCEmap_mask = (3<<(CCEind&0x1f));
+      break;
+
+    case 4:
+      CCEmap_mask = (0xf<<(CCEind&0x1f));
+      break;
+
+    case 8:
+      CCEmap_mask = (0xff<<(CCEind&0x1f));
+      break;
+
+    default:
+      LOG_E( PHY, "Illegal L2 value %d\n", L2 );
+      mac_xface->macphy_exit( "Illegal L2\n" );
+      return; // not reached
+    }
+
+    CCEmap_cand = (*CCEmap)&CCEmap_mask;
+
+    // CCE is not allocated yet
+
+    if (CCEmap_cand == 0) {
+#ifdef DEBUG_DCI_DECODING
+
+      if (do_common == 1)
+        LOG_I(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",
+                pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);
+      else
+        LOG_I(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n",
+                pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c);
+
+#endif
+
+      dci_decoding(sizeof_bits,
+                   L,
+                   &pdcch_vars[eNB_id]->e_rx[CCEind*72],
+                   &dci_decoded_output[current_thread_id][0]);
+      
+      //  for (i=0;i<3+(sizeof_bits>>3);i++)
+      //  printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]);
+      
+      crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits);
+#ifdef DEBUG_DCI_DECODING
+      printf("crc =>%x\n",crc);
+#endif
+
+      if (((L>1) && ((crc == si_rnti)|| (crc == p_rnti)|| (crc == ra_rnti)))||
+          (crc == pdcch_vars[eNB_id]->crnti))   {
+        dci_alloc[*dci_cnt].dci_length = sizeof_bits;
+        dci_alloc[*dci_cnt].rnti       = crc;
+        dci_alloc[*dci_cnt].L          = L;
+        dci_alloc[*dci_cnt].firstCCE   = CCEind;
+
+        //printf("DCI FOUND !!! crc =>%x,  sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes);
+        if (sizeof_bytes<=4) {
+          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][0];
+          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][1];
+          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][2];
+          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][3];
+#ifdef DEBUG_DCI_DECODING
+          printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[current_thread_id][0],
+                  dci_decoded_output[current_thread_id][1],
+                  dci_decoded_output[current_thread_id][2],
+                  dci_decoded_output[current_thread_id][3]);
+#endif
+        } else {
+          dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[current_thread_id][0];
+          dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[current_thread_id][1];
+          dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[current_thread_id][2];
+          dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[current_thread_id][3];
+          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][4];
+          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][5];
+          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][6];
+          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][7];
+#ifdef DEBUG_DCI_DECODING
+          printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
+              dci_decoded_output[current_thread_id][0],dci_decoded_output[current_thread_id][1],dci_decoded_output[current_thread_id][2],dci_decoded_output[current_thread_id][3],
+              dci_decoded_output[current_thread_id][4],dci_decoded_output[current_thread_id][5],dci_decoded_output[current_thread_id][6],dci_decoded_output[current_thread_id][7]);
+#endif
+        }
+
+        if (crc==si_rnti) {
+          dci_alloc[*dci_cnt].format     = format_si;
+          *dci_cnt = *dci_cnt+1;
+        } else if (crc==p_rnti) {
+          dci_alloc[*dci_cnt].format     = format_p;
+          *dci_cnt = *dci_cnt+1;
+        } else if (crc==ra_rnti) {
+          dci_alloc[*dci_cnt].format     = format_ra;
+          // store first nCCE of group for PUCCH transmission of ACK/NAK
+          pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind;
+          *dci_cnt = *dci_cnt+1;
+        } else if (crc==pdcch_vars[eNB_id]->crnti) {
+
+          if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[current_thread_id][0]&0x80)==0)) {// check if pdu is format 0 or 1A
+            if (*format0_found == 0) {
+              dci_alloc[*dci_cnt].format     = format0;
+              *format0_found = 1;
+              *dci_cnt = *dci_cnt+1;
+              pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind;
+            }
+          } else if (format_c == format0) { // this is a format 1A DCI
+            dci_alloc[*dci_cnt].format     = format1A;
+            *dci_cnt = *dci_cnt+1;
+            pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind;
+          } else {
+            // store first nCCE of group for PUCCH transmission of ACK/NAK
+            if (*format_c_found == 0) {
+              dci_alloc[*dci_cnt].format     = format_c;
+              *dci_cnt = *dci_cnt+1;
+              *format_c_found = 1;
+              pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind;
+            }
+          }
+        }
+
+        //LOG_I(PHY,"DCI decoding CRNTI  [format: %d, nCCE[nr_tti_rx: %d]: %d ], AggregationLevel %d \n",format_c, nr_tti_rx, pdcch_vars[eNB_id]->nCCE[nr_tti_rx],L2);
+        //  memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes);
+
+
+
+        switch (1<<L) {
+        case 1:
+          *CCEmap|=(1<<(CCEind&0x1f));
+          break;
+
+        case 2:
+          *CCEmap|=(1<<(CCEind&0x1f));
+          break;
+
+        case 4:
+          *CCEmap|=(1<<(CCEind&0x1f));
+          break;
+
+        case 8:
+          *CCEmap|=(1<<(CCEind&0x1f));
+          break;
+        }
+
+#ifdef DEBUG_DCI_DECODING
+        LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %s in CCE %d (CCEmap %x) candidate %d / %d \n",
+              *dci_cnt,crc,1<<L,sizeof_bits,dci_format_strings[dci_alloc[*dci_cnt-1].format],CCEind,*CCEmap,m,nb_candidates );
+        dump_dci(frame_parms,&dci_alloc[*dci_cnt-1]);
+
+#endif
+         return;
+      } // rnti match
+    }  // CCEmap_cand == 0
+    
+//	if ( agregationLevel != 0xFF &&
+//        (format_c == format0 && m==0 && si_rnti != SI_RNTI))
+//    {
+//      //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0.
+//      return;
+//    }
+
+  } // candidate loop
+}
+
+uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_NR_UE *ue,
+                                DCI_ALLOC_t *dci_alloc,
+                                uint8_t DCIFormat,
+                                uint8_t agregationLevel,
+                                int16_t eNB_id,
+                                uint8_t nr_tti_rx)
+{
+
+  uint8_t  dci_cnt=0,old_dci_cnt=0;
+  uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0;
+  NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]];
+  NR_DL_FRAME_PARMS *frame_parms  = &ue->frame_parms;
+  uint8_t mi = get_mi(&ue->frame_parms,nr_tti_rx);
+  uint16_t ra_rnti=99;
+  uint8_t format0_found=0,format_c_found=0;
+  uint8_t tmode = ue->transmission_mode[eNB_id];
+  uint8_t frame_type = frame_parms->frame_type;
+  uint8_t format0_size_bits=0,format0_size_bytes=0;
+  uint8_t format1_size_bits=0,format1_size_bytes=0;
+  dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,nr_tti_rx);
+
+  switch (frame_parms->N_RB_DL) {
+  case 6:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_1_5MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_1_5MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
+
+    } else {
+      format0_size_bits  = sizeof_DCI0_1_5MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_1_5MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t);
+    }
+
+    break;
+
+  case 25:
+  default:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_5MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_5MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_5MHz_TDD_t);
+    } else {
+      format0_size_bits  = sizeof_DCI0_5MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_5MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_5MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_5MHz_FDD_t);
+    }
+
+    break;
+
+  case 50:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_10MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_10MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_10MHz_TDD_t);
+
+    } else {
+      format0_size_bits  = sizeof_DCI0_10MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_10MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_10MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_10MHz_FDD_t);
+    }
+
+    break;
+
+  case 100:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_20MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_20MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_20MHz_TDD_t);
+    } else {
+      format0_size_bits  = sizeof_DCI0_20MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_20MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_20MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_20MHz_FDD_t);
+    }
+
+    break;
+  }
+
+  if (ue->prach_resources[eNB_id])
+    ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+
+  // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8
+  dci_decoding_procedure0(pdcch_vars,0,mode,
+                          nr_tti_rx,
+                          dci_alloc,
+                          eNB_id,
+                          ue->current_thread_id[nr_tti_rx],
+                          frame_parms,
+                          mi,
+                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                          ra_rnti,
+              P_RNTI,
+              agregationLevel,
+                          format1A,
+                          format1A,
+                          format1A,
+                          format0,
+                          format0_size_bits,
+                          format0_size_bytes,
+                          &dci_cnt,
+                          &format0_found,
+                          &format_c_found,
+                          &CCEmap0,
+                          &CCEmap1,
+                          &CCEmap2);
+
+  if ((CCEmap0==0xffff)||
+      ((format0_found==1)&&(format_c_found==1)))
+    return(dci_cnt);
+
+  if (DCIFormat == 1)
+  {
+      if ((tmode < 3) || (tmode == 7)) {
+          //printf("Crnti decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat);
+
+          // Now check UE_SPEC format 1 search spaces at aggregation 1
+
+           //printf("[DCI search] Format 1/1A aggregation 1\n");
+
+          old_dci_cnt=dci_cnt;
+          dci_decoding_procedure0(pdcch_vars,0,mode,nr_tti_rx,
+                                  dci_alloc,
+                                  eNB_id,
+                                  ue->current_thread_id[nr_tti_rx],
+                                  frame_parms,
+                                  mi,
+                                  ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                                  ra_rnti,
+                                  P_RNTI,
+                                  0,
+                                  format1A,
+                                  format1A,
+                                  format1A,
+                                  format1,
+                                  format1_size_bits,
+                                  format1_size_bytes,
+                                  &dci_cnt,
+                                  &format0_found,
+                                  &format_c_found,
+                                  &CCEmap0,
+                                  &CCEmap1,
+                                  &CCEmap2);
+
+          if ((CCEmap0==0xffff) ||
+              (format_c_found==1))
+            return(dci_cnt);
+
+          if (dci_cnt>old_dci_cnt)
+            return(dci_cnt);
+
+          //printf("Crnti 1 decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat);
+
+      }
+      else
+      {
+          AssertFatal(0,"Other Transmission mode not yet coded\n");
+      }
+  }
+  else
+  {
+     AssertFatal(0,"DCI format %d not yet implemented \n",DCIFormat);
+  }
+
+  return(dci_cnt);
+
+}
+*/
+
+#ifdef NR_PDCCH_DCI_RUN
+uint16_t nr_dci_format_size (NR_DCI_format_t format,
+                             uint8_t pusch_alloc_list,
+                             uint16_t n_RB_ULBWP,
+                             uint16_t n_RB_DLBWP,
+                             uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS]){
+#ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size)-> \n");
+#endif
+
+/*
+ * Formats 0_1, not completely implemented. See (*)
+ */
+// format {0_0,0_1,1_0,1_1,2_0,2_1,2_2,2_3} according to 38.212 Section 7.3.1
+/*#define NBR_NR_FORMATS  8
+#define NBR_NR_DCI FIELDS     48
+#define CARRIER_IND                      0
+#define SUL_IND_0_1                      1
+#define IDENTIFIER_DCI_FORMATS           2
+#define SLOT_FORMAT_IND                  3
+#define PRE_EMPTION_IND                  4
+#define TPC_CMD_NUMBER                   5
+#define BLOCK_NUMBER                     6
+#define BANDWIDTH_PART_IND               7
+#define FREQ_DOM_RESOURCE_ASSIGNMENT_UL  8
+#define FREQ_DOM_RESOURCE_ASSIGNMENT_DL  9
+#define TIME_DOM_RESOURCE_ASSIGNMENT    10
+#define VRB_TO_PRB_MAPPING              11
+#define PRB_BUNDLING_SIZE_IND           12
+#define RATE_MATCHING_IND               13
+#define ZP_CSI_RS_TRIGGER               14
+#define FREQ_HOPPING_FLAG               15
+#define TB1_MCS                         16
+#define TB1_NDI                         17
+#define TB1_RV                          18
+#define TB2_MCS                         19
+#define TB2_NDI                         20
+#define TB2_RV                          21
+#define MCS                             22
+#define NDI                             23
+#define RV                              24
+#define HARQ_PROCESS_NUMBER             25
+#define DAI                             26
+#define FIRST_DAI                       27
+#define SECOND_DAI                      28
+#define TPC_PUSCH                       29
+#define TPC_PUCCH                       30
+#define PUCCH_RESOURCE_IND              31
+#define PDSCH_TO_HARQ_FEEDBACK_TIME_IND 32
+#define SHORT_MESSAGE_IND               33
+#define SRS_RESOURCE_IND                34
+#define PRECOD_NBR_LAYERS               35
+#define ANTENNA_PORTS                   36
+#define TCI                             37
+#define SRS_REQUEST                     38
+#define TPC_CMD_NUMBER_FORMAT2_3        39
+#define CSI_REQUEST                     40
+#define CBGTI                           41
+#define CBGFI                           42
+#define PTRS_DMRS                       43
+#define BETA_OFFSET_IND                 44
+#define DMRS_SEQ_INI                    45
+#define SUL_IND_0_0                     46
+#define PADDING                         47*/
+  //uint8_t pusch_alloc_list=1;
+  uint8_t n_zp = 1; // number of ZP CSI-RS resource sets in the higher layer parameter [ZP-CSI-RS-ResourceConfigList].
+  uint8_t n_SRS=1;
+  uint8_t dci_field_size_table [NBR_NR_DCI_FIELDS][NBR_NR_FORMATS] = { // This table contains the number of bits for each field (row) contained in each dci format (column).
+                                                                       // The values of the variables indicate field sizes in number of bits
+//Format0_0                              Format0_1                               Format1_0                               Format1_1                      Formats2_0/1/2/3
+{0,                                      3,                                      0,                                      3,                                      0,0,0,0}, // 0  CARRIER_IND: 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213]
+{0,                                      0,                                      0,                                      0,                                      0,0,0,0}, // 1  SUL_IND_0_1:
+{1,                                      1,                                      1,                                      1,                                      1,1,1,1}, // 2  IDENTIFIER_DCI_FORMATS:
+{0,                                      0,                                      0,                                      0,                                      1,0,0,0}, // 3  SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213]
+{0,                                      0,                                      0,                                      0,                                      0,1,0,0}, // 4  PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits
+{0,                                      0,                                      0,                                      0,                                      0,0,1,0}, // 5  TPC_CMD_NUMBER: The parameter xxx provided by higher layers determines the index to the TPC command number for an UL of a cell. Each TPC command number is 2 bits
+{0,                                      0,                                      0,                                      0,                                      0,0,0,1}, // 6  BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3
+{0,                                      ceil(log2(n_RB_ULBWP)),                 0,                                      ceil(log2(n_RB_ULBWP)),                 0,0,0,0}, // 7  BANDWIDTH_PART_IND:
+{ceil(log2(n_RB_ULBWP*(n_RB_ULBWP+1)/2)),ceil(log2(n_RB_ULBWP*(n_RB_ULBWP+1)/2)),0,                                      0,                                      0,0,0,0}, // 8  FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered
+                                                                                                                                                                           // (NOTE 1) If DCI format 0_0 is monitored in common search space
+                                                                                                                                                                           // and if the number of information bits in the DCI format 0_0 prior to padding
+                                                                                                                                                                           // is larger than the payload size of the DCI format 1_0 monitored in common search space
+                                                                                                                                                                           // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0
+                                                                                                                                                                           // is reduced such that the size of DCI format 0_0 equals to the size of the DCI format 1_0
+{0,                                      0,                                      ceil(log2(n_RB_DLBWP*(n_RB_DLBWP+1)/2)),ceil(log2(n_RB_DLBWP*(n_RB_DLBWP+1)/2)),0,0,0,0}, // 9  FREQ_DOM_RESOURCE_ASSIGNMENT_DL:
+{log2(pusch_alloc_list),                 log2(pusch_alloc_list),                 log2(pusch_alloc_list),                 log2(pusch_alloc_list),                 0,0,0,0}, // 10 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits,
+                                                                                                                                                                           // where I the number of entries in the higher layer parameter pusch-AllocationList
+{0,                                      1,                                      1,                                      1,                                      0,0,0,0}, // 11 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0
+{0,                                      0,                                      0,                                      1,                                      0,0,0,0}, // 12 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214]
+{0,                                      0,                                      0,                                      2,                                      0,0,0,0}, // 13 RATE_MATCHING_IND: 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set
+{0,                                      0,                                      0,                                      log2(n_zp)+1,                           0,0,0,0}, // 14 ZP_CSI_RS_TRIGGER:
+{1,                                      1,                                      0,                                      0,                                      0,0,0,0}, // 15 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0
+{0,                                      0,                                      0,                                      5,                                      0,0,0,0}, // 16 TB1_MCS:
+{0,                                      0,                                      0,                                      1,                                      0,0,0,0}, // 17 TB1_NDI:
+{0,                                      0,                                      0,                                      2,                                      0,0,0,0}, // 18 TB1_RV:
+{0,                                      0,                                      0,                                      5,                                      0,0,0,0}, // 19 TB2_MCS:
+{0,                                      0,                                      0,                                      1,                                      0,0,0,0}, // 20 TB2_NDI:
+{0,                                      0,                                      0,                                      2,                                      0,0,0,0}, // 21 TB2_RV:
+{5,                                      5,                                      5,                                      0,                                      0,0,0,0}, // 22 MCS:
+{1,                                      1,                                      1,                                      0,                                      0,0,0,0}, // 23 NDI:
+{2,                                      2,                                      2,                                      0,                                      0,0,0,0}, // 24 RV:
+{4,                                      4,                                      4,                                      4,                                      0,0,0,0}, // 25 HARQ_PROCESS_NUMBER:
+{0,                                      0,                                      2,                                      4,                                      0,0,0,0}, // 26 DAI: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI
+                                                                                                                                                                           // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI
+                                                                                                                                                                           // 0 otherwise
+{0,                                      2,                                      0,                                      0,                                      0,0,0,0}, // 27 FIRST_DAI: (1 or 2 bits) 1 bit for semi-static HARQ-ACK // 2 bits for dynamic HARQ-ACK codebook with single HARQ-ACK codebook
+{0,                                      2,                                      0,                                      0,                                      0,0,0,0}, // 28 SECOND_DAI: (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks // 0 bits otherwise
+{2,                                      2,                                      0,                                      0,                                      0,0,0,0}, // 29 TPC_PUSCH:
+{0,                                      0,                                      2,                                      2,                                      0,0,0,0}, // 30 TPC_PUCCH:
+{0,                                      0,                                      3,                                      3,                                      0,0,0,0}, // 31 PUCCH_RESOURCE_IND:
+{0,                                      0,                                      3,                                      3,                                      0,0,0,0}, // 32 PDSCH_TO_HARQ_FEEDBACK_TIME_IND:
+{0,                                      0,                                      0,                                      0,                                      0,0,0,0}, // 33 SHORT_MESSAGE_IND: 1 bit if crc scrambled with P-RNTI
+                                                                                                                                                                           // not implemented at the moment
+{0,                                      log2(n_SRS),                            0,                                      0,                                      0,0,0,0}, // 34 SRS_RESOURCE_IND:
+{0,                                      0,                                      0,                                      0,                                      0,0,0,0}, // 35 PRECOD_NBR_LAYERS:
+{0,                                      0,                                      0,                                      0,                                      0,0,0,0}, // 36 ANTENNA_PORTS:
+{0,                                      0,                                      0,                                      3,                                      0,0,0,0}, // 37 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits
+{0,                                      3,                                      0,                                      0,                                      0,0,0,2}, // 38 SRS_REQUEST:
+{0,                                      0,                                      0,                                      0,                                      0,0,0,2}, // 39 TPC_CMD_NUMBER_FORMAT2_3:
+{0,                                      6,                                      0,                                      0,                                      0,0,0,0}, // 40 CSI_REQUEST:
+{0,                                      8,                                      0,                                      8,                                      0,0,0,0}, // 41 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH
+{0,                                      0,                                      0,                                      1,                                      0,0,0,0}, // 42 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator
+{0,                                      2,                                      0,                                      0,                                      0,0,0,0}, // 43 PTRS_DMRS:
+{0,                                      2,                                      0,                                      0,                                      0,0,0,0}, // 44 BETA_OFFSET_IND:
+{0,                                      1,                                      0,                                      1,                                      0,0,0,0}, // 45 DMRS_SEQ_INI: 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding
+                                                                                                                                                                           //is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise
+{0,                                      0,                                      0,                                      0,                                      0,0,0,0}, // 46 SUL_IND_0_0:
+{0,                                      0,                                      0,                                      0,                                      0,0,0,0}  // 47 PADDING: (Note 2) If DCI format 0_0 is monitored in common search space
+                                                                                                                                                                           // and if the number of information bits in the DCI format 0_0 prior to padding
+                                                                                                                                                                           // is less than the payload size of the DCI format 1_0 monitored in common search space
+                                                                                                                                                                           // zeros shall be appended to the DCI format 0_0
+                                                                                                                                                                           // until the payload size equals that of the DCI format 1_0
+};
+
+// NOTE 1: adjustments in freq_dom_resource_assignment_UL to be done if necessary
+// NOTE 2: adjustments in padding to be done if necessary
+
+uint8_t dci_size [8] = {0,0,0,0,0,0,0,0}; // will contain size for each format
+
+  for (int i=0 ; i<NBR_NR_FORMATS ; i++) {
+    for (int j=0; j<NBR_NR_DCI_FIELDS; j++) {
+      #ifdef NR_PDCCH_DCI_DEBUG
+      //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size)-> i=%d, j=%d\n", i, j);
+      #endif
+      dci_size [i] = dci_size [i] + dci_field_size_table[j][i]; // dci_size[i] contains the size in bits of the dci pdu format i
+      if (i==(int)format) {                                  // (int)format indicates the position of each format in the table (e.g. format1_0=2 -> position in table is 2)
+        dci_fields_sizes[j] = dci_field_size_table[j][i];       // dci_fields_sizes[j] contains the sizes of each field (j) for a determined format i
+      }
+    }
+    #ifdef NR_PDCCH_DCI_DEBUG
+      printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_size[%d]=%d for n_RB_ULBWP=%d\n",
+             i,dci_size[i],n_RB_ULBWP);
+    #endif
+  }
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_field_size_table[%d] = { ",format);
+    for (int j=0; j<NBR_NR_DCI_FIELDS; j++) printf("%d, ",dci_field_size_table[j][(int)format-15]);
+    printf(" }\n");
+  #endif
+
+  if ((format == format0_0) || (format == format1_0)) {
+  // According to Section 7.3.1.1.1 in TS 38.212
+  // If DCI format 0_0 is monitored in common search space and if the number of information bits in the DCI format 0_0 prior to padding
+  // is less than the payload size of the DCI format 1_0 monitored in common search space for scheduling the same serving cell,
+  // zeros shall be appended to the DCI format 0_0 until the payload size equals that of the DCI format 1_0.
+    if (dci_size[0] < dci_size[2]) { // '0' corresponding to index for format0_0 and '2' corresponding to index of format1_0
+      if (format == format0_0) {
+        dci_fields_sizes[PADDING] = dci_size[2] - dci_size[0];
+        dci_size[0] = dci_size[2];
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]);
+        #endif
+      }
+    }
+  // If DCI format 0_0 is monitored in common search space and if the number of information bits in the DCI format 0_0 prior to padding
+  // is larger than the payload size of the DCI format 1_0 monitored in common search space for scheduling the same serving cell,
+  // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0 is reduced
+  // such that the size of DCI format 0_0 equals to the size of the DCI format 1_0..
+    if (dci_size[0] > dci_size[2]) {
+      if (format == format0_0) {
+        dci_fields_sizes[BANDWIDTH_PART_IND] -= (dci_size[0] - dci_size[2]);
+        dci_size[0] = dci_size[2];
+        #ifdef NR_PDCCH_DCI_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]);
+        #endif
+      }
+    }
+  }
+
+  return dci_size[(int)format];
+}
+#endif
+
+#ifdef NR_PDCCH_DCI_RUN
+uint8_t nr_dci_decoding_procedure(int s,
+                                  int p,
+                                  PHY_VARS_NR_UE *ue,
+                                  NR_DCI_ALLOC_t *dci_alloc,
+                                  int do_common,
+                                  int16_t eNB_id,
+                                  uint8_t nr_tti_rx,
+                                  uint8_t dci_fields_sizes[48],
+                                  uint16_t n_RB_ULBWP,
+                                  uint16_t n_RB_DLBWP) {
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure) nr_tti_rx=%d\n",nr_tti_rx);
+  #endif
+  uint8_t dci_cnt = 0, old_dci_cnt = 0;
+  uint32_t CCEmap0 = 0, CCEmap1 = 0, CCEmap2 = 0;
+
+  NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]];
+  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  uint8_t mi;// = get_mi(&ue->frame_parms, nr_tti_rx);
+  uint16_t ra_rnti = 99;
+  uint16_t tc_rnti = 1; // FIXME
+  uint16_t int_rnti = 1; // FIXME
+  uint16_t sfi_rnti = 1; // FIXME
+  uint16_t tpc_pusch_rnti =1; // FIXME
+  uint16_t tpc_pucch_rnti = 1; // FIXME
+  uint16_t tpc_srs_rnti = 1; // FIXME
+  uint8_t format0_found = 0, format_c_found = 0;
+  uint8_t tmode = ue->transmission_mode[eNB_id];
+  uint8_t frame_type = frame_parms->frame_type;
+  //uint8_t dci_fields_sizes[48];
+  uint8_t format0_0_size_bits = 0, format0_0_size_bytes = 0; //FIXME
+  uint8_t format0_1_size_bits = 0, format0_1_size_bytes = 0; //FIXME
+  uint8_t format1_0_size_bits = 0, format1_0_size_bytes = 0; //FIXME
+  uint8_t format1_1_size_bits = 0, format1_1_size_bytes = 0; //FIXME
+  uint8_t format2_0_size_bits = 0, format2_0_size_bytes = 0; //FIXME
+  uint8_t format2_1_size_bits = 0, format2_1_size_bytes = 0; //FIXME
+  uint8_t format2_2_size_bits = 0, format2_2_size_bytes = 0; //FIXME
+  uint8_t format2_3_size_bits = 0, format2_3_size_bytes = 0; //FIXME
+
+  /*
+   * the following variables have to be removed
+   */
+  uint8_t format1A_size_bits = 0, format1A_size_bytes = 0;
+  uint8_t format1C_size_bits = 0, format1C_size_bytes = 0;
+  uint8_t format0_size_bits  = 0, format0_size_bytes  = 0;
+  uint8_t format1_size_bits  = 0, format1_size_bytes  = 0;
+  uint8_t format2_size_bits  = 0, format2_size_bytes  = 0;
+  uint8_t format2A_size_bits = 0, format2A_size_bytes = 0;
+  /*
+   *
+   */
+
+  /*
+   *
+   * The implementation of this function will depend on the information given by the searchSpace IE
+   *
+   * In LTE the UE has no knowledge about:
+   * - the type of search (common or ue-specific)
+   * - the DCI format it is going to be decoded when performing the PDCCH monitoring
+   * So the blind decoding has to be done for common and ue-specific searchSpaces for each aggregation level and for each dci format
+   *
+   * In NR the UE has a knowledge about the search Space type and the DCI format it is going to be decoded,
+   * so in the blind decoding we can call the function nr_dci_decoding_procedure0 with the searchSpace type and the dci format parameter
+   * We will call this function as many times as aggregation levels indicated in searchSpace
+   * Implementation according to 38.213 v15.1.0 Section 10.
+   *
+   */
+
+  NR_UE_PDCCH *pdcch_vars2                         = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id];
+  NR_UE_SEARCHSPACE_CSS_DCI_FORMAT_t css_dci_format = pdcch_vars2->searchSpace[s].searchSpaceType.common_dci_formats;
+  NR_UE_SEARCHSPACE_USS_DCI_FORMAT_t uss_dci_format = pdcch_vars2->searchSpace[s].searchSpaceType.ue_specific_dci_formats;
+
+  // The following initialization is only for test purposes. To be removed
+  // NR_UE_SEARCHSPACE_CSS_DCI_FORMAT_t
+  css_dci_format = cformat0_0_and_1_0;
+  //NR_UE_SEARCHSPACE_USS_DCI_FORMAT_t
+  uss_dci_format = uformat0_0_and_1_0;
+
+  /*
+   * Possible overlap between RE for SS/PBCH blocks (described in section 10, 38.213) has not been implemented yet
+   * This can be implemented by setting variable 'mode = NO_DCI' when overlap occurs
+   */
+  //dci_detect_mode_t mode = 3; //dci_detect_mode_select(&ue->frame_parms, nr_tti_rx);
+
+  #ifdef NR_PDCCH_DCI_DEBUG
+    printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> searSpaceType=%d\n",do_common);
+    if (do_common) {
+      printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> css_dci_format=%d\n",css_dci_format);
+    } else {
+      printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> uss_dci_format=%d\n",uss_dci_format);
+    }
+  #endif
+  // A set of PDCCH candidates for a UE to monitor is defined in terms of PDCCH search spaces
+  if (do_common) { // COMMON SearchSpaceType assigned to current SearchSpace/CORESET
+    // Type0-PDCCH  common search space for a DCI format with CRC scrambled by a SI-RNTI
+               // number of consecutive resource blocks and a number of consecutive symbols for
+               // the control resource set of the Type0-PDCCH common search space from
+               // the four most significant bits of RMSI-PDCCH-Config as described in Tables 13-1 through 13-10
+               // and determines PDCCH monitoring occasions
+               // from the four least significant bits of RMSI-PDCCH-Config,
+               // included in MasterInformationBlock, as described in Tables 13-11 through 13-15
+    // Type0A-PDCCH common search space for a DCI format with CRC scrambled by a SI-RNTI
+    // Type1-PDCCH  common search space for a DCI format with CRC scrambled by a RA-RNTI, or a TC-RNTI, or a C-RNTI
+    // Type2-PDCCH  common search space for a DCI format with CRC scrambled by a P-RNTI
+    if (css_dci_format == cformat0_0_and_1_0) {
+      // 38.213 v15.1.0 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE
+      // aggregation level for Type0/Type0A/Type2-PDCCH common search space
+      //   CCE Aggregation Level    Number of Candidates
+      //           4                       4
+      //           8                       2
+      //           16                      1
+      // FIXME
+      // We shall consider Table 10.1-1 to calculate the blind decoding only for Type0/Type0A/Type2-PDCCH
+      // Shall we consider the nrofCandidates in SearSpace IE that considers Aggregation Levels 1,2,4,8,16? Our implementation considers Table 10.1-1
+
+      // blind decoding (Type0-PDCCH,Type0A-PDCCH,Type1-PDCCH,Type2-PDCCH)
+      // for format0_0 => we are NOT implementing format0_0 for common search spaces. FIXME!
+
+      // for format1_0, first we calculate dci pdu size
+      format1_0_size_bits = nr_dci_format_size(format1_0,1,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes);
+      // the second parameter '1' is the pusch_alloc_list used to calculate size of field TIME_DOM_RESOURCE_ASSIGNMENT
+      //format1_0_size_bits = nr_dci_format_size(2,1,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes);
+      format1_0_size_bytes = (format1_0_size_bits%8 == 0) ? (uint8_t)floor(format1_0_size_bits/8) : (uint8_t)(floor(format1_0_size_bits/8) + 1);
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format1_0_size_bits=%d, format1_0_size_bytes=%d\n",
+                css_dci_format,format1_0_size_bits,format1_0_size_bytes);
+      #endif
+      // for aggregation level 4. The number of candidates (L2=4) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n",
+                css_dci_format,(1<<2));
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 2,
+                cformat0_0_and_1_0, format1A, format1A, format0,
+                format1_0_size_bits, format1A_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // for aggregation level 8. The number of candidates (L2=8) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n",
+                css_dci_format,(1<<3));
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 3,
+                cformat0_0_and_1_0, format1A, format1A, format0,
+                format1_0_size_bits, format1A_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // for aggregation level 16. The number of candidates (L2=16) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n",
+                css_dci_format,(1<<4));
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 4,
+                cformat0_0_and_1_0, format1A, format1A, format0,
+                format1_0_size_bits, format1A_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+    }
+
+    // Type3-PDCCH  common search space for a DCI format with CRC scrambled by INT-RNTI, or SFI-RNTI,
+    //    or TPC-PUSCH-RNTI, or TPC-PUCCH-RNTI, or TPC-SRS-RNTI, or C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
+    if (css_dci_format == cformat2_0) {
+      // for format2_0, first we calculate dci pdu size
+      format2_0_size_bits = nr_dci_format_size(format2_0,0,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes);
+      format2_0_size_bytes = (format2_0_size_bits%8 == 0) ? (uint8_t)floor(format2_0_size_bits/8) : (uint8_t)(floor(format2_0_size_bits/8) + 1);
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_0_size_bits=%d, format2_0_size_bytes=%d\n",
+                css_dci_format,format2_0_size_bits,format2_0_size_bytes);
+      #endif
+      // for aggregation level 1. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 0,
+                format1A, format1A, format1A, format0,
+                format1A_size_bits, format1A_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // for aggregation level 2. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 1,
+                format1A, format1A, format1A, format0,
+                format1A_size_bits, format1A_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // for aggregation level 4. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 2,
+                format1A, format1A, format1A, format0,
+                format1A_size_bits, format1A_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // for aggregation level 8. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 3,
+                format1A, format1A, format1A, format0,
+                format1A_size_bits, format1A_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // for aggregation level 16. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 4,
+                format1A, format1A, format1A, format0,
+                format1A_size_bits, format1A_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+    }
+    if (css_dci_format == cformat2_1) {
+      // for format2_1, first we calculate dci pdu size
+      format2_1_size_bits = nr_dci_format_size(format2_1,0,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes);
+      format2_1_size_bytes = (format2_1_size_bits%8 == 0) ? (uint8_t)floor(format2_1_size_bits/8) : (uint8_t)(floor(format2_1_size_bits/8) + 1);
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_1_size_bits=%d, format2_1_size_bytes=%d\n",
+                css_dci_format,format2_1_size_bits,format2_1_size_bytes);
+      #endif
+    }
+    if (css_dci_format == cformat2_2) {
+      // for format2_2, first we calculate dci pdu size
+      format2_2_size_bits = nr_dci_format_size(format2_2,0,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes);
+      format2_2_size_bytes = (format2_2_size_bits%8 == 0) ? (uint8_t)floor(format2_2_size_bits/8) : (uint8_t)(floor(format2_2_size_bits/8) + 1);
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_2_size_bits=%d, format2_2_size_bytes=%d\n",
+                css_dci_format,format2_2_size_bits,format2_2_size_bytes);
+      #endif
+    }
+    if (css_dci_format == cformat2_3) {
+      // for format2_1, first we calculate dci pdu size
+      format2_3_size_bits = nr_dci_format_size(format2_3,0,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes);
+      format2_3_size_bytes = (format2_3_size_bits%8 == 0) ? (uint8_t)floor(format2_3_size_bits/8) : (uint8_t)(floor(format2_3_size_bits/8) + 1);
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_3_size_bits=%d, format2_3_size_bytes=%d\n",
+                css_dci_format,format2_3_size_bits,format2_3_size_bytes);
+      #endif
+    }
+  } else { // UE-SPECIFIC SearchSpaceType assigned to current SearchSpace/CORESET
+    // UE-specific search space for a DCI format with CRC scrambled by C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
+    if (uss_dci_format == uformat0_0_and_1_0) {
+      // for format0_0, first we calculate dci pdu size
+      format0_0_size_bits = nr_dci_format_size(format0_0,1,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes);
+      format0_0_size_bytes = (format0_0_size_bits%8 == 0) ? (uint8_t)floor(format0_0_size_bits/8) : (uint8_t)(floor(format0_0_size_bits/8) + 1);
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format0_0_size_bits=%d, format0_0_size_bytes=%d\n",
+                css_dci_format,format0_0_size_bits,format0_0_size_bytes);
+      #endif
+      // blind decoding format0_0 for aggregation level 1. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> ue-Specific searchSpaces with format uss_dci_format=%d and aggregation level 1, format0_0_size_bits=%d, format0_0_size_bytes=%d\n",
+                uss_dci_format,format0_0_size_bits,format0_0_size_bytes);
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 0,
+                format1A, format1A, format1A, format0,
+                format0_0_size_bits, format0_0_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // blind decoding format0_0 for aggregation level 2. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> ue-Specific searchSpaces with format uss_dci_format=%d and aggregation level 2, format0_0_size_bits=%d, format0_0_size_bytes=%d\n",
+                uss_dci_format,format0_0_size_bits,format0_0_size_bytes);
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 1,
+                format1A, format1A, format1A, format0,
+                format0_0_size_bits, format0_0_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // blind decoding format0_0 for aggregation level 4. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> ue-Specific searchSpaces with format uss_dci_format=%d and aggregation level 4, format0_0_size_bits=%d, format0_0_size_bytes=%d\n",
+                uss_dci_format,format0_0_size_bits,format0_0_size_bytes);
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 2,
+                format1A, format1A, format1A, format0,
+                format0_0_size_bits, format0_0_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // blind decoding format0_0 for aggregation level 8. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> ue-Specific searchSpaces with format uss_dci_format=%d and aggregation level 8, format0_0_size_bits=%d, format0_0_size_bytes=%d\n",
+                uss_dci_format,format0_0_size_bits,format0_0_size_bytes);
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 3,
+                format1A, format1A, format1A, format0,
+                format0_0_size_bits, format0_0_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // blind decoding format0_0 for aggregation level 16. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> ue-Specific searchSpaces with format uss_dci_format=%d and aggregation level 16, format0_0_size_bits=%d, format0_0_size_bytes=%d\n",
+                uss_dci_format,format0_0_size_bits,format0_0_size_bytes);
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti,  tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 4,
+                format1A, format1A, format1A, format0,
+                format0_0_size_bits, format0_0_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+
+      // for format1_0, first we calculate dci pdu size
+      format1_0_size_bits = nr_dci_format_size(format1_0,1,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes);
+      format1_0_size_bytes = (format1_0_size_bits%8 == 0) ? (uint8_t)floor(format1_0_size_bits/8) : (uint8_t)(floor(format1_0_size_bits/8) + 1);
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format1_0_size_bits=%d, format1_0_size_bytes=%d\n",
+                css_dci_format,format1_0_size_bits,format1_0_size_bytes);
+      #endif
+      // blind decoding format1_0 for aggregation level 1. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> ue-Specific searchSpaces with format uss_dci_format=%d and aggregation level 1, format1_0_size_bits=%d, format1_0_size_bytes=%d\n",
+              uss_dci_format,format1_0_size_bits,format1_0_size_bytes);
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 0,
+                format1A, format1A, format1A, format0,
+                format1_0_size_bits, format1_0_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // blind decoding format1_0 for aggregation level 2. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> ue-Specific searchSpaces with format uss_dci_format=%d and aggregation level 2, format1_0_size_bits=%d, format1_0_size_bytes=%d\n",
+                uss_dci_format,format1_0_size_bits,format1_0_size_bytes);
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 1,
+                format1A, format1A, format1A, format0,
+                format1_0_size_bits, format1_0_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // blind decoding format1_0 for aggregation level 4. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> ue-Specific searchSpaces with format uss_dci_format=%d and aggregation level 4, format1_0_size_bits=%d, format1_0_size_bytes=%d\n",
+                uss_dci_format,format1_0_size_bits,format1_0_size_bytes);
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 2,
+                format1A, format1A, format1A, format0,
+                format1_0_size_bits, format1_0_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // blind decoding format1_0 for aggregation level 8. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> ue-Specific searchSpaces with format uss_dci_format=%d and aggregation level 8, format1_0_size_bits=%d, format1_0_size_bytes=%d\n",
+                uss_dci_format,format1_0_size_bits,format1_0_size_bytes);
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti, tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 3,
+                format1A, format1A, format1A, format0,
+                format1_0_size_bits, format1_0_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+      // blind decoding format1_0 for aggregation level 16. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> ue-Specific searchSpaces with format uss_dci_format=%d and aggregation level 16, format1_0_size_bits=%d, format1_0_size_bytes=%d\n",
+                uss_dci_format,format1_0_size_bits,format1_0_size_bytes);
+      #endif
+      nr_dci_decoding_procedure0(s,p,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, mi,
+                ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, tc_rnti, int_rnti, sfi_rnti,  tpc_pusch_rnti, tpc_pucch_rnti, tpc_srs_rnti, 4,
+                format1A, format1A, format1A, format0,
+                format1_0_size_bits, format1_0_size_bytes, &dci_cnt,
+                &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2);
+    }
+    if (uss_dci_format == uformat0_1_and_1_1) { // Not implemented yet. FIXME!!!
+      // for format0_1, first we calculate dci pdu size
+      format0_1_size_bits = nr_dci_format_size(format0_1,1,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes);
+      format0_1_size_bytes = (format0_1_size_bits%8 == 0) ? (uint8_t)floor(format0_1_size_bits/8) : (uint8_t)(floor(format0_1_size_bits/8) + 1);
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format0_1_size_bits=%d, format0_1_size_bytes=%d\n",
+                css_dci_format,format0_1_size_bits,format0_1_size_bytes);
+      #endif
+      // blind decoding format0_1 for aggregation level 1.  The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      // blind decoding format0_1 for aggregation level 2.  The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      // blind decoding format0_1 for aggregation level 4.  The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      // blind decoding format0_1 for aggregation level 8.  The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      // blind decoding format0_1 for aggregation level 16. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+
+      // for format1_1, first we calculate dci pdu size
+      format1_1_size_bits = nr_dci_format_size(format1_1,1,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes);
+      format1_1_size_bytes = (format1_1_size_bits%8 == 0) ? (uint8_t)floor(format1_1_size_bits/8) : (uint8_t)(floor(format1_1_size_bits/8) + 1);
+      #ifdef NR_PDCCH_DCI_DEBUG
+        printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format1_1_size_bits=%d, format1_1_size_bytes=%d\n",
+                css_dci_format,format1_1_size_bits,format1_1_size_bytes);
+      #endif
+      // blind decoding format1_1 for aggregation level 1.  The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      // blind decoding format1_1 for aggregation level 2.  The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      // blind decoding format1_1 for aggregation level 4.  The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      // blind decoding format1_1 for aggregation level 8.  The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+      // blind decoding format1_1 for aggregation level 16. The number of candidates (nrofCandidates) will be calculated in function nr_dci_decoding_procedure0
+    }
+  }
+  return(dci_cnt);
+}
+#endif
+
+
+
+
+
+/*
+uint16_t dci_decoding_procedure(PHY_VARS_NR_UE *ue,
+                                DCI_ALLOC_t *dci_alloc,
+                                int do_common,
+                                int16_t eNB_id,
+                                uint8_t nr_tti_rx)
+{
+
+  uint8_t  dci_cnt=0,old_dci_cnt=0;
+  uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0;
+  NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]];
+  NR_DL_FRAME_PARMS *frame_parms  = &ue->frame_parms;
+  uint8_t mi = get_mi(&ue->frame_parms,nr_tti_rx);
+  uint16_t ra_rnti=99;
+  uint8_t format0_found=0,format_c_found=0;
+  uint8_t tmode = ue->transmission_mode[eNB_id];
+  uint8_t frame_type = frame_parms->frame_type;
+  uint8_t format1A_size_bits=0,format1A_size_bytes=0;
+  uint8_t format1C_size_bits=0,format1C_size_bytes=0;
+  uint8_t format0_size_bits=0,format0_size_bytes=0;
+  uint8_t format1_size_bits=0,format1_size_bytes=0;
+  uint8_t format2_size_bits=0,format2_size_bytes=0;
+  uint8_t format2A_size_bits=0,format2A_size_bytes=0;
+  dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,nr_tti_rx);
+
+  switch (frame_parms->N_RB_DL) {
+  case 6:
+    if (frame_type == TDD) {
+      format1A_size_bits  = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
+      format1A_size_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
+      format1C_size_bits  = sizeof_DCI1C_1_5MHz_t;
+      format1C_size_bytes = sizeof(DCI1C_1_5MHz_t);
+      format0_size_bits  = sizeof_DCI0_1_5MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_1_5MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
+
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        format2_size_bits  = sizeof_DCI2_1_5MHz_2A_TDD_t;
+        format2_size_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t);
+        format2A_size_bits  = sizeof_DCI2A_1_5MHz_2A_TDD_t;
+        format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t);
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        format2_size_bits  = sizeof_DCI2_1_5MHz_4A_TDD_t;
+        format2_size_bytes = sizeof(DCI2_1_5MHz_4A_TDD_t);
+        format2A_size_bits  = sizeof_DCI2A_1_5MHz_4A_TDD_t;
+        format2A_size_bytes = sizeof(DCI2A_1_5MHz_4A_TDD_t);
+      }
+    } else {
+      format1A_size_bits  = sizeof_DCI1A_1_5MHz_FDD_t;
+      format1A_size_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
+      format1C_size_bits  = sizeof_DCI1C_1_5MHz_t;
+      format1C_size_bytes = sizeof(DCI1C_1_5MHz_t);
+      format0_size_bits  = sizeof_DCI0_1_5MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_1_5MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t);
+
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        format2_size_bits  = sizeof_DCI2_1_5MHz_2A_FDD_t;
+        format2_size_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t);
+        format2A_size_bits  = sizeof_DCI2A_1_5MHz_2A_FDD_t;
+        format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t);
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        format2_size_bits  = sizeof_DCI2_1_5MHz_4A_FDD_t;
+        format2_size_bytes = sizeof(DCI2_1_5MHz_4A_FDD_t);
+        format2A_size_bits  = sizeof_DCI2A_1_5MHz_4A_FDD_t;
+        format2A_size_bytes = sizeof(DCI2A_1_5MHz_4A_FDD_t);
+      }
+    }
+
+    break;
+
+  case 25:
+  default:
+    if (frame_type == TDD) {
+      format1A_size_bits  = sizeof_DCI1A_5MHz_TDD_1_6_t;
+      format1A_size_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
+      format1C_size_bits  = sizeof_DCI1C_5MHz_t;
+      format1C_size_bytes = sizeof(DCI1C_5MHz_t);
+      format0_size_bits  = sizeof_DCI0_5MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_5MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_5MHz_TDD_t);
+
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        format2_size_bits  = sizeof_DCI2_5MHz_2A_TDD_t;
+        format2_size_bytes = sizeof(DCI2_5MHz_2A_TDD_t);
+        format2A_size_bits  = sizeof_DCI2A_5MHz_2A_TDD_t;
+        format2A_size_bytes = sizeof(DCI2A_5MHz_2A_TDD_t);
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        format2_size_bits  = sizeof_DCI2_5MHz_4A_TDD_t;
+        format2_size_bytes = sizeof(DCI2_5MHz_4A_TDD_t);
+        format2A_size_bits  = sizeof_DCI2A_5MHz_4A_TDD_t;
+        format2A_size_bytes = sizeof(DCI2A_5MHz_4A_TDD_t);
+      }
+    } else {
+      format1A_size_bits  = sizeof_DCI1A_5MHz_FDD_t;
+      format1A_size_bytes = sizeof(DCI1A_5MHz_FDD_t);
+      format1C_size_bits  = sizeof_DCI1C_5MHz_t;
+      format1C_size_bytes = sizeof(DCI1C_5MHz_t);
+      format0_size_bits  = sizeof_DCI0_5MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_5MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_5MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_5MHz_FDD_t);
+
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        format2_size_bits  = sizeof_DCI2_5MHz_2A_FDD_t;
+        format2_size_bytes = sizeof(DCI2_5MHz_2A_FDD_t);
+        format2A_size_bits  = sizeof_DCI2A_5MHz_2A_FDD_t;
+        format2A_size_bytes = sizeof(DCI2A_5MHz_2A_FDD_t);
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        format2_size_bits  = sizeof_DCI2_5MHz_4A_FDD_t;
+        format2_size_bytes = sizeof(DCI2_5MHz_4A_FDD_t);
+        format2A_size_bits  = sizeof_DCI2A_5MHz_4A_FDD_t;
+        format2A_size_bytes = sizeof(DCI2A_5MHz_4A_FDD_t);
+      }
+    }
+
+    break;
+
+  case 50:
+    if (frame_type == TDD) {
+      format1A_size_bits  = sizeof_DCI1A_10MHz_TDD_1_6_t;
+      format1A_size_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
+      format1C_size_bits  = sizeof_DCI1C_10MHz_t;
+      format1C_size_bytes = sizeof(DCI1C_10MHz_t);
+      format0_size_bits  = sizeof_DCI0_10MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_10MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_10MHz_TDD_t);
+
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        format2_size_bits  = sizeof_DCI2_10MHz_2A_TDD_t;
+        format2_size_bytes = sizeof(DCI2_10MHz_2A_TDD_t);
+        format2A_size_bits  = sizeof_DCI2A_10MHz_2A_TDD_t;
+        format2A_size_bytes = sizeof(DCI2A_10MHz_2A_TDD_t);
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        format2_size_bits  = sizeof_DCI2_10MHz_4A_TDD_t;
+        format2_size_bytes = sizeof(DCI2_10MHz_4A_TDD_t);
+        format2A_size_bits  = sizeof_DCI2A_10MHz_4A_TDD_t;
+        format2A_size_bytes = sizeof(DCI2A_10MHz_4A_TDD_t);
+      }
+    } else {
+      format1A_size_bits  = sizeof_DCI1A_10MHz_FDD_t;
+      format1A_size_bytes = sizeof(DCI1A_10MHz_FDD_t);
+      format1C_size_bits  = sizeof_DCI1C_10MHz_t;
+      format1C_size_bytes = sizeof(DCI1C_10MHz_t);
+      format0_size_bits  = sizeof_DCI0_10MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_10MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_10MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_10MHz_FDD_t);
+
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        format2_size_bits  = sizeof_DCI2_10MHz_2A_FDD_t;
+        format2_size_bytes = sizeof(DCI2_10MHz_2A_FDD_t);
+        format2A_size_bits  = sizeof_DCI2A_10MHz_2A_FDD_t;
+        format2A_size_bytes = sizeof(DCI2A_10MHz_2A_FDD_t);
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        format2_size_bits  = sizeof_DCI2_10MHz_4A_FDD_t;
+        format2_size_bytes = sizeof(DCI2_10MHz_4A_FDD_t);
+        format2A_size_bits  = sizeof_DCI2A_10MHz_4A_FDD_t;
+        format2A_size_bytes = sizeof(DCI2A_10MHz_4A_FDD_t);
+      }
+    }
+
+    break;
+
+  case 100:
+    if (frame_type == TDD) {
+      format1A_size_bits  = sizeof_DCI1A_20MHz_TDD_1_6_t;
+      format1A_size_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
+      format1C_size_bits  = sizeof_DCI1C_20MHz_t;
+      format1C_size_bytes = sizeof(DCI1C_20MHz_t);
+      format0_size_bits  = sizeof_DCI0_20MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_20MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_20MHz_TDD_t);
+
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        format2_size_bits  = sizeof_DCI2_20MHz_2A_TDD_t;
+        format2_size_bytes = sizeof(DCI2_20MHz_2A_TDD_t);
+        format2A_size_bits  = sizeof_DCI2A_20MHz_2A_TDD_t;
+        format2A_size_bytes = sizeof(DCI2A_20MHz_2A_TDD_t);
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        format2_size_bits  = sizeof_DCI2_20MHz_4A_TDD_t;
+        format2_size_bytes = sizeof(DCI2_20MHz_4A_TDD_t);
+        format2A_size_bits  = sizeof_DCI2A_20MHz_4A_TDD_t;
+        format2A_size_bytes = sizeof(DCI2A_20MHz_4A_TDD_t);
+      }
+    } else {
+      format1A_size_bits  = sizeof_DCI1A_20MHz_FDD_t;
+      format1A_size_bytes = sizeof(DCI1A_20MHz_FDD_t);
+      format1C_size_bits  = sizeof_DCI1C_20MHz_t;
+      format1C_size_bytes = sizeof(DCI1C_20MHz_t);
+      format0_size_bits  = sizeof_DCI0_20MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_20MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_20MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_20MHz_FDD_t);
+
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        format2_size_bits  = sizeof_DCI2_20MHz_2A_FDD_t;
+        format2_size_bytes = sizeof(DCI2_20MHz_2A_FDD_t);
+        format2A_size_bits  = sizeof_DCI2A_20MHz_2A_FDD_t;
+        format2A_size_bytes = sizeof(DCI2A_20MHz_2A_FDD_t);
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        format2_size_bits  = sizeof_DCI2_20MHz_4A_FDD_t;
+        format2_size_bytes = sizeof(DCI2_20MHz_4A_FDD_t);
+        format2A_size_bits  = sizeof_DCI2A_20MHz_4A_FDD_t;
+        format2A_size_bytes = sizeof(DCI2A_20MHz_4A_FDD_t);
+      }
+    }
+
+    break;
+  }
+
+  if (do_common == 1) {
+#ifdef DEBUG_DCI_DECODING
+    printf("[DCI search] doing common search/format0 aggregation 4\n");
+#endif
+
+    if (ue->prach_resources[eNB_id])
+      ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+
+    // First check common search spaces at aggregation 4 (SI_RNTI, P_RNTI and RA_RNTI format 0/1A),
+    // and UE_SPEC format0 (PUSCH) too while we're at it
+    dci_decoding_procedure0(pdcch_vars,1,mode,nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0) ,
+                            ra_rnti,
+                            P_RNTI,
+                            2,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format0,
+                            format1A_size_bits,
+                            format1A_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff) ||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    // Now check common search spaces at aggregation 4 (SI_RNTI,P_RNTI and RA_RNTI and C-RNTI format 1C),
+    // and UE_SPEC format0 (PUSCH) too while we're at it
+    dci_decoding_procedure0(pdcch_vars,1,mode,nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+                            P_RNTI,
+                            2,
+                            format1C,
+                            format1C,
+                            format1C,
+                            format1C,
+                            format1C_size_bits,
+                            format1C_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff) ||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    // Now check common search spaces at aggregation 8 (SI_RNTI,P_RNTI and RA_RNTI format 1A),
+    // and UE_SPEC format0 (PUSCH) too while we're at it
+    //  printf("[DCI search] doing common search/format0 aggregation 3\n");
+#ifdef DEBUG_DCI_DECODING
+    printf("[DCI search] doing common search/format0 aggregation 8\n");
+#endif
+    dci_decoding_procedure0(pdcch_vars,1,mode,nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+			    P_RNTI,
+                            ra_rnti,
+                            3,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format0,
+                            format1A_size_bits,
+                            format1A_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    // Now check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI and C-RNTI format 1C),
+    // and UE_SPEC format0 (PUSCH) too while we're at it
+    dci_decoding_procedure0(pdcch_vars,1,mode,nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+			    3,
+                            format1C,
+                            format1C,
+                            format1C,
+                            format1C,
+                            format1C_size_bits,
+                            format1C_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+    //#endif
+
+  }
+
+  if (ue->UE_mode[eNB_id] <= PRACH)
+    return(dci_cnt);
+
+  if (ue->prach_resources[eNB_id])
+    ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+
+  // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8
+  //  printf("[DCI search] Format 0/1A aggregation 8\n");
+  dci_decoding_procedure0(pdcch_vars,0,mode,
+                          nr_tti_rx,
+                          dci_alloc,
+                          eNB_id,
+                          ue->current_thread_id[nr_tti_rx],
+                          frame_parms,
+                          mi,
+                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                          ra_rnti,
+                          P_RNTI,
+                          0,
+                          format1A,
+                          format1A,
+                          format1A,
+                          format0,
+                          format0_size_bits,
+                          format0_size_bytes,
+                          &dci_cnt,
+                          &format0_found,
+                          &format_c_found,
+                          &CCEmap0,
+                          &CCEmap1,
+                          &CCEmap2);
+
+  if ((CCEmap0==0xffff)||
+      ((format0_found==1)&&(format_c_found==1)))
+    return(dci_cnt);
+
+  //printf("[DCI search] Format 0 aggregation 1 dci_cnt %d\n",dci_cnt);
+
+  if (dci_cnt == 0)
+  {
+  // Now check UE_SPEC format 0 search spaces at aggregation 4
+  dci_decoding_procedure0(pdcch_vars,0,mode,
+                          nr_tti_rx,
+                          dci_alloc,
+                          eNB_id,
+                          ue->current_thread_id[nr_tti_rx],
+                          frame_parms,
+                          mi,
+                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                          ra_rnti,
+			  P_RNTI,
+			  1,
+                          format1A,
+                          format1A,
+                          format1A,
+                          format0,
+                          format0_size_bits,
+                          format0_size_bytes,
+                          &dci_cnt,
+                          &format0_found,
+                          &format_c_found,
+                          &CCEmap0,
+                          &CCEmap1,
+                          &CCEmap2);
+
+  if ((CCEmap0==0xffff)||
+      ((format0_found==1)&&(format_c_found==1)))
+    return(dci_cnt);
+
+
+  //printf("[DCI search] Format 0 aggregation 2 dci_cnt %d\n",dci_cnt);
+  }
+
+  if (dci_cnt == 0)
+  {
+  // Now check UE_SPEC format 0 search spaces at aggregation 2
+  dci_decoding_procedure0(pdcch_vars,0,mode,
+                          nr_tti_rx,
+                          dci_alloc,
+                          eNB_id,
+                          ue->current_thread_id[nr_tti_rx],
+                          frame_parms,
+                          mi,
+                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                          ra_rnti,
+			  P_RNTI,
+                          2,
+                          format1A,
+                          format1A,
+                          format1A,
+                          format0,
+                          format0_size_bits,
+                          format0_size_bytes,
+                          &dci_cnt,
+                          &format0_found,
+                          &format_c_found,
+                          &CCEmap0,
+                          &CCEmap1,
+                          &CCEmap2);
+
+  if ((CCEmap0==0xffff)||
+      ((format0_found==1)&&(format_c_found==1)))
+    return(dci_cnt);
+
+  //printf("[DCI search] Format 0 aggregation 4 dci_cnt %d\n",dci_cnt);
+  }
+
+  if (dci_cnt == 0)
+  {
+  // Now check UE_SPEC format 0 search spaces at aggregation 1
+  dci_decoding_procedure0(pdcch_vars,0,mode,
+                          nr_tti_rx,
+                          dci_alloc,
+                          eNB_id,
+                          ue->current_thread_id[nr_tti_rx],
+                          frame_parms,
+                          mi,
+                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                          ra_rnti,
+			  P_RNTI,
+                          3,
+                          format1A,
+                          format1A,
+                          format1A,
+                          format0,
+                          format0_size_bits,
+                          format0_size_bytes,
+                          &dci_cnt,
+                          &format0_found,
+                          &format_c_found,
+                          &CCEmap0,
+                          &CCEmap1,
+                          &CCEmap2);
+
+  if ((CCEmap0==0xffff)||
+      ((format0_found==1)&&(format_c_found==1)))
+    return(dci_cnt);
+
+  //printf("[DCI search] Format 0 aggregation 8 dci_cnt %d\n",dci_cnt);
+
+  }
+  // These are for CRNTI based on transmission mode
+  if ((tmode < 3) || (tmode == 7)) {
+    // Now check UE_SPEC format 1 search spaces at aggregation 1
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            0,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format1,
+                            format1_size_bits,
+                            format1_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+    //printf("[DCI search] Format 1 aggregation 1 dci_cnt %d\n",dci_cnt);
+
+    if ((CCEmap0==0xffff) ||
+        (format_c_found==1))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    // Now check UE_SPEC format 1 search spaces at aggregation 2
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            1,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format1,
+                            format1_size_bits,
+                            format1_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+    //printf("[DCI search] Format 1 aggregation 2 dci_cnt %d\n",dci_cnt);
+
+    if ((CCEmap0==0xffff)||
+        (format_c_found==1))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    // Now check UE_SPEC format 1 search spaces at aggregation 4
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+			    2,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format1,
+                            format1_size_bits,
+                            format1_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+    //printf("[DCI search] Format 1 aggregation 4 dci_cnt %d\n",dci_cnt);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    //#ifdef ALL_AGGREGATION
+    // Now check UE_SPEC format 1 search spaces at aggregation 8
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            3,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format1,
+                            format1_size_bits,
+                            format1_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+    //printf("[DCI search] Format 1 aggregation 8 dci_cnt %d\n",dci_cnt);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    //#endif //ALL_AGGREGATION
+  } else if (tmode == 3) {
+
+
+    LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes);
+    // Now check UE_SPEC format 2A_2A search spaces at aggregation 1
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+                            P_RNTI,
+                            0,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format2A,
+                            format2A_size_bits,
+                            format2A_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    LOG_D(PHY," format 2A_2A search CCEmap0 %x, format0_found %d, format_c_found %d \n", CCEmap0, format0_found, format_c_found);
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt);
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    // Now check UE_SPEC format 2 search spaces at aggregation 2
+    LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 2 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes);
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            1,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format2A,
+                            format2A_size_bits,
+                            format2A_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt);
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    // Now check UE_SPEC format 2_2A search spaces at aggregation 4
+    LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 4 \n");
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+                            P_RNTI,
+                            2,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format2A,
+                            format2A_size_bits,
+                            format2A_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt);
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    //#ifdef ALL_AGGREGATION
+    // Now check UE_SPEC format 2_2A search spaces at aggregation 8
+    LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 8 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes);
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            3,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format2A,
+                            format2A_size_bits,
+                            format2A_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+    //#endif
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt);
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+  } else if (tmode == 4) {
+
+    // Now check UE_SPEC format 2_2A search spaces at aggregation 1
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            0,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format2,
+                            format2_size_bits,
+                            format2_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    // Now check UE_SPEC format 2 search spaces at aggregation 2
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            1,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format2,
+                            format2_size_bits,
+                            format2_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    // Now check UE_SPEC format 2_2A search spaces at aggregation 4
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            2,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format2,
+                            format2_size_bits,
+                            format2_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    //#ifdef ALL_AGGREGATION
+    // Now check UE_SPEC format 2_2A search spaces at aggregation 8
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            3,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format2,
+                            format2_size_bits,
+                            format2_size_bytes,
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+    //#endif
+  } else if ((tmode==5) || (tmode==6)) { // This is MU-MIMO
+
+    // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 1
+#ifdef DEBUG_DCI_DECODING
+    LOG_I(PHY," MU-MIMO check UE_SPEC format 1E_2A_M10PRB\n");
+#endif
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            0,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format1E_2A_M10PRB,
+                            sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t,
+                            sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t),
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 2
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            1,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format1E_2A_M10PRB,
+                            sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t,
+                            sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t),
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 4
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            2,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format1E_2A_M10PRB,
+                            sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t,
+                            sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t),
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    //#ifdef ALL_AGGREGATION
+
+    // Now check UE_SPEC format 1E_2A_M10PRB search spaces at aggregation 8
+    old_dci_cnt=dci_cnt;
+    dci_decoding_procedure0(pdcch_vars,0,mode,
+                            nr_tti_rx,
+                            dci_alloc,
+                            eNB_id,
+                            ue->current_thread_id[nr_tti_rx],
+                            frame_parms,
+                            mi,
+                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                            ra_rnti,
+			    P_RNTI,
+                            3,
+                            format1A,
+                            format1A,
+                            format1A,
+                            format1E_2A_M10PRB,
+                            sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t,
+                            sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t),
+                            &dci_cnt,
+                            &format0_found,
+                            &format_c_found,
+                            &CCEmap0,
+                            &CCEmap1,
+                            &CCEmap2);
+
+    if ((CCEmap0==0xffff)||
+        ((format0_found==1)&&(format_c_found==1)))
+      return(dci_cnt);
+
+    if (dci_cnt>old_dci_cnt)
+      return(dci_cnt);
+
+    //#endif  //ALL_AGGREGATION
+
+  }
+
+  return(dci_cnt);
+}
+*/
+#ifdef PHY_ABSTRACTION
+uint16_t dci_decoding_procedure_emul(NR_UE_PDCCH **pdcch_vars,
+                                     uint8_t num_ue_spec_dci,
+                                     uint8_t num_common_dci,
+                                     DCI_ALLOC_t *dci_alloc_tx,
+                                     DCI_ALLOC_t *dci_alloc_rx,
+                                     int16_t eNB_id)
+{
+
+  uint8_t  dci_cnt=0,i;
+
+  memcpy(dci_alloc_rx,dci_alloc_tx,num_common_dci*sizeof(DCI_ALLOC_t));
+  dci_cnt = num_common_dci;
+  LOG_D(PHY,"[DCI][EMUL] : num_common_dci %d\n",num_common_dci);
+
+  for (i=num_common_dci; i<(num_ue_spec_dci+num_common_dci); i++) {
+    LOG_D(PHY,"[DCI][EMUL] Checking dci %d => %x format %d (bit 0 %d)\n",i,pdcch_vars[eNB_id]->crnti,dci_alloc_tx[i].format,
+          dci_alloc_tx[i].dci_pdu[0]&0x80);
+
+    if (dci_alloc_tx[i].rnti == pdcch_vars[eNB_id]->crnti) {
+      memcpy(dci_alloc_rx+dci_cnt,dci_alloc_tx+i,sizeof(DCI_ALLOC_t));
+      dci_cnt++;
+    }
+  }
+
+
+  return(dci_cnt);
+}
+#endif
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.h b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d12b1e2a01f9cefaa6674615f608322f6afa40d
--- /dev/null
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.h
@@ -0,0 +1,111 @@
+/*
+ * 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.1  (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/dci_nr.h
+* \brief typedefs for NR DCI structures from 38-212.
+* \author R. Knopp, A. Mico Pereperez
+* \date 2018
+* \version 0.1
+* \company Eurecom
+* \email: knopp@eurecom.fr
+* \note
+* \warning
+*/
+#ifndef USER_MODE
+#include "PHY/types.h"
+#else
+#include <stdint.h>
+#endif
+
+
+
+#define MAX_DCI_SIZE_BITS 45
+
+
+#define NR_PDCCH_DCI_H
+#ifdef NR_PDCCH_DCI_H
+struct NR_DCI_INFO_EXTRACTED {
+  uint8_t carrier_ind                     ; // 0  CARRIER_IND: 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213]
+  uint8_t sul_ind_0_1                     ; // 1  SUL_IND_0_1:
+  uint8_t identifier_dci_formats          ; // 2  IDENTIFIER_DCI_FORMATS:
+  uint8_t slot_format_ind                 ; // 3  SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213]
+  uint8_t pre_emption_ind                 ; // 4  PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits
+  uint8_t tpc_cmd_number                  ; // 5  TPC_CMD_NUMBER: The parameter xxx provided by higher layers determines the index to the TPC command number for an UL of a cell. Each TPC command number is 2 bits
+  uint8_t block_number                    ; // 6  BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3
+  uint8_t bandwidth_part_ind              ; // 7  BANDWIDTH_PART_IND:
+  uint16_t freq_dom_resource_assignment_UL; // 8  FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered
+                                            // (NOTE 1) If DCI format 0_0 is monitored in common search space
+                                            // and if the number of information bits in the DCI format 0_0 prior to padding
+                                            // is larger than the payload size of the DCI format 1_0 monitored in common search space
+                                            // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0
+                                            // is reduced such that the size of DCI format 0_0 equals to the size of the DCI format 1_0
+  uint16_t freq_dom_resource_assignment_DL; // 9  FREQ_DOM_RESOURCE_ASSIGNMENT_DL:
+  uint8_t time_dom_resource_assignment    ; // 10 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits,
+                                            // where I the number of entries in the higher layer parameter pusch-AllocationList
+  uint8_t vrb_to_prb_mapping              ; // 11 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0
+  uint8_t prb_bundling_size_ind           ; // 12 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214]
+  uint8_t rate_matching_ind               ; // 13 RATE_MATCHING_IND: 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set
+  uint8_t zp_csi_rs_trigger               ; // 14 ZP_CSI_RS_TRIGGER:
+  uint8_t freq_hopping_flag               ; // 15 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0
+  uint8_t tb1_mcs                         ; // 16 TB1_MCS:
+  uint8_t tb1_ndi                         ; // 17 TB1_NDI:
+  uint8_t tb1_rv                          ; // 18 TB1_RV:
+  uint8_t tb2_mcs                         ; // 19 TB2_MCS:
+  uint8_t tb2_ndi                         ; // 20 TB2_NDI:
+  uint8_t tb2_rv                          ; // 21 TB2_RV:
+  uint8_t mcs                             ; // 22 MCS:
+  uint8_t ndi                             ; // 23 NDI:
+  uint8_t rv                              ; // 24 RV:
+  uint8_t harq_process_number             ; // 25 HARQ_PROCESS_NUMBER:
+  uint8_t dai                             ; // 26 DAI: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI
+                                            // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI
+                                            // 0 otherwise
+  uint8_t first_dai                       ; // 27 FIRST_DAI: (1 or 2 bits) 1 bit for semi-static HARQ-ACK
+  uint8_t second_dai                      ; // 28 SECOND_DAI: (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks
+  uint8_t tpc_pusch                       ; // 29 TPC_PUSCH:
+  uint8_t tpc_pucch                       ; // 30 TPC_PUCCH:
+  uint8_t pucch_resource_ind              ; // 31 PUCCH_RESOURCE_IND:
+  uint8_t pdsch_to_harq_feedback_time_ind ; // 32 PDSCH_TO_HARQ_FEEDBACK_TIME_IND:
+  uint8_t short_message_ind               ; // 33 SHORT_MESSAGE_IND: 1 bit if crc scrambled with P-RNTI
+  uint8_t srs_resource_ind                ; // 34 SRS_RESOURCE_IND:
+  uint8_t precod_nbr_layers               ; // 35 PRECOD_NBR_LAYERS:
+  uint8_t antenna_ports                   ; // 36 ANTENNA_PORTS:
+  uint8_t tci                             ; // 37 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits
+  uint8_t srs_request                     ; // 38 SRS_REQUEST:
+  uint8_t tpc_cmd_number_format2_3        ; // 39 TPC_CMD_NUMBER_FORMAT2_3:
+  uint8_t csi_request                     ; // 40 CSI_REQUEST:
+  uint8_t cbgti                           ; // 41 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH
+  uint8_t cbgfi                           ; // 42 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator
+  uint8_t ptrs_dmrs                       ; // 43 PTRS_DMRS:
+  uint8_t beta_offset_ind                 ; // 44 BETA_OFFSET_IND:
+  uint8_t dmrs_seq_ini                    ; // 45 DMRS_SEQ_INI: 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding
+                                            // is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise
+  uint8_t sul_ind_0_0                     ; // 46 SUL_IND_0_0:
+  uint16_t padding                        ; // 47 PADDING: (Note 2) If DCI format 0_0 is monitored in common search space
+                                            // and if the number of information bits in the DCI format 0_0 prior to padding
+                                            // is less than the payload size of the DCI format 1_0 monitored in common search space
+                                            // zeros shall be appended to the DCI format 0_0
+                                            // until the payload size equals that of the DCI format 1_0
+
+};
+typedef struct NR_DCI_INFO_EXTRACTED NR_DCI_INFO_EXTRACTED_t;
+#endif
+
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
new file mode 100644
index 0000000000000000000000000000000000000000..03fb91e7fa3a7ce9c14cc6e05f8a5998381d87b2
--- /dev/null
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
@@ -0,0 +1,10080 @@
+/*
+ * 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.1  (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/dci_tools_nr.c
+ * \brief PHY Support routines (eNB/UE) for filling PDSCH/PUSCH/DLSCH/ULSCH data structures based on DCI PDUs generated by eNB MAC scheduler.
+ * \author R. Knopp, A. Mico Pereperez
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+//#include "PHY/defs.h"
+#include "PHY/defs_nr_UE.h"
+//#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
+//#include "PHY/extern.h"
+//#include "SCHED/defs.h"
+#ifdef DEBUG_DCI_TOOLS
+#include "PHY/vars.h"
+#endif
+#include "assertions.h"
+
+
+//#define DEBUG_HARQ
+
+//#include "LAYER2/MAC/extern.h"
+//#include "LAYER2/MAC/defs.h"
+//#include "../openair2/LAYER2/MAC/extern.h"
+//#include "../openair2/LAYER2/MAC/defs.h"
+
+//#define DEBUG_DCI
+#define NR_PDCCH_DCI_TOOLS
+#define NR_PDCCH_DCI_TOOLS_DEBUG
+
+#if 0
+
+uint32_t localRIV2alloc_LUT6[32];
+uint32_t distRIV2alloc_even_LUT6[32];
+uint32_t distRIV2alloc_odd_LUT6[32];
+uint16_t RIV2nb_rb_LUT6[32];
+uint16_t RIV2first_rb_LUT6[32];
+uint16_t RIV_max6=0;
+
+uint32_t localRIV2alloc_LUT25[512];
+uint32_t distRIV2alloc_even_LUT25[512];
+uint32_t distRIV2alloc_odd_LUT25[512];
+uint16_t RIV2nb_rb_LUT25[512];
+uint16_t RIV2first_rb_LUT25[512];
+uint16_t RIV_max25=0;
+
+
+uint32_t localRIV2alloc_LUT50_0[1600];
+uint32_t localRIV2alloc_LUT50_1[1600];
+uint32_t distRIV2alloc_gap0_even_LUT50_0[1600];
+uint32_t distRIV2alloc_gap0_odd_LUT50_0[1600];
+uint32_t distRIV2alloc_gap0_even_LUT50_1[1600];
+uint32_t distRIV2alloc_gap0_odd_LUT50_1[1600];
+uint32_t distRIV2alloc_gap1_even_LUT50_0[1600];
+uint32_t distRIV2alloc_gap1_odd_LUT50_0[1600];
+uint32_t distRIV2alloc_gap1_even_LUT50_1[1600];
+uint32_t distRIV2alloc_gap1_odd_LUT50_1[1600];
+uint16_t RIV2nb_rb_LUT50[1600];
+uint16_t RIV2first_rb_LUT50[1600];
+uint16_t RIV_max50=0;
+
+uint32_t localRIV2alloc_LUT100_0[6000];
+uint32_t localRIV2alloc_LUT100_1[6000];
+uint32_t localRIV2alloc_LUT100_2[6000];
+uint32_t localRIV2alloc_LUT100_3[6000];
+uint32_t distRIV2alloc_gap0_even_LUT100_0[6000];
+uint32_t distRIV2alloc_gap0_odd_LUT100_0[6000];
+uint32_t distRIV2alloc_gap0_even_LUT100_1[6000];
+uint32_t distRIV2alloc_gap0_odd_LUT100_1[6000];
+uint32_t distRIV2alloc_gap0_even_LUT100_2[6000];
+uint32_t distRIV2alloc_gap0_odd_LUT100_2[6000];
+uint32_t distRIV2alloc_gap0_even_LUT100_3[6000];
+uint32_t distRIV2alloc_gap0_odd_LUT100_3[6000];
+uint32_t distRIV2alloc_gap1_even_LUT100_0[6000];
+uint32_t distRIV2alloc_gap1_odd_LUT100_0[6000];
+uint32_t distRIV2alloc_gap1_even_LUT100_1[6000];
+uint32_t distRIV2alloc_gap1_odd_LUT100_1[6000];
+uint32_t distRIV2alloc_gap1_even_LUT100_2[6000];
+uint32_t distRIV2alloc_gap1_odd_LUT100_2[6000];
+uint32_t distRIV2alloc_gap1_even_LUT100_3[6000];
+uint32_t distRIV2alloc_gap1_odd_LUT100_3[6000];
+uint16_t RIV2nb_rb_LUT100[6000];
+uint16_t RIV2first_rb_LUT100[6000];
+uint16_t RIV_max100=0;
+
+
+extern uint32_t current_dlsch_cqi;
+
+// Table 8.6.3-3 36.213
+uint16_t beta_cqi[16] = {0,   //reserved
+                         0,   //reserved
+                         9,   //1.125
+                         10,  //1.250
+                         11,  //1.375
+                         13,  //1.625
+                         14,  //1.750
+                         16,  //2.000
+                         18,  //2.250
+                         20,  //2.500
+                         23,  //2.875
+                         25,  //3.125
+                         28,  //3.500
+                         32,  //4.000
+                         40,  //5.000
+                         50
+                        }; //6.250
+
+// Table 8.6.3-2 36.213
+uint16_t beta_ri[16] = {10,   //1.250
+                        13,   //1.625
+                        16,   //2.000
+                        20,   //2.500
+                        25,   //3.125
+                        32,   //4.000
+                        40,   //5.000
+                        50,   //6.250
+                        64,   //8.000
+                        80,   //10.000
+                        101,  //12.625
+                        127,  //15.875
+                        160,  //20.000
+                        0,    //reserved
+                        0,    //reserved
+                        0
+                       };   //reserved
+
+// Table 8.6.3-2 36.213
+uint16_t beta_ack[16] = {16,  //2.000
+                         20,  //2.500
+                         25,  //3.125
+                         32,  //4.000
+                         40,  //5.000
+                         50,  //6.250
+                         64,  //8.000
+                         80,  //10.000
+                         101, //12.625
+                         127, //15.875
+                         160, //20.000
+                         248, //31.000
+                         400, //50.000
+                         640, //80.000
+                         808
+                        };//126.00
+
+
+#endif
+int8_t delta_PUSCH_abs[4] = {-4,-1,1,4};
+int8_t delta_PUSCH_acc[4] = {-1,0,1,3};
+int8_t *delta_PUCCH_lut = delta_PUSCH_acc;
+
+#if 0
+void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2)
+{
+
+  uint32_t i,shift,subset;
+  rb_alloc2[0] = 0;
+  rb_alloc2[1] = 0;
+  rb_alloc2[2] = 0;
+  rb_alloc2[3] = 0;
+
+  //  printf("N_RB_DL %d, ra_header %d, rb_alloc %x\n",N_RB_DL,ra_header,rb_alloc);
+
+  switch (N_RB_DL) {
+
+  case 6:
+    rb_alloc2[0] = rb_alloc&0x3f;
+    break;
+
+  case 25:
+    if (ra_header == 0) {// Type 0 Allocation
+
+      for (i=12; i>0; i--) {
+        if ((rb_alloc&(1<<i)) != 0)
+          rb_alloc2[0] |= (3<<((2*(12-i))));
+
+        //      printf("rb_alloc2 (type 0) %x\n",rb_alloc2);
+      }
+
+      if ((rb_alloc&1) != 0)
+        rb_alloc2[0] |= (1<<24);
+    } else {
+      subset = rb_alloc&1;
+      shift  = (rb_alloc>>1)&1;
+
+      for (i=0; i<11; i++) {
+        if ((rb_alloc&(1<<(i+2))) != 0)
+          rb_alloc2[0] |= (1<<(2*i));
+
+        //printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
+      }
+
+      if ((shift == 0) && (subset == 1))
+        rb_alloc2[0]<<=1;
+      else if ((shift == 1) && (subset == 0))
+        rb_alloc2[0]<<=4;
+      else if ((shift == 1) && (subset == 1))
+        rb_alloc2[0]<<=3;
+    }
+
+    break;
+
+  case 50:
+    if (ra_header == 0) {// Type 0 Allocation
+
+      for (i=16; i>0; i--) {
+        if ((rb_alloc&(1<<i)) != 0)
+          rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32));
+      }
+
+      /*
+      for (i=1;i<=16;i++) {
+        if ((rb_alloc&(1<<(16-i))) != 0)
+      rb_alloc2[(3*i)>>5] |= (7<<((3*i)%32));
+      }
+      */
+      // bit mask across
+      if ((rb_alloc2[0]>>31)==1)
+        rb_alloc2[1] |= 1;
+
+      if ((rb_alloc&1) != 0)
+        rb_alloc2[1] |= (3<<16);
+
+      /*
+        for (i=0;i<16;i++) {
+        if (((rb_alloc>>(16-i))&1) != 0)
+        rb_alloc2[(3*i)>>5] |= (7<<((3*i)%32));
+        if ((i==10)&&((rb_alloc&(1<<6))!=0))
+        rb_alloc2[1] = 1;
+        //  printf("rb_alloc2[%d] (type 0) %x ((%x>>%d)&1=%d)\n",(3*i)>>5,rb_alloc2[(3*i)>>5],rb_alloc,i,(rb_alloc>>i)&1);
+
+        }
+        // fill in 2 from last bit instead of 3
+        if ((rb_alloc&1) != 0)
+        rb_alloc2[1] |= (3<<i);
+        //    printf("rb_alloc2[%d] (type 0) %x ((%x>>%d)&1=%d)\n",(3*i)>>5,rb_alloc2[(3*i)>>5],rb_alloc,i,(rb_alloc>>i)&1);
+        */
+      //      printf("rb_alloc[1]=%x,rb_alloc[0]=%x\n",rb_alloc2[1],rb_alloc2[0]);
+    } else {
+      LOG_E(PHY,"resource type 1 not supported for  N_RB_DL=50\n");
+      //      mac_xface->macphy_exit("resource type 1 not supported for  N_RB_DL=100\n");
+      /*
+      subset = rb_alloc&1;
+      shift  = (rb_alloc>>1)&1;
+      for (i=0;i<11;i++) {
+      if ((rb_alloc&(1<<(i+2))) != 0)
+      rb_alloc2 |= (1<<(2*i));
+      //      printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
+      }
+      if ((shift == 0) && (subset == 1))
+      rb_alloc2<<=1;
+      else if ((shift == 1) && (subset == 0))
+      rb_alloc2<<=4;
+      else if ((shift == 1) && (subset == 1))
+      rb_alloc2<<=3;
+      */
+    }
+
+    break;
+
+  case 100:
+    if (ra_header == 0) {// Type 0 Allocation
+      for (i=0; i<25; i++) {
+        if ((rb_alloc&(1<<(24-i))) != 0)
+          rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32));
+
+        //  printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i));
+      }
+    } else {
+      LOG_E(PHY,"resource type 1 not supported for  N_RB_DL=100\n");
+      //      mac_xface->macphy_exit("resource type 1 not supported for  N_RB_DL=100\n");
+      /*
+      subset = rb_alloc&1;
+      shift  = (rb_alloc>>1)&1;
+      for (i=0;i<11;i++) {
+      if ((rb_alloc&(1<<(i+2))) != 0)
+      rb_alloc2 |= (1<<(2*i));
+      //      printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
+      }
+      if ((shift == 0) && (subset == 1))
+      rb_alloc2<<=1;
+      else if ((shift == 1) && (subset == 0))
+      rb_alloc2<<=4;
+      else if ((shift == 1) && (subset == 1))
+      rb_alloc2<<=3;
+      */
+    }
+
+    break;
+
+  default:
+    LOG_E(PHY,"Invalid N_RB_DL %d\n", N_RB_DL);
+    DevParam (N_RB_DL, 0, 0);
+    break;
+  }
+
+}
+
+
+
+uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL)
+{
+
+  uint32_t nprb=0,i;
+
+  switch (N_RB_DL) {
+  case 6:
+    for (i=0; i<6; i++) {
+      if ((rb_alloc&(1<<i)) != 0)
+        nprb += 1;
+    }
+
+    break;
+
+  case 25:
+    if (ra_header == 0) {// Type 0 Allocation
+
+      for (i=12; i>0; i--) {
+        if ((rb_alloc&(1<<i)) != 0)
+          nprb += 2;
+      }
+
+      if ((rb_alloc&1) != 0)
+        nprb += 1;
+    } else {
+      for (i=0; i<11; i++) {
+        if ((rb_alloc&(1<<(i+2))) != 0)
+          nprb += 1;
+      }
+    }
+
+    break;
+
+  case 50:
+    if (ra_header == 0) {// Type 0 Allocation
+
+      for (i=0; i<16; i++) {
+        if ((rb_alloc&(1<<(16-i))) != 0)
+          nprb += 3;
+      }
+
+      if ((rb_alloc&1) != 0)
+        nprb += 2;
+
+    } else {
+      for (i=0; i<17; i++) {
+        if ((rb_alloc&(1<<(i+2))) != 0)
+          nprb += 1;
+      }
+    }
+
+    break;
+
+  case 100:
+    if (ra_header == 0) {// Type 0 Allocation
+
+      for (i=0; i<25; i++) {
+        if ((rb_alloc&(1<<(24-i))) != 0)
+          nprb += 4;
+      }
+    } else {
+      for (i=0; i<25; i++) {
+        if ((rb_alloc&(1<<(i+2))) != 0)
+          nprb += 1;
+      }
+    }
+
+    break;
+
+  default:
+    LOG_E(PHY,"Invalide N_RB_DL %d\n", N_RB_DL);
+    DevParam (N_RB_DL, 0, 0);
+    break;
+  }
+
+  return(nprb);
+}
+
+uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs)
+{
+
+  uint16_t RIV;
+
+  if (Lcrbs<=(1+(N_RB_DL>>1)))
+    RIV = (N_RB_DL*(Lcrbs-1)) + RBstart;
+  else
+    RIV = (N_RB_DL*(N_RB_DL+1-Lcrbs)) + (N_RB_DL-1-RBstart);
+
+  return(RIV);
+}
+
+// Convert a DCI Format 1C RIV to a Format 1A RIV
+// This extracts the start and length in PRBs from the 1C rballoc and
+// recomputes the RIV as if it were the 1A rballoc
+
+uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) {
+
+  int NpDLVRB,N_RB_step,LpCRBsm1,RBpstart;
+
+  switch (N_RB_DL) {
+
+  case 6: // N_RB_step = 2, NDLVRB = 6, NpDLVRB = 3
+    NpDLVRB   = 3;
+    N_RB_step = 2;
+    break;
+  case 25: // N_RB_step = 2, NDLVRB = 24, NpDLVRB = 12
+    NpDLVRB   = 12;
+    N_RB_step = 2;
+    break;
+  case 50: // N_RB_step = 4, NDLVRB = 46, NpDLVRB = 11
+    NpDLVRB   = 11;
+    N_RB_step = 4;
+    break;
+  case 100: // N_RB_step = 4, NDLVRB = 96, NpDLVRB = 24
+    NpDLVRB   = 24;
+    N_RB_step = 4;
+    break;
+  default:
+    NpDLVRB   = 24;
+    N_RB_step = 4;
+    break;
+  }
+
+  // This is the 1C part from 7.1.6.3 in 36.213
+  LpCRBsm1 = rballoc/NpDLVRB;
+  //  printf("LpCRBs = %d\n",LpCRBsm1+1);
+
+  if (LpCRBsm1 <= (NpDLVRB/2)) {
+    RBpstart = rballoc % NpDLVRB;
+  }
+  else {
+    LpCRBsm1 = NpDLVRB-LpCRBsm1;
+    RBpstart = NpDLVRB-(rballoc%NpDLVRB);
+  }
+  //  printf("RBpstart %d\n",RBpstart);
+  return(computeRIV(N_RB_DL,N_RB_step*RBpstart,N_RB_step*(LpCRBsm1+1)));
+
+}
+
+uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {
+
+  int offset;
+
+  switch (N_RB_DL) {
+
+  case 6:
+  // N_RB_DL = tildeN_RB_DL = 6
+  // Ngap = 4 , P=1, Nrow = 2, Nnull = 2
+
+    switch (vrb) {
+    case 0:  // even: 0->0, 1->2, odd: 0->3, 1->5
+    case 1:
+      return ((3*odd_slot) + 2*(vrb&3))%6;
+      break;
+    case 2:  // even: 2->3, 3->5, odd: 2->0, 3->2
+    case 3:
+      return ((3*odd_slot) + 2*(vrb&3) + 5)%6;
+      break;
+    case 4:  // even: 4->1, odd: 4->4
+      return ((3*odd_slot) + 1)%6;
+    case 5:  // even: 5->4, odd: 5->1
+      return ((3*odd_slot) + 4)%6;
+      break;
+    }
+    break;
+
+  case 15:
+    if (vrb<12) {
+      if ((vrb&3) < 2)     // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11
+  return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14);
+      else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13
+  return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14);
+    }
+    if (vrb==12)
+      return (3+(7*odd_slot)) % 14;
+    if (vrb==13)
+      return (10+(7*odd_slot)) % 14;
+    return 14;
+    break;
+
+  case 25:
+    return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24);
+    break;
+
+  case 50: // P=3
+    if (Ngap==0) {
+      // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27
+      if (vrb>=23)
+  offset=4;
+      else
+  offset=0;
+      if (vrb<44) {
+  if ((vrb&3)>=2)
+    return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46;
+  else
+    return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46;
+      }
+      if (vrb==44)  // even: 44->11, odd: 45->34
+  return offset+((23*odd_slot) + 22-12+1);
+      if (vrb==45)  // even: 45->10, odd: 45->33
+  return offset+((23*odd_slot) + 22+12);
+      if (vrb==46)
+  return offset+46+((23*odd_slot) + 23-12+1) % 46;
+      if (vrb==47)
+  return offset+46+((23*odd_slot) + 23+12) % 46;
+      if (vrb==48)
+  return offset+46+((23*odd_slot) + 23-12+1) % 46;
+      if (vrb==49)
+  return offset+46+((23*odd_slot) + 23+12) % 46;
+    }
+    else {
+      // Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27
+      if (vrb>=9)
+  offset=18;
+      else
+  offset=0;
+
+      if (vrb<12) {
+  if ((vrb&3)>=2)
+    return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18;
+  else
+    return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18;
+      }
+      else {
+  return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18);
+      }
+    }
+    break;
+  case 75:
+    // Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0
+    if (Ngap ==0) {
+      return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64);
+    } else {
+      // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
+      return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
+    }
+    break;
+  case 100:
+    // Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0
+    if (Ngap ==0) {
+      return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96);
+    } else {
+      // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
+      return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
+    }
+    break;
+  default:
+    LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL);
+    return 0;
+  }
+  return 0;
+
+}
+
+
+void generate_RIV_tables()
+{
+
+  // 6RBs localized RIV
+  uint8_t Lcrbs,RBstart;
+  uint16_t RIV;
+  uint32_t alloc0,allocdist0_0_even,allocdist0_0_odd,allocdist0_1_even,allocdist0_1_odd;
+  uint32_t alloc1,allocdist1_0_even,allocdist1_0_odd,allocdist1_1_even,allocdist1_1_odd;
+  uint32_t alloc2,allocdist2_0_even,allocdist2_0_odd,allocdist2_1_even,allocdist2_1_odd;
+  uint32_t alloc3,allocdist3_0_even,allocdist3_0_odd,allocdist3_1_even,allocdist3_1_odd;
+  uint32_t nVRB,nVRB_even_dist,nVRB_odd_dist;
+
+  for (RBstart=0; RBstart<6; RBstart++) {
+    alloc0 = 0;
+    allocdist0_0_even = 0;
+    allocdist0_0_odd  = 0;
+    for (Lcrbs=1; Lcrbs<=(6-RBstart); Lcrbs++) {
+      //printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
+      nVRB             = Lcrbs-1+RBstart;
+      alloc0          |= (1<<nVRB);
+      allocdist0_0_even |= (1<<get_prb(6,0,nVRB,0));
+      allocdist0_0_odd  |= (1<<get_prb(6,1,nVRB,0));
+      RIV=computeRIV(6,RBstart,Lcrbs);
+
+      if (RIV>RIV_max6)
+        RIV_max6 = RIV;
+
+      //      printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs);
+      localRIV2alloc_LUT6[RIV] = alloc0;
+      distRIV2alloc_even_LUT6[RIV]  = allocdist0_0_even;
+      distRIV2alloc_odd_LUT6[RIV]  = allocdist0_0_odd;
+      RIV2nb_rb_LUT6[RIV]      = Lcrbs;
+      RIV2first_rb_LUT6[RIV]   = RBstart;
+    }
+  }
+
+
+  for (RBstart=0; RBstart<25; RBstart++) {
+    alloc0 = 0;
+    allocdist0_0_even = 0;
+    allocdist0_0_odd  = 0;
+    for (Lcrbs=1; Lcrbs<=(25-RBstart); Lcrbs++) {
+      nVRB = Lcrbs-1+RBstart;
+      //printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
+      alloc0     |= (1<<nVRB);
+      allocdist0_0_even |= (1<<get_prb(25,0,nVRB,0));
+      allocdist0_0_odd  |= (1<<get_prb(25,1,nVRB,0));
+
+      //printf("alloc 0 %x, allocdist0_even %x, allocdist0_odd %x\n",alloc0,allocdist0_0_even,allocdist0_0_odd);
+      RIV=computeRIV(25,RBstart,Lcrbs);
+
+      if (RIV>RIV_max25)
+        RIV_max25 = RIV;;
+
+
+      localRIV2alloc_LUT25[RIV]      = alloc0;
+      distRIV2alloc_even_LUT25[RIV]  = allocdist0_0_even;
+      distRIV2alloc_odd_LUT25[RIV]   = allocdist0_0_odd;
+      RIV2nb_rb_LUT25[RIV]           = Lcrbs;
+      RIV2first_rb_LUT25[RIV]        = RBstart;
+    }
+  }
+
+
+  for (RBstart=0; RBstart<50; RBstart++) {
+    alloc0 = 0;
+    alloc1 = 0;
+    allocdist0_0_even=0;
+    allocdist1_0_even=0;
+    allocdist0_0_odd=0;
+    allocdist1_0_odd=0;
+    allocdist0_1_even=0;
+    allocdist1_1_even=0;
+    allocdist0_1_odd=0;
+    allocdist1_1_odd=0;
+
+    for (Lcrbs=1; Lcrbs<=(50-RBstart); Lcrbs++) {
+
+      nVRB = Lcrbs-1+RBstart;
+
+
+      if (nVRB<32)
+        alloc0 |= (1<<nVRB);
+      else
+        alloc1 |= (1<<(nVRB-32));
+
+      // Distributed Gap1, even slot
+      nVRB_even_dist = get_prb(50,0,nVRB,0);
+      if (nVRB_even_dist<32)
+        allocdist0_0_even |= (1<<nVRB_even_dist);
+      else
+        allocdist1_0_even |= (1<<(nVRB_even_dist-32));
+
+      // Distributed Gap1, odd slot
+      nVRB_odd_dist = get_prb(50,1,nVRB,0);
+      if (nVRB_odd_dist<32)
+        allocdist0_0_odd |= (1<<nVRB_odd_dist);
+      else
+        allocdist1_0_odd |= (1<<(nVRB_odd_dist-32));
+
+      // Distributed Gap2, even slot
+      nVRB_even_dist = get_prb(50,0,nVRB,1);
+      if (nVRB_even_dist<32)
+        allocdist0_1_even |= (1<<nVRB_even_dist);
+      else
+        allocdist1_1_even |= (1<<(nVRB_even_dist-32));
+
+      // Distributed Gap2, odd slot
+      nVRB_odd_dist = get_prb(50,1,nVRB,1);
+      if (nVRB_odd_dist<32)
+        allocdist0_1_odd |= (1<<nVRB_odd_dist);
+      else
+        allocdist1_1_odd |= (1<<(nVRB_odd_dist-32));
+
+      RIV=computeRIV(50,RBstart,Lcrbs);
+
+      if (RIV>RIV_max50)
+        RIV_max50 = RIV;
+
+      //      printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs);
+      localRIV2alloc_LUT50_0[RIV]      = alloc0;
+      localRIV2alloc_LUT50_1[RIV]      = alloc1;
+      distRIV2alloc_gap0_even_LUT50_0[RIV]  = allocdist0_0_even;
+      distRIV2alloc_gap0_even_LUT50_1[RIV]  = allocdist1_0_even;
+      distRIV2alloc_gap0_odd_LUT50_0[RIV]   = allocdist0_0_odd;
+      distRIV2alloc_gap0_odd_LUT50_1[RIV]   = allocdist1_0_odd;
+      distRIV2alloc_gap1_even_LUT50_0[RIV]  = allocdist0_1_even;
+      distRIV2alloc_gap1_even_LUT50_1[RIV]  = allocdist1_1_even;
+      distRIV2alloc_gap1_odd_LUT50_0[RIV]   = allocdist0_1_odd;
+      distRIV2alloc_gap1_odd_LUT50_1[RIV]   = allocdist1_1_odd;
+      RIV2nb_rb_LUT50[RIV]        = Lcrbs;
+      RIV2first_rb_LUT50[RIV]     = RBstart;
+    }
+  }
+
+
+  for (RBstart=0; RBstart<100; RBstart++) {
+    alloc0 = 0;
+    alloc1 = 0;
+    alloc2 = 0;
+    alloc3 = 0;
+    allocdist0_0_even=0;
+    allocdist1_0_even=0;
+    allocdist2_0_even=0;
+    allocdist3_0_even=0;
+    allocdist0_0_odd=0;
+    allocdist1_0_odd=0;
+    allocdist2_0_odd=0;
+    allocdist3_0_odd=0;
+    allocdist0_1_even=0;
+    allocdist1_1_even=0;
+    allocdist2_1_even=0;
+    allocdist3_1_even=0;
+    allocdist0_1_odd=0;
+    allocdist1_1_odd=0;
+    allocdist2_1_odd=0;
+    allocdist3_1_odd=0;
+
+    for (Lcrbs=1; Lcrbs<=(100-RBstart); Lcrbs++) {
+
+      nVRB = Lcrbs-1+RBstart;
+
+      if (nVRB<32)
+        alloc0 |= (1<<nVRB);
+      else if (nVRB<64)
+        alloc1 |= (1<<(nVRB-32));
+      else if (nVRB<96)
+        alloc2 |= (1<<(nVRB-64));
+      else
+        alloc3 |= (1<<(nVRB-96));
+
+      // Distributed Gap1, even slot
+      nVRB_even_dist = get_prb(100,0,nVRB,0);
+
+//      if ((RBstart==0) && (Lcrbs<=8))
+//  printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist);
+
+
+      if (nVRB_even_dist<32)
+        allocdist0_0_even |= (1<<nVRB_even_dist);
+      else if (nVRB_even_dist<64)
+        allocdist1_0_even |= (1<<(nVRB_even_dist-32));
+      else if (nVRB_even_dist<96)
+  allocdist2_0_even |= (1<<(nVRB_even_dist-64));
+      else
+  allocdist3_0_even |= (1<<(nVRB_even_dist-96));
+/*      if ((RBstart==0) && (Lcrbs<=8))
+  printf("rballoc =>(%08x.%08x.%08x.%08x)\n",
+         allocdist0_0_even,
+         allocdist1_0_even,
+         allocdist2_0_even,
+         allocdist3_0_even
+         );
+*/
+      // Distributed Gap1, odd slot
+      nVRB_odd_dist = get_prb(100,1,nVRB,0);
+      if (nVRB_odd_dist<32)
+        allocdist0_0_odd |= (1<<nVRB_odd_dist);
+      else if (nVRB_odd_dist<64)
+        allocdist1_0_odd |= (1<<(nVRB_odd_dist-32));
+      else if (nVRB_odd_dist<96)
+  allocdist2_0_odd |= (1<<(nVRB_odd_dist-64));
+      else
+  allocdist3_0_odd |= (1<<(nVRB_odd_dist-96));
+
+
+      // Distributed Gap2, even slot
+      nVRB_even_dist = get_prb(100,0,nVRB,1);
+      if (nVRB_even_dist<32)
+        allocdist0_1_even |= (1<<nVRB_even_dist);
+      else if (nVRB_even_dist<64)
+        allocdist1_1_even |= (1<<(nVRB_even_dist-32));
+      else if (nVRB_even_dist<96)
+  allocdist2_1_even |= (1<<(nVRB_even_dist-64));
+      else
+  allocdist3_1_even |= (1<<(nVRB_even_dist-96));
+
+
+      // Distributed Gap2, odd slot
+      nVRB_odd_dist = get_prb(100,1,nVRB,1);
+      if (nVRB_odd_dist<32)
+        allocdist0_1_odd |= (1<<nVRB_odd_dist);
+      else if (nVRB_odd_dist<64)
+        allocdist1_1_odd |= (1<<(nVRB_odd_dist-32));
+      else if (nVRB_odd_dist<96)
+  allocdist2_1_odd |= (1<<(nVRB_odd_dist-64));
+      else
+  allocdist3_1_odd |= (1<<(nVRB_odd_dist-96));
+
+
+      RIV=computeRIV(100,RBstart,Lcrbs);
+
+      if (RIV>RIV_max100)
+        RIV_max100 = RIV;
+
+      //      printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs);
+      localRIV2alloc_LUT100_0[RIV] = alloc0;
+      localRIV2alloc_LUT100_1[RIV] = alloc1;
+      localRIV2alloc_LUT100_2[RIV] = alloc2;
+      localRIV2alloc_LUT100_3[RIV] = alloc3;
+      distRIV2alloc_gap0_even_LUT100_0[RIV]  = allocdist0_0_even;
+      distRIV2alloc_gap0_even_LUT100_1[RIV]  = allocdist1_0_even;
+      distRIV2alloc_gap0_even_LUT100_2[RIV]  = allocdist2_0_even;
+      distRIV2alloc_gap0_even_LUT100_3[RIV]  = allocdist3_0_even;
+      distRIV2alloc_gap0_odd_LUT100_0[RIV]   = allocdist0_0_odd;
+      distRIV2alloc_gap0_odd_LUT100_1[RIV]   = allocdist1_0_odd;
+      distRIV2alloc_gap0_odd_LUT100_2[RIV]   = allocdist2_0_odd;
+      distRIV2alloc_gap0_odd_LUT100_3[RIV]   = allocdist3_0_odd;
+      distRIV2alloc_gap1_even_LUT100_0[RIV]  = allocdist0_1_even;
+      distRIV2alloc_gap1_even_LUT100_1[RIV]  = allocdist1_1_even;
+      distRIV2alloc_gap1_even_LUT100_2[RIV]  = allocdist2_1_even;
+      distRIV2alloc_gap1_even_LUT100_3[RIV]  = allocdist3_1_even;
+      distRIV2alloc_gap1_odd_LUT100_0[RIV]   = allocdist0_1_odd;
+      distRIV2alloc_gap1_odd_LUT100_1[RIV]   = allocdist1_1_odd;
+      distRIV2alloc_gap1_odd_LUT100_2[RIV]   = allocdist2_1_odd;
+      distRIV2alloc_gap1_odd_LUT100_3[RIV]   = allocdist3_1_odd;
+
+      RIV2nb_rb_LUT100[RIV]      = Lcrbs;
+      RIV2first_rb_LUT100[RIV]   = RBstart;
+    }
+  }
+}
+
+// Ngap = 3, N_VRB_DL=6, P=1, N_row=2, N_null=4*2-6=2
+// permutation for even slots :
+//    n_PRB'(0,2,4) = (0,1,2), n_PRB'(1,3,5) = (4,5,6)
+//    n_PRB''(0,1,2,3) = (0,2,4,6)
+//    => n_tilde_PRB(5) = (4)
+//       n_tilde_PRB(4) = (1)
+//       n_tilde_PRB(2,3) = (3,5)
+//       n_tilde_PRB(0,1) = (0,2)
+
+
+
+uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci)
+{
+
+  return(localRIV2alloc_LUT25[rb_alloc_dci]);
+
+}
+
+uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti)
+{
+  unsigned char UE_id;
+
+  // find the UE_index corresponding to rnti
+  UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
+  DevAssert( UE_id != (unsigned char)-1 );
+
+  return(PHY_vars_eNB_g[Mod_id][CC_id]->transmission_mode[UE_id]);
+}
+
+int generate_eNB_dlsch_params_from_dci(int frame,
+                                       uint8_t subframe,
+                                       void *dci_pdu,
+                                       uint16_t rnti,
+                                       DCI_format_t dci_format,
+                                       LTE_eNB_DLSCH_t **dlsch,
+                                       NR_DL_FRAME_PARMS *frame_parms,
+                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+                                       uint16_t si_rnti,
+                                       uint16_t ra_rnti,
+                                       uint16_t p_rnti,
+                                       uint16_t DL_pmi_single,
+                                       uint8_t beamforming_mode)
+{
+
+  uint8_t harq_pid = UINT8_MAX;
+  uint32_t rballoc = UINT32_MAX;
+  uint32_t RIV_max = 0;
+  uint8_t NPRB,tbswap,tpmi=0;
+  LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
+  uint8_t frame_type=frame_parms->frame_type;
+  uint8_t vrb_type=0;
+  uint8_t mcs=0,mcs1=0,mcs2=0;
+  uint8_t I_mcs = 0;
+  uint8_t rv=0,rv1=0,rv2=0;
+  uint8_t rah=0;
+  uint8_t TPC=0;
+  uint8_t TB0_active=0,TB1_active=0;
+  LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
+
+  //   printf("Generate eNB DCI, format %d, rnti %x (pdu %p)\n",dci_format,rnti,dci_pdu);
+
+  switch (dci_format) {
+
+  case format0:
+    return(-1);
+    break;
+
+  case format1A:  // This is DLSCH allocation for control traffic
+
+
+
+    dlsch[0]->subframe_tx[subframe] = 1;
+
+
+    switch (frame_parms->N_RB_DL) {
+    case 6:
+      if (frame_type == TDD) {
+        vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
+        mcs      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc  = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv;
+        TPC      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
+
+        //        printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
+      } else {
+        vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type;
+        mcs      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc  = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv;
+        TPC      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC;
+        harq_pid = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
+
+        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
+      }
+
+      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+      dlsch0_harq->codeword=0;
+
+      if (vrb_type==LOCALIZED) {
+  dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT6[rballoc];
+      }
+      else {
+  LOG_E(PHY,"Distributed RB allocation not done yet\n");
+  mac_xface->macphy_exit("exiting");
+      }
+      dlsch0_harq->vrb_type       = vrb_type;
+      dlsch0_harq->nb_rb          = RIV2nb_rb_LUT6[rballoc];//NPRB;
+      RIV_max = RIV_max6;
+
+
+      break;
+
+    case 25:
+      if (frame_type == TDD) {
+        vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
+        mcs      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc  = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv;
+        TPC      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
+
+        //      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
+      } else {
+        vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type;
+        mcs      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc  = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv;
+        TPC      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC;
+        harq_pid = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid;
+
+        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
+      }
+
+      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+
+
+      if (vrb_type==LOCALIZED) {
+  dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT25[rballoc];
+      }
+      else {
+  LOG_E(PHY,"Distributed RB allocation not done yet\n");
+  mac_xface->macphy_exit("exiting");
+      }
+      dlsch0_harq->vrb_type       = vrb_type;
+      dlsch0_harq->nb_rb          = RIV2nb_rb_LUT25[rballoc];//NPRB;
+      RIV_max                     = RIV_max25;
+      break;
+
+    case 50:
+      if (frame_type == TDD) {
+        vrb_type = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
+        mcs      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc  = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv;
+        TPC      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
+
+        //      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
+      } else {
+        vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type;
+        mcs      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc  = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv;
+        TPC      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC;
+        harq_pid = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid;
+        //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
+      }
+
+      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+      if (vrb_type==LOCALIZED) {
+  dlsch0_harq->rb_alloc[0]     = localRIV2alloc_LUT50_0[rballoc];
+  dlsch0_harq->rb_alloc[1]     = localRIV2alloc_LUT50_1[rballoc];
+      }
+      else {
+  LOG_E(PHY,"Distributed RB allocation not done yet\n");
+  mac_xface->macphy_exit("exiting");
+      }
+
+
+      dlsch0_harq->vrb_type        = vrb_type;
+      dlsch0_harq->nb_rb                               = RIV2nb_rb_LUT50[rballoc];//NPRB;
+      RIV_max = RIV_max50;
+      break;
+
+    case 100:
+      if (frame_type == TDD) {
+        vrb_type = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
+        mcs      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc  = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv;
+        TPC      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
+        //      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
+      } else {
+        vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type;
+        mcs      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc  = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv;
+        TPC      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC;
+        harq_pid = ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid;
+        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
+      }
+
+      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+
+      dlsch0_harq->vrb_type         = vrb_type;
+      if (vrb_type==LOCALIZED) {
+  dlsch0_harq->rb_alloc[0]      = localRIV2alloc_LUT100_0[rballoc];
+  dlsch0_harq->rb_alloc[1]      = localRIV2alloc_LUT100_1[rballoc];
+  dlsch0_harq->rb_alloc[2]      = localRIV2alloc_LUT100_2[rballoc];
+  dlsch0_harq->rb_alloc[3]      = localRIV2alloc_LUT100_3[rballoc];
+      }
+      else {
+  LOG_E(PHY,"Distributed RB allocation not done yet\n");
+  mac_xface->macphy_exit("exiting");
+      }
+
+
+
+      dlsch0_harq->nb_rb                               = RIV2nb_rb_LUT100[rballoc];//NPRB;
+      RIV_max = RIV_max100;
+      break;
+
+    default:
+      LOG_E(PHY,"Invalid N_RB_D %dL\n", frame_parms->N_RB_DL);
+      DevParam (frame_parms->N_RB_DL, 0, 0);
+      break;
+    }
+
+    // harq_pid field is reserved
+    if ((rnti==si_rnti) || (rnti==ra_rnti) || (rnti==p_rnti)) { //
+      harq_pid=0;
+      // see 36-212 V8.6.0 p. 45
+      NPRB      = (TPC&1)+2;
+      // 36-213 sec.7.1.7.2 p.26
+      I_mcs     = mcs;
+    } else {
+      if (harq_pid>=8) {
+        LOG_E(PHY,"ERROR: Format 1A: harq_pid=%d >= 8\n", harq_pid);
+        return(-1);
+      }
+
+      if (rballoc>RIV_max) {
+        LOG_E(PHY,"ERROR: Format 1A: rb_alloc (%x) > RIV_max (%x)\n",rballoc,RIV_max);
+        return(-1);
+      }
+
+      NPRB      = dlsch0_harq->nb_rb;
+      I_mcs     = get_I_TBS(mcs);
+    }
+
+    if (NPRB==0)
+      return(-1);
+
+    //printf("NPRB %d, nb_rb %d, ndi %d\n",NPRB,dlsch0_harq->nb_rb,ndi);
+    dlsch0_harq->rvidx     = rv;
+
+    dlsch0_harq->Nl          = 1;
+    //dlsch0_harq->layer_index = 0;
+
+    dlsch0_harq->mimo_mode   = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
+    /*
+    if ((rnti!=si_rnti)&&(rnti!=ra_rnti)&&(rnti!=p_rnti)) {  //handle toggling for C-RNTI
+    if (dlsch0_harq->first_tx == 1) {
+    LOG_D(PHY,"First TX for TC-RNTI %x, clearing first_tx flag\n",rnti);
+    dlsch0_harq->first_tx=0;
+    dlsch0_harq->Ndi = 1;
+    }
+    else {
+    if (ndi == dlsch0_harq->DCINdi)
+    dlsch0_harq->Ndi         = 0;
+    else
+    dlsch0_harq->Ndi         = 1;
+    }
+
+    dlsch0_harq->DCINdi=ndi;
+    }
+    else {
+    dlsch0_harq->Ndi         = 1;
+    }
+    */
+    dlsch0_harq->dl_power_off = 1;
+
+
+
+    dlsch0_harq->mcs           = mcs;
+    dlsch0_harq->TBS           = TBStable[I_mcs][NPRB-1];
+
+    dlsch[0]->current_harq_pid   = harq_pid;
+    dlsch[0]->harq_ids[subframe] = harq_pid;
+
+    dlsch[0]->active = 1;
+    dlsch0 = dlsch[0];
+
+    dlsch[0]->rnti = rnti;
+
+    dlsch[0]->harq_ids[subframe] = harq_pid;
+
+    if (dlsch0_harq->round == 0)
+      dlsch0_harq->status = ACTIVE;
+
+    break;
+
+  case format1:
+
+    switch (frame_parms->N_RB_DL) {
+
+    case 6:
+      if (frame_type == TDD) {
+        mcs       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs;
+        rballoc   = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah;
+        rv        = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv;
+        harq_pid  = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs;
+        rah      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah;
+        rballoc  = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv;
+        harq_pid = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 25:
+
+      if (frame_type == TDD) {
+        mcs       = ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs;
+        rballoc   = ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI1_5MHz_TDD_t *)dci_pdu)->rah;
+        rv        = ((DCI1_5MHz_TDD_t *)dci_pdu)->rv;
+        harq_pid  = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid;
+        LOG_D(PHY,"eNB: subframe %d UE %x, Format1 DCI: ndi %d, harq_pid %d\n",subframe,rnti,((DCI1_5MHz_TDD_t *)dci_pdu)->ndi,harq_pid);
+      } else {
+        mcs      = ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs;
+        rah      = ((DCI1_5MHz_FDD_t *)dci_pdu)->rah;
+        rballoc  = ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1_5MHz_FDD_t *)dci_pdu)->rv;
+        harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid;
+        LOG_D(PHY,"eNB: subframe %d UE %x, Format1 DCI: ndi %d, harq_pid %d\n",subframe,rnti,((DCI1_5MHz_FDD_t *)dci_pdu)->ndi,harq_pid);
+
+      }
+
+      break;
+
+    case 50:
+      if (frame_type == TDD) {
+        mcs       = ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs;
+        rballoc   = ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI1_10MHz_TDD_t *)dci_pdu)->rah;
+        rv        = ((DCI1_10MHz_TDD_t *)dci_pdu)->rv;
+        harq_pid  = ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs      = ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs;
+        rah      = ((DCI1_10MHz_FDD_t *)dci_pdu)->rah;
+        rballoc  = ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1_10MHz_FDD_t *)dci_pdu)->rv;
+        harq_pid = ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 100:
+      if (frame_type == TDD) {
+        mcs       = ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs;
+        rballoc   = ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI1_20MHz_TDD_t *)dci_pdu)->rah;
+        rv        = ((DCI1_20MHz_TDD_t *)dci_pdu)->rv;
+        harq_pid  = ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs      = ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs;
+        rah      = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah;
+        rballoc  = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc;
+        rv       = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv;
+        harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    }
+
+    if (harq_pid>=8) {
+      LOG_E(PHY,"ERROR: Format 1: harq_pid=%d >= 8\n", harq_pid);
+      return(-1);
+    }
+
+    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+    dlsch0_harq->codeword=0;
+
+    // printf("DCI: Setting subframe_tx for subframe %d\n",subframe);
+    dlsch[0]->subframe_tx[subframe] = 1;
+
+    conv_rballoc(rah,
+                 rballoc,frame_parms->N_RB_DL,
+                 dlsch0_harq->rb_alloc);
+
+    dlsch0_harq->nb_rb = conv_nprb(rah,
+                                   rballoc,
+                                   frame_parms->N_RB_DL);
+
+    NPRB      = dlsch0_harq->nb_rb;
+
+
+    if (NPRB==0)
+      return(-1);
+
+
+    dlsch0_harq->rvidx       = rv;
+
+    dlsch0_harq->Nl          = 1;
+    //    dlsch[0]->layer_index = 0;
+    if (beamforming_mode == 0)
+      dlsch0_harq->mimo_mode = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
+    else if (beamforming_mode == 7)
+      dlsch0_harq->mimo_mode = TM7;
+    else
+      LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode);
+
+    dlsch0_harq->dl_power_off = 1;
+    /*
+      if (dlsch[0]->harq_processes[harq_pid]->first_tx == 1) {
+      LOG_D(PHY,"First TX for C-RNTI %x, clearing first_tx flag, shouldn't happen!\n",rnti);
+      dlsch[0]->harq_processes[harq_pid]->first_tx=0;
+      dlsch[0]->harq_processes[harq_pid]->Ndi = 1;
+      }
+      else {
+      LOG_D(PHY,"Checking for Toggled Ndi for C-RNTI %x, old value %d, DCINdi %d\n",rnti,dlsch[0]->harq_processes[harq_pid]->DCINdi,ndi);
+      if (ndi == dlsch[0]->harq_processes[harq_pid]->DCINdi)
+      dlsch[0]->harq_processes[harq_pid]->Ndi         = 0;
+      else
+      dlsch[0]->harq_processes[harq_pid]->Ndi         = 1;
+      }
+      dlsch[0]->harq_processes[harq_pid]->DCINdi=ndi;
+    */
+
+    dlsch[0]->active = 1;
+
+
+
+    if (dlsch0_harq->round == 0) {
+      dlsch0_harq->status = ACTIVE;
+      // MCS and TBS don't change across HARQ rounds
+      dlsch0_harq->mcs         = mcs;
+      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1];
+
+    }
+
+    dlsch[0]->current_harq_pid = harq_pid;
+    dlsch[0]->harq_ids[subframe] = harq_pid;
+
+
+
+    dlsch0 = dlsch[0];
+
+    dlsch[0]->rnti = rnti;
+
+
+    break;
+
+  case format2: // DL Scheduling assignment for MIMO including closed loop spatial multiplexing
+
+    switch (frame_parms->N_RB_DL) {
+
+    case 6:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else {
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 25:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else {
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 50:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else {
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 100:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else {
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+    }
+
+    if (harq_pid>=8) {
+      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
+      return(-1);
+    }
+
+
+    // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0
+    // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated
+    TB0_active = 1;
+    TB1_active = 1;
+
+    if ((rv1 == 1) && (mcs1 == 0)) {
+      TB0_active=0;
+    }
+    if ((rv2 == 1) && (mcs2 == 0)) {
+      TB1_active=0;
+    }
+#ifdef DEBUG_HARQ
+    printf(" eNOdeB RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rv1, rv2, mcs1, mcs2);
+#endif
+    if (TB0_active && TB1_active && tbswap==0) {
+      dlsch0=dlsch[0];
+      dlsch1=dlsch[1];
+      dlsch0->active = 1;
+      dlsch1->active = 1;
+      dlsch0_harq = dlsch0->harq_processes[harq_pid];
+      dlsch1_harq = dlsch1->harq_processes[harq_pid];
+      dlsch0_harq->mcs = mcs1;
+      dlsch1_harq->mcs = mcs2;
+      dlsch0_harq->rvidx = rv1;
+      dlsch1_harq->rvidx = rv2;
+      dlsch0_harq->status = ACTIVE;
+      dlsch1_harq->status = ACTIVE;
+      dlsch0_harq->codeword=0;
+      dlsch1_harq->codeword=1;
+#ifdef DEBUG_HARQ
+      printf("\n ENB: BOTH ACTIVE\n");
+#endif
+    }
+    else if (TB0_active && TB1_active && tbswap==1) {
+      dlsch0=dlsch[0];
+      dlsch1=dlsch[1];
+      dlsch0->active = 1;
+      dlsch1->active = 1;
+      dlsch0_harq = dlsch0->harq_processes[harq_pid];
+      dlsch1_harq = dlsch1->harq_processes[harq_pid];
+      dlsch0_harq->mcs = mcs1;
+      dlsch1_harq->mcs = mcs2;
+      dlsch0_harq->rvidx = rv1;
+      dlsch1_harq->rvidx = rv2;
+      dlsch0_harq->status = ACTIVE;
+      dlsch1_harq->status = ACTIVE;
+      dlsch0_harq->codeword=1;
+      dlsch1_harq->codeword=0;
+    }
+    else if (TB0_active && (TB1_active==0)) {
+      dlsch0=dlsch[0];
+      dlsch0->active = 1;
+      dlsch0_harq = dlsch0->harq_processes[harq_pid];
+      dlsch0_harq->mcs = mcs1;
+      dlsch0_harq->rvidx = rv1;
+      dlsch0_harq->status = ACTIVE;
+      dlsch0_harq->codeword = 0;
+      dlsch1=NULL;
+      dlsch1_harq = NULL;
+#ifdef DEBUG_HARQ
+      printf("\n ENB: TB1 is deactivated, retransmit TB0 transmit in TM6\n");
+#endif
+    }
+    else if ((TB0_active==0) && TB1_active) {
+      dlsch1=dlsch[1];
+      dlsch1->active = 1;
+      dlsch1_harq = dlsch1->harq_processes[harq_pid];
+      dlsch1_harq->mcs = mcs2;
+      dlsch1_harq->rvidx = rv2;
+      dlsch1_harq->status = ACTIVE;
+      dlsch1_harq->codeword = 0;
+      dlsch0=NULL;
+      dlsch0_harq = NULL;
+#ifdef DEBUG_HARQ
+      printf("\n ENB: TB0 is deactivated, retransmit TB1 transmit in TM6\n");
+#endif
+    }
+  // printf("[eNB] dlsch0_harq->round = %d, dlsch1_harq->round = %d \n", dlsch0_harq->round, dlsch1_harq->round);
+
+
+    if (dlsch0 != NULL){
+      dlsch0->subframe_tx[subframe] = 1;
+
+      dlsch0->current_harq_pid = harq_pid;
+      dlsch0->harq_ids[subframe] = harq_pid;
+    }
+
+    if (dlsch1_harq != NULL){
+      dlsch1->current_harq_pid = harq_pid;
+      dlsch1->harq_ids[subframe] = harq_pid;
+    }
+
+
+    if (dlsch0 != NULL ){
+      conv_rballoc(rah,
+                   rballoc,
+                   frame_parms->N_RB_DL,
+                   dlsch0_harq->rb_alloc);
+
+      dlsch0_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL);
+
+      if (dlsch1 != NULL){
+        dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0];
+        dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
+      }
+    } else if ((dlsch0 == NULL ) && (dlsch1 != NULL )){
+        conv_rballoc(rah,
+                     rballoc,
+                     frame_parms->N_RB_DL,
+                     dlsch1_harq->rb_alloc);
+
+        dlsch1_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL);
+    }
+
+
+    /*if (dlsch0_harq->nb_rb == 0)
+      return(-1);*/
+
+
+    // assume both TBs are active
+    if (dlsch0_harq != NULL)
+      dlsch0_harq->Nl        = 1;
+    if (dlsch1_harq != NULL)
+      dlsch1_harq->Nl        = 1;
+
+
+    // check if either TB is disabled (see 36-213 V11.3 Section )
+
+    if (frame_parms->nb_antenna_ports_eNB == 2) {
+      if ((dlsch0 != NULL) && (dlsch1 != NULL)) {  //two CW active
+
+        dlsch0_harq->dl_power_off = 1;
+        dlsch1_harq->dl_power_off = 1;
+        dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+        dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
+        switch (tpmi) {
+        case 0:
+          dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
+          dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,0,1);
+          dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,0,1);
+          break;
+        case 1:
+          dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
+          dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1,1);
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1,1);
+
+          break;
+        case 2: // PUSCH precoding
+          dlsch0_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
+          dlsch0_harq->pmi_alloc   = DL_pmi_single;
+          dlsch1_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
+          dlsch1_harq->pmi_alloc   = DL_pmi_single;
+          break;
+        default:
+          break;
+        }
+      } else if ((dlsch0 != NULL) && (dlsch1 == NULL))  { // only CW 0 active
+        dlsch0_harq->dl_power_off = 1;
+        dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+        switch (tpmi) {
+        case 0 :
+          dlsch0_harq->mimo_mode   = ALAMOUTI;
+          break;
+        case 1:
+          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING11;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,0,0);
+          break;
+        case 2:
+          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1,0);
+          break;
+        case 3:
+          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,2,0);
+          break;
+        case 4:
+          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,3,0);
+          break;
+        case 5:
+          dlsch0_harq->mimo_mode   = PUSCH_PRECODING0;
+          dlsch0_harq->pmi_alloc   = DL_pmi_single;
+          break;
+        case 6:
+          dlsch0_harq->mimo_mode   = PUSCH_PRECODING1;
+          dlsch0_harq->pmi_alloc   = DL_pmi_single;
+          break;
+        }
+      } else if ((dlsch0 == NULL) && (dlsch1 != NULL))  {
+          dlsch1_harq->dl_power_off = 1;
+          dlsch1_harq->TBS= TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
+          switch (tpmi) {
+          case 0 :
+            dlsch1_harq->mimo_mode   = ALAMOUTI;
+            break;
+          case 1:
+            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING11;
+            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,0,0);
+            break;
+          case 2:
+            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1m1;
+            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,1,0);
+            break;
+          case 3:
+            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1j;
+            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,2,0);
+            break;
+          case 4:
+            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1mj;
+            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,3,0);
+            break;
+          case 5:
+            dlsch1_harq->mimo_mode   = PUSCH_PRECODING0;
+            dlsch1_harq->pmi_alloc   = DL_pmi_single;
+            break;
+          case 6:
+            dlsch1_harq->mimo_mode   = PUSCH_PRECODING1;
+            dlsch1_harq->pmi_alloc   = DL_pmi_single;
+            break;
+          }
+         // printf ("[eNB] dlsch1_harq->pmi_alloc %d\n", dlsch1_harq->pmi_alloc);
+        }
+
+    } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+      // fill in later
+    }
+
+    // reset HARQ process if this is the first transmission
+   /* if (dlsch0_harq->round == 0)
+      dlsch0_harq->status = ACTIVE;
+
+    if (dlsch1_harq->round == 0)
+      dlsch1_harq->status = ACTIVE;*/
+    if (dlsch0_harq != NULL)
+      dlsch0->rnti = rnti;
+    if (dlsch1 != NULL)
+      dlsch1->rnti = rnti;
+
+
+    break;
+
+  case format2A:
+
+    switch (frame_parms->N_RB_DL) {
+
+    case 6:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+        } else {
+          mcs1      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else {
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 25:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+        } else {
+          mcs1      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else {
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 50:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+        } else {
+          mcs1      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else {
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 100:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+        } else {
+          mcs1      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tpmi;
+        } else {
+          mcs1      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv2;
+          harq_pid  = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi    = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
+        }
+      } else {
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+    }
+
+
+    if (harq_pid>=8) {
+      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
+      return(-1);
+    }
+
+
+    // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0
+    // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated
+    // This must be set as in TM4, does not work properly now.
+    if (tbswap == 0) {
+      dlsch0 = dlsch[0];
+      dlsch1 = dlsch[1];
+    } else {
+      dlsch0 = dlsch[1];
+      dlsch1 = dlsch[0];
+    }
+
+    dlsch0_harq = dlsch0->harq_processes[harq_pid];
+    dlsch1_harq = dlsch1->harq_processes[harq_pid];
+
+    dlsch0->subframe_tx[subframe] = 1;
+
+    dlsch0->current_harq_pid = harq_pid;
+    dlsch1->current_harq_pid = harq_pid;
+    dlsch0->harq_ids[subframe] = harq_pid;
+    dlsch1->harq_ids[subframe] = harq_pid;
+    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
+
+
+    conv_rballoc(rah,
+                 rballoc,
+                 frame_parms->N_RB_DL,
+                 dlsch0_harq->rb_alloc);
+
+    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];
+    dlsch0_harq->nb_rb                               = conv_nprb(rah,
+        rballoc,
+        frame_parms->N_RB_DL);
+    dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;
+
+    if (dlsch0_harq->nb_rb == 0)
+      return(-1);
+
+    dlsch0_harq->mcs       = mcs1;
+    dlsch1_harq->mcs       = mcs2;
+    dlsch0_harq->rvidx     = rv1;
+    dlsch1_harq->rvidx     = rv2;
+
+    // assume both TBs are active
+    dlsch0_harq->Nl        = 1;
+    dlsch1_harq->Nl        = 1;
+    dlsch0->active = 1;
+    dlsch1->active = 1;
+
+
+    // check if either TB is disabled (see 36-213 V11.3 Section )
+    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
+      dlsch0->active = 0;
+    }
+
+    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
+      dlsch1->active = 0;
+    }
+
+   // dlsch0_harq->dl_power_off = 0;
+   // dlsch1_harq->dl_power_off = 0;
+
+
+    if (frame_parms->nb_antenna_ports_eNB == 2) {
+      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+      dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
+
+      if ((dlsch0->active==1) && (dlsch1->active==1)) {
+
+        dlsch0_harq->mimo_mode = LARGE_CDD;
+        dlsch1_harq->mimo_mode = LARGE_CDD;
+        dlsch0_harq->dl_power_off = 1;
+        dlsch1_harq->dl_power_off = 1;
+      } else {
+        dlsch0_harq->mimo_mode   = ALAMOUTI;
+        dlsch1_harq->mimo_mode   = ALAMOUTI;
+      }
+    } else if (frame_parms->nb_antenna_ports_eNB == 4) { // 4 antenna case
+      if ((dlsch0->active==1) && (dlsch1->active==1)) {
+        switch (tpmi) {
+        case 0: // one layer per transport block
+          dlsch0_harq->mimo_mode   = LARGE_CDD;
+          dlsch1_harq->mimo_mode   = LARGE_CDD;
+          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+          dlsch0_harq->dl_power_off = 1;
+          dlsch1_harq->dl_power_off = 1;
+          break;
+
+        case 1: // one-layers on TB 0, two on TB 1
+          dlsch0_harq->mimo_mode   = LARGE_CDD;
+          dlsch1_harq->mimo_mode   = LARGE_CDD;
+          dlsch1_harq->Nl          = 2;
+          dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1];
+          dlsch0_harq->dl_power_off = 1;
+          dlsch1_harq->dl_power_off = 1;
+          break;
+
+        case 2: // two-layers on TB 0, two on TB 1
+          dlsch0_harq->mimo_mode   = LARGE_CDD;
+          dlsch1_harq->mimo_mode   = LARGE_CDD;
+          dlsch0_harq->Nl          = 2;
+          dlsch0_harq->dl_power_off = 1;
+          dlsch1_harq->dl_power_off = 1;
+
+          if (frame_parms->N_RB_DL <= 56) {
+            dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
+            dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1];
+          } else {
+            LOG_E(PHY,"Add implementation of Table 7.1.7.2.2-1 for two-layer TBS conversion with N_RB_DL > 56\n");
+          }
+
+          break;
+
+        case 3: //
+          LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n");
+          break;
+        }
+      } else if (dlsch0->active == 1) {
+        switch (tpmi) {
+        case 0: // one layer per transport block
+          dlsch0_harq->mimo_mode   = ALAMOUTI;
+          dlsch1_harq->mimo_mode   = ALAMOUTI;
+          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+          break;
+
+        case 1: // two-layers on TB 0
+          dlsch0_harq->mimo_mode   = LARGE_CDD;
+          dlsch0_harq->Nl          = 2;
+          dlsch0_harq->dl_power_off = 1;
+          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
+          break;
+
+        case 2: // two-layers on TB 0, two on TB 1
+        case 3: //
+          LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi);
+          break;
+        }
+      } else if (dlsch1->active == 1) {
+        switch (tpmi) {
+        case 0: // one layer per transport block
+          dlsch0_harq->mimo_mode   = ALAMOUTI;
+          dlsch1_harq->mimo_mode   = ALAMOUTI;
+          dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
+          break;
+
+        case 1: // two-layers on TB 0
+          dlsch1_harq->mimo_mode   = LARGE_CDD;
+          dlsch1_harq->Nl          = 2;
+          dlsch1_harq->dl_power_off = 1;
+          dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1];
+          break;
+
+        case 2: // two-layers on TB 0, two on TB 1
+        case 3: //
+          LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi);
+          break;
+        }
+      }
+    } else {
+      LOG_E(PHY,"Illegal number of antennas for eNB %d\n",frame_parms->nb_antenna_ports_eNB);
+    }
+
+    // reset HARQ process if this is the first transmission
+    if ((dlsch0->active==1) && (dlsch0_harq->round == 0))
+      dlsch0_harq->status = ACTIVE;
+
+    if ((dlsch1->active==1) && (dlsch1_harq->round == 0))
+      dlsch1_harq->status = ACTIVE;
+
+    dlsch0->rnti = rnti;
+    dlsch1->rnti = rnti;
+
+
+    //    printf("eNB: Format 2A TBS0 %d, TBS1 %d\n",dlsch0_harq->TBS,dlsch1_harq->TBS);
+
+    break;
+
+  case format2B:
+
+    switch (frame_parms->N_RB_DL) {
+
+    case 6:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->rballoc;
+        rv1       = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->rballoc;
+        rv1       = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 25:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2B_5MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2B_5MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2B_5MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2B_5MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2B_5MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2B_5MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 50:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2B_10MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2B_10MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2B_10MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2B_10MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2B_10MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2B_10MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 100:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2B_20MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2B_20MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2B_20MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2B_20MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2B_20MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2B_20MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+    }
+
+
+    if (harq_pid>=8) {
+      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
+      return(-1);
+    }
+
+
+
+    dlsch0 = dlsch[0];
+    dlsch1 = dlsch[1];
+
+
+    dlsch0->subframe_tx[subframe] = 1;
+
+    dlsch0->current_harq_pid = harq_pid;
+    dlsch1->current_harq_pid = harq_pid;
+    dlsch0->harq_ids[subframe] = harq_pid;
+    dlsch1->harq_ids[subframe] = harq_pid;
+    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
+
+
+    dlsch0_harq = dlsch0->harq_processes[harq_pid];
+    dlsch1_harq = dlsch1->harq_processes[harq_pid];
+
+    // Needs to be checked
+    dlsch0_harq->codeword=0;
+    dlsch1_harq->codeword=1;
+
+    conv_rballoc(rah,
+                 rballoc,
+                 frame_parms->N_RB_DL,
+                 dlsch0_harq->rb_alloc);
+
+    dlsch1_harq->rb_alloc[0]     = dlsch0_harq->rb_alloc[0];
+
+    dlsch0_harq->nb_rb           = conv_nprb(rah,
+              rballoc,
+              frame_parms->N_RB_DL);
+    dlsch1_harq->nb_rb           = dlsch0_harq->nb_rb;
+
+    dlsch0_harq->mcs       = mcs1;
+    dlsch1_harq->mcs       = mcs2;
+    dlsch0_harq->rvidx     = rv1;
+    dlsch1_harq->rvidx     = rv2;
+
+    // check if either TB is disabled (see 36-213 V8.6 p. 26)
+
+
+    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0))
+      dlsch0_harq->status = DISABLED;
+
+    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0))
+      dlsch1_harq->status = DISABLED;
+
+    dlsch0_harq->Nl        = 1;
+
+
+    if (dlsch0_harq->round == 0) {
+      dlsch0_harq->status = ACTIVE;
+      //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
+    }
+
+    dlsch0_harq->mcs         = mcs1;
+
+    if (dlsch0_harq->nb_rb > 0) {
+      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+    } else {
+      dlsch0_harq->TBS = 0;
+    }
+
+    dlsch0->active = 1;
+
+    dlsch0->rnti = rnti;
+    dlsch1->rnti = rnti;
+
+    dlsch0_harq->dl_power_off = 1;
+    dlsch1_harq->dl_power_off = 1;
+
+    break;
+
+  case format2C:
+
+    switch (frame_parms->N_RB_DL) {
+
+    case 6:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->rballoc;
+        rv1       = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->rballoc;
+        rv1       = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 25:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2C_5MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2C_5MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2C_5MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2C_5MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2C_5MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2C_5MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 50:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2C_10MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2C_10MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2C_10MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2C_10MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2C_10MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2C_10MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 100:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2C_20MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2C_20MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2C_20MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2C_20MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2C_20MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2C_20MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+    }
+
+
+    if (harq_pid>=8) {
+      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
+      return(-1);
+    }
+
+
+
+    dlsch0 = dlsch[0];
+    dlsch1 = dlsch[1];
+
+    dlsch0->subframe_tx[subframe] = 1;
+
+    dlsch0->current_harq_pid = harq_pid;
+    dlsch1->current_harq_pid = harq_pid;
+    dlsch0->harq_ids[subframe] = harq_pid;
+    dlsch1->harq_ids[subframe] = harq_pid;
+    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
+
+    dlsch0_harq = dlsch0->harq_processes[harq_pid];
+    dlsch1_harq = dlsch1->harq_processes[harq_pid];
+
+    // Needs to be checked
+    dlsch0_harq->codeword=0;
+    dlsch1_harq->codeword=1;
+
+    conv_rballoc(rah,
+                 rballoc,
+                 frame_parms->N_RB_DL,
+                 dlsch0_harq->rb_alloc);
+    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];
+
+    dlsch0_harq->nb_rb                               = conv_nprb(rah,
+        rballoc,
+        frame_parms->N_RB_DL);
+    dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;
+
+    if (dlsch0_harq->nb_rb == 0)
+      return(-1);
+
+    dlsch0_harq->mcs       = mcs1;
+    dlsch1_harq->mcs       = mcs2;
+    dlsch0_harq->rvidx     = rv1;
+    dlsch1_harq->rvidx     = rv2;
+
+    // check if either TB is disabled (see 36-213 V8.6 p. 26)
+
+
+    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
+      dlsch0->active = 0;
+    }
+
+    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
+      dlsch1->active = 0;
+    }
+
+
+
+    if ((dlsch0_harq->round == 0) && (dlsch0->active == 1) ) {
+      dlsch0_harq->status      = ACTIVE;
+      dlsch0_harq->mcs         = mcs1;
+    }
+
+    if ((dlsch1_harq->round == 0) && (dlsch1->active == 1) ) {
+      dlsch1_harq->status      = ACTIVE;
+      dlsch1_harq->mcs         = mcs2;
+    }
+
+    // check TPMI information to compute TBS
+    if (frame_parms->nb_antenna_ports_eNB == 2) {
+      if (dlsch1->active == 1) { // both TBs are active
+        dlsch0_harq->TBS           = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+        dlsch1_harq->TBS           = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
+      } else {
+        dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+      }
+    } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+
+    }
+
+    dlsch0->rnti = rnti;
+    dlsch1->rnti = rnti;
+
+    dlsch0_harq->dl_power_off = 1;
+    dlsch1_harq->dl_power_off = 1;
+
+    break;
+
+  case format2D:
+
+    switch (frame_parms->N_RB_DL) {
+
+    case 6:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->rballoc;
+        rv1       = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->rballoc;
+        rv1       = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 25:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2D_5MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2D_5MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2D_5MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2D_5MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2D_5MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2D_5MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 50:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2D_10MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2D_10MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2D_10MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2D_10MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2D_10MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2D_10MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+
+    case 100:
+      if (frame_type == TDD) {
+        mcs1      = ((DCI2D_20MHz_TDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2D_20MHz_TDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2D_20MHz_TDD_t *)dci_pdu)->harq_pid;
+      } else {
+        mcs1      = ((DCI2D_20MHz_FDD_t *)dci_pdu)->mcs1;
+        mcs2      = ((DCI2D_20MHz_FDD_t *)dci_pdu)->mcs2;
+        rballoc   = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rballoc;
+        rah       = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rah;
+        rv1       = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rv1;
+        rv2       = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rv2;
+        harq_pid  = ((DCI2D_20MHz_FDD_t *)dci_pdu)->harq_pid;
+      }
+
+      break;
+    }
+
+
+    if (harq_pid>=8) {
+      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
+      return(-1);
+    }
+
+
+
+    dlsch0 = dlsch[0];
+    dlsch1 = dlsch[1];
+
+    dlsch0->subframe_tx[subframe] = 1;
+
+    dlsch0->current_harq_pid = harq_pid;
+    dlsch1->current_harq_pid = harq_pid;
+    dlsch0->harq_ids[subframe] = harq_pid;
+    dlsch1->harq_ids[subframe] = harq_pid;
+    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
+
+
+    dlsch0_harq = dlsch0->harq_processes[harq_pid];
+    dlsch1_harq = dlsch1->harq_processes[harq_pid];
+
+    // Needs to be checked
+    dlsch0_harq->codeword=0;
+    dlsch1_harq->codeword=1;
+
+    conv_rballoc(rah,
+                 rballoc,
+                 frame_parms->N_RB_DL,
+                 dlsch0_harq->rb_alloc);
+    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];
+
+    dlsch0_harq->nb_rb                               = conv_nprb(rah,
+        rballoc,
+        frame_parms->N_RB_DL);
+    dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;
+
+    dlsch0_harq->mcs       = mcs1;
+    dlsch1_harq->mcs       = mcs2;
+    dlsch0_harq->rvidx     = rv1;
+    dlsch1_harq->rvidx     = rv2;
+
+    // check if either TB is disabled (see 36-213 V8.6 p. 26)
+
+
+    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0))
+      dlsch0_harq->status = DISABLED;
+
+    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0))
+      dlsch1_harq->status = DISABLED;
+
+    dlsch0_harq->Nl        = 1;
+
+
+    if (dlsch0_harq->round == 0) {
+      dlsch0_harq->status = ACTIVE;
+      //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
+    }
+
+    dlsch0_harq->mcs         = mcs1;
+
+    if (dlsch0_harq->nb_rb > 0) {
+      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+    } else {
+      dlsch0_harq->TBS = 0;
+    }
+
+    dlsch0->active = 1;
+
+    dlsch0->rnti = rnti;
+    dlsch1->rnti = rnti;
+
+    dlsch0_harq->dl_power_off = 1;
+    dlsch1_harq->dl_power_off = 1;
+
+    break;
+
+
+  case format1E_2A_M10PRB:
+
+    harq_pid  = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid;
+
+    if (harq_pid>=8) {
+      LOG_E(PHY,"ERROR: Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid);
+      return(-1);
+    }
+
+    /*
+      tbswap = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tb_swap;
+      if (tbswap == 0) {
+      dlsch0 = dlsch[0];
+      dlsch1 = dlsch[1];
+      }
+      else{
+      dlsch0 = dlsch[1];
+      dlsch1 = dlsch[0];
+      }
+    */
+    dlsch0 = dlsch[0];
+    dlsch0->subframe_tx[subframe] = 1;
+
+    dlsch0->current_harq_pid = harq_pid;
+    //dlsch1->current_harq_pid = harq_pid;
+    dlsch0->harq_ids[subframe] = harq_pid;
+    //dlsch1->harq_ids[subframe] = harq_pid;
+    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
+    dlsch0_harq = dlsch0->harq_processes[harq_pid];
+       // Needs to be checked
+    dlsch0_harq->codeword=0;
+
+    conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah,
+                 ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL,
+                 dlsch0_harq->rb_alloc);
+
+    //dlsch1->rb_alloc[0]                         = dlsch0->rb_alloc[0];
+
+    dlsch0_harq->nb_rb                               = conv_nprb(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah,
+        ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,
+        frame_parms->N_RB_DL);
+    //dlsch1->nb_rb                               = dlsch0->nb_rb;
+
+    dlsch0_harq->mcs       = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
+    //dlsch1_harq->mcs       = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs2;
+    dlsch0_harq->rvidx     = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv;
+    //dlsch1_harq->rvidx     = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv2;
+
+    // check if either TB is disabled (see 36-213 V8.6 p. 26) --> only for format 2 and 2A
+
+    //if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0))
+    //  dlsch0_harq->status = DISABLED;
+
+    //if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0))
+    // dlsch1_harq->status = DISABLED;
+
+    dlsch0_harq->Nl        = 1;
+
+    //dlsch0->layer_index                         = tbswap;
+    //dlsch1->layer_index                         = 1-tbswap;
+
+    // Fix this
+    tpmi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tpmi;
+
+    switch (tpmi) {
+    case 0 :
+      dlsch0_harq->mimo_mode   = ALAMOUTI;
+      break;
+
+    case 1:
+      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING11;
+      dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,0, 0);
+
+      break;
+
+    case 2:
+      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
+      dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1, 0);
+
+      break;
+
+    case 3:
+      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
+      dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,2, 0);
+
+      break;
+
+    case 4:
+      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
+      dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,3, 0);
+      break;
+
+    case 5:
+      dlsch0_harq->mimo_mode   = PUSCH_PRECODING0;
+      dlsch0_harq->pmi_alloc   = DL_pmi_single;
+      break;
+
+    case 6:
+      dlsch0_harq->mimo_mode   = PUSCH_PRECODING1;
+      return(-1);
+      break;
+    }
+
+    //    printf("Set pmi %x (tpmi %d)\n",dlsch0->pmi_alloc,tpmi);
+
+
+    if (frame_parms->mode1_flag == 1)
+      dlsch0_harq->mimo_mode   = SISO;
+
+    //    dlsch0_harq->Ndi         = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi;
+    if (dlsch0_harq->round == 0) {
+      dlsch0_harq->status = ACTIVE;
+      //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
+    }
+
+    dlsch0_harq->mcs         = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
+
+    if (dlsch0_harq->nb_rb > 0) {
+      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+    } else {
+      dlsch0_harq->TBS = 0;
+    }
+
+    dlsch0->active = 1;
+
+    dlsch0->rnti = rnti;
+    //dlsch1->rnti = rnti;
+
+    //    dlsch0->dl_power_off = 1;
+    dlsch0_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off;
+    //dlsch1->dl_power_off = 1;
+
+    break;
+
+  default:
+    LOG_E(PHY,"Unknown DCI format\n");
+    return(-1);
+    break;
+  }
+
+
+  if (dlsch0_harq) {
+    dlsch0_harq->frame   = frame;
+    dlsch0_harq->subframe = subframe;
+  }
+  if (dlsch1_harq) {
+    dlsch1_harq->frame   = frame;
+    dlsch1_harq->subframe = subframe;
+  }
+
+#ifdef DEBUG_DCI
+
+  if (dlsch0) {
+    printf("dlsch0 eNB: dlsch0   %p\n",dlsch0);
+    printf("dlsch0 eNB: rnti     %x\n",dlsch0->rnti);
+    printf("dlsch0 eNB: NBRB     %d\n",dlsch0_harq->nb_rb);
+    printf("dlsch0 eNB: rballoc  %x\n",dlsch0_harq->rb_alloc[0]);
+    printf("dlsch0 eNB: harq_pid %d\n",harq_pid);
+    printf("dlsch0 eNB: round    %d\n",dlsch0_harq->round);
+    printf("dlsch0 eNB: rvidx    %d\n",dlsch0_harq->rvidx);
+    printf("dlsch0 eNB: TBS      %d (NPRB %d)\n",dlsch0_harq->TBS,NPRB);
+    printf("dlsch0 eNB: mcs      %d\n",dlsch0_harq->mcs);
+    printf("dlsch0 eNB: tpmi %d\n",tpmi);
+    printf("dlsch0 eNB: mimo_mode %d\n",dlsch0_harq->mimo_mode);
+  }
+
+    if (dlsch1) {
+    printf("dlsch1 eNB: dlsch1   %p\n",dlsch1);
+    printf("dlsch1 eNB: rnti     %x\n",dlsch1->rnti);
+    printf("dlsch1 eNB: NBRB     %d\n",dlsch1_harq->nb_rb);
+    printf("dlsch1 eNB: rballoc  %x\n",dlsch1_harq->rb_alloc[0]);
+    printf("dlsch1 eNB: harq_pid %d\n",harq_pid);
+    printf("dlsch1 eNB: round    %d\n",dlsch1_harq->round);
+    printf("dlsch1 eNB: rvidx    %d\n",dlsch1_harq->rvidx);
+    printf("dlsch1 eNB: TBS      %d (NPRB %d)\n",dlsch1_harq->TBS,NPRB);
+    printf("dlsch1 eNB: mcs      %d\n",dlsch1_harq->mcs);
+    printf("dlsch1 eNB: tpmi %d\n",tpmi);
+    printf("dlsch1 eNB: mimo_mode %d\n",dlsch1_harq->mimo_mode);
+  }
+
+#endif
+
+  // compute DL power control parameters
+
+  if (dlsch0 != NULL){
+  computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB);
+  computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off);
+}
+  if (dlsch1 != NULL){
+      computeRhoA_eNB(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB);
+  computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off);
+  }
+
+
+  return(0);
+}
+
+
+int dump_dci(NR_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
+{
+  switch (dci->format) {
+
+  case format0:   // This is an UL SCH allocation so nothing here, inform MAC
+    if ((frame_parms->frame_type == TDD) &&
+        (frame_parms->tdd_config>0))
+      switch(frame_parms->N_RB_DL) {
+      case 6:
+        LOG_D(PHY,"DCI format0 (TDD, 1.5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu[0])[0],
+              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping,
+              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift,
+              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai,
+              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req);
+        break;
+
+      case 25:
+        LOG_D(PHY,"DCI format0 (TDD1-6, 5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu[0])[0],
+              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping,
+              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift,
+              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai,
+              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req);
+        break;
+
+      case 50:
+        LOG_D(PHY,"DCI format0 (TDD1-6, 10MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu[0])[0],
+              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping,
+              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift,
+              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai,
+              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req);
+        break;
+
+      case 100:
+        LOG_D(PHY,"DCI format0 (TDD1-6, 20MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu[0])[0],
+              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping,
+              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift,
+              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai,
+              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req);
+        break;
+
+      default:
+        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+        DevParam (frame_parms->N_RB_DL, 0, 0);
+        break;
+      }
+    else if (frame_parms->frame_type == FDD)
+      switch(frame_parms->N_RB_DL) {
+      case 6:
+        LOG_D(PHY,"DCI format0 (FDD, 1.5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu[0])[0],
+              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->hopping,
+              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->cshift,
+              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req);
+        break;
+
+      case 25:
+        LOG_D(PHY,"DCI format0 (FDD, 5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu[0])[0],
+              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->hopping,
+              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->cshift,
+              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req);
+        break;
+
+      case 50:
+        LOG_D(PHY,"DCI format0 (FDD, 10MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu[0])[0],
+              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->hopping,
+              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->cshift,
+              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req);
+        break;
+
+      case 100:
+        LOG_D(PHY,"DCI format0 (FDD, 20MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu[0])[0],
+              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->hopping,
+              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->cshift,
+              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req);
+        break;
+
+      default:
+        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+        DevParam (frame_parms->N_RB_DL, 0, 0);
+        break;
+      }
+    else
+      LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n");
+
+    break;
+
+  case format1:
+    if ((frame_parms->frame_type == TDD) &&
+        (frame_parms->tdd_config>0))
+
+      switch(frame_parms->N_RB_DL) {
+      case 6:
+        LOG_D(PHY,"DCI format1 (TDD 1.5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu)[0],
+              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah,
+              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rv,
+              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->dai);
+        break;
+
+      case 25:
+        LOG_D(PHY,"DCI format1 (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu)[0],
+              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah,
+              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rv,
+              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->dai);
+        break;
+
+      case 50:
+        LOG_D(PHY,"DCI format1 (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu)[0],
+              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rah,
+              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rv,
+              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->dai);
+        break;
+
+      case 100:
+        LOG_D(PHY,"DCI format1 (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu)[0],
+              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rah,
+              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rv,
+              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->TPC,
+              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->dai);
+        break;
+
+      default:
+        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+        DevParam (frame_parms->N_RB_DL, 0, 0);
+        break;
+      }
+    else if (frame_parms->frame_type == FDD) {
+      switch(frame_parms->N_RB_DL) {
+      case 6:
+        LOG_D(PHY,"DCI format1 (FDD, 1.5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu)[0],
+              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rah,
+              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv,
+              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
+        break;
+
+      case 25:
+        LOG_D(PHY,"DCI format1 (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu)[0],
+              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rah,
+              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv,
+              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
+        break;
+
+      case 50:
+        LOG_D(PHY,"DCI format1 (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu)[0],
+              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rah,
+              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rv,
+              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
+        break;
+
+      case 100:
+        LOG_D(PHY,"DCI format1 (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n",
+              dci->rnti,
+              ((uint32_t*)&dci->dci_pdu)[0],
+              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rah,
+              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
+              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
+              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
+              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rv,
+              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
+        break;
+
+      default:
+        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+        DevParam (frame_parms->N_RB_DL, 0, 0);
+        break;
+      }
+    }
+
+    else
+      LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n");
+
+    break;
+
+  case format1A:  // This is DLSCH allocation for control traffic
+    if ((frame_parms->frame_type == TDD) &&
+        (frame_parms->tdd_config>0)) {
+      switch (frame_parms->N_RB_DL) {
+      case 6:
+        LOG_D(PHY,"DCI format1A (TDD1-6, 1_5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
+        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]);
+        LOG_D(PHY,"MCS %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
+        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
+        LOG_D(PHY,"NDI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
+        LOG_D(PHY,"RV %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
+        LOG_D(PHY,"TPC %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
+        LOG_D(PHY,"DAI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
+        break;
+
+      case 25:
+        LOG_D(PHY,"DCI format1A (TDD1-6, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
+        LOG_D(PHY,"RB_ALLOC %d (NB_RB %d)\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]);
+        LOG_D(PHY,"MCS %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
+        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
+        LOG_D(PHY,"NDI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
+        LOG_D(PHY,"RV %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
+        LOG_D(PHY,"TPC %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
+        LOG_D(PHY,"DAI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
+        break;
+
+      case 50:
+        LOG_D(PHY,"DCI format1A (TDD1-6, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
+        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]);
+        LOG_D(PHY,"MCS %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
+        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
+        LOG_D(PHY,"NDI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
+        LOG_D(PHY,"RV %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
+        LOG_D(PHY,"TPC %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
+        LOG_D(PHY,"DAI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
+        break;
+
+      case 100:
+        LOG_D(PHY,"DCI format1A (TDD1-6, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
+        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT100[((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]);
+        LOG_D(PHY,"MCS %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
+        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
+        LOG_D(PHY,"NDI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
+        LOG_D(PHY,"RV %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
+        LOG_D(PHY,"TPC %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
+        LOG_D(PHY,"DAI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
+        break;
+
+      default:
+        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+        DevParam (frame_parms->N_RB_DL, 0, 0);
+        break;
+      }
+
+    } else if (frame_parms->frame_type == FDD) {
+      switch (frame_parms->N_RB_DL) {
+      case 6:
+        LOG_D(PHY,"DCI format1A(FDD, 1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
+        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]);
+        LOG_D(PHY,"MCS %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
+        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
+        LOG_D(PHY,"NDI %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
+        LOG_D(PHY,"RV %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv);
+        LOG_D(PHY,"TPC %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
+        break;
+
+      case 25:
+        LOG_D(PHY,"DCI format1A(FDD, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
+        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]);
+        LOG_D(PHY,"MCS %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
+        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
+        LOG_D(PHY,"NDI %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
+        LOG_D(PHY,"RV %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rv);
+        LOG_D(PHY,"TPC %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
+        break;
+
+      case 50:
+        LOG_D(PHY,"DCI format1A(FDD, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
+        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]);
+        LOG_D(PHY,"MCS %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
+        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
+        LOG_D(PHY,"NDI %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
+        LOG_D(PHY,"RV %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rv);
+        LOG_D(PHY,"TPC %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
+        break;
+
+      case 100:
+        LOG_D(PHY,"DCI format1A(FDD, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
+        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT100[((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]);
+        LOG_D(PHY,"MCS %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
+        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
+        LOG_D(PHY,"NDI %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
+        LOG_D(PHY,"RV %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rv);
+        LOG_D(PHY,"TPC %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
+        break;
+
+      default:
+        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+        DevParam (frame_parms->N_RB_DL, 0, 0);
+        break;
+      }
+    }
+
+    break;
+
+  case format1C:  // This is DLSCH allocation for control traffic
+    switch (frame_parms->N_RB_DL) {
+    case 6:
+      LOG_D(PHY,"DCI format1C (1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+      LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",
+      ((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT6[conv_1C_RIV(((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,6)]);
+      LOG_D(PHY,"MCS %d\n",((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->mcs);
+      break;
+
+    case 25:
+      LOG_D(PHY,"DCI format1C (5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+      LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[conv_1C_RIV(((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,25)]);
+      LOG_D(PHY,"MCS %d\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->mcs);
+      break;
+
+    case 50:
+      LOG_D(PHY,"DCI format1C (10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+      LOG_D(PHY,"Ngap %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->Ngap);
+      LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,50)]);
+      LOG_D(PHY,"MCS %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->mcs);
+      break;
+
+    case 100:
+      LOG_D(PHY,"DCI format1C (20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
+      LOG_D(PHY,"Ngap %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->Ngap);
+      LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,100)]);
+      LOG_D(PHY,"MCS %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->mcs);
+      break;
+
+
+    default:
+      LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+        DevParam (frame_parms->N_RB_DL, 0, 0);
+        break;
+    }
+
+
+    break;
+
+  case format2:
+
+    if ((frame_parms->frame_type == TDD) &&
+        (frame_parms->tdd_config>0)) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        switch(frame_parms->N_RB_DL) {
+        case 6:
+          LOG_D(PHY,"DCI format2 2 antennas (TDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi
+               );
+          break;
+
+        case 25:
+          LOG_D(PHY,"DCI format2 2 antennas (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi);
+          break;
+
+        case 50:
+          LOG_D(PHY,"DCI format2 2 antennas (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi);
+          break;
+
+        case 100:
+          LOG_D(PHY,"DCI format2 2 antennas (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi);
+          break;
+
+        default:
+          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+          DevParam (frame_parms->N_RB_DL, 0, 0);
+          break;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        switch(frame_parms->N_RB_DL) {
+        case 6:
+          LOG_D(PHY,"DCI format2 2 antennas (TDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi
+               );
+          break;
+
+        case 25:
+          LOG_D(PHY,"DCI format2 2 antennas (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
+          break;
+
+        case 50:
+          LOG_D(PHY,"DCI format2 2 antennas (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
+          break;
+
+        case 100:
+          LOG_D(PHY,"DCI format2 2 antennas (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
+          break;
+
+        default:
+          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+          DevParam (frame_parms->N_RB_DL, 0, 0);
+          break;
+        }
+      }
+    } else if (frame_parms->frame_type == FDD) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        switch(frame_parms->N_RB_DL) {
+        case 6:
+          LOG_D(PHY,"DCI format2 2 antennas (FDD, 1.5 MHz), rnti %x (%x):  rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 25:
+
+          LOG_D(PHY,"DCI format2 2 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, swap %d, TPMI %d, TPC %d\n",
+
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 50:
+          LOG_D(PHY,"DCI format2 2 antennas (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 100:
+          LOG_D(PHY,"DCI format2 2 antennas (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        default:
+          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+          DevParam (frame_parms->N_RB_DL, 0, 0);
+          break;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        switch(frame_parms->N_RB_DL) {
+
+        case 6:
+          LOG_D(PHY,"DCI format2 4 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 25:
+          LOG_D(PHY,"DCI format2 4 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 50:
+          LOG_D(PHY,"DCI format2 4 antennas (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 100:
+          LOG_D(PHY,"DCI format2 4 antennas (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        default:
+          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+          DevParam (frame_parms->N_RB_DL, 0, 0);
+          break;
+        }
+      }
+    }
+
+    else
+      LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n");
+
+    break;
+
+  case format2A:
+
+    if ((frame_parms->frame_type == TDD) &&
+        (frame_parms->tdd_config>0)) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        switch(frame_parms->N_RB_DL) {
+        case 6:
+          LOG_D(PHY,"DCI format2A 2 antennas (FDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap
+               );
+          break;
+
+        case 25:
+          LOG_D(PHY,"DCI format2A 2 antennas (FDD 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap);
+          break;
+
+        case 50:
+          LOG_D(PHY,"DCI format2A 2 antennas (FDD 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap);
+          break;
+
+        case 100:
+          LOG_D(PHY,"DCI format2A 2 antennas (FDD 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap);
+          break;
+
+        default:
+          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+          DevParam (frame_parms->N_RB_DL, 0, 0);
+          break;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        switch(frame_parms->N_RB_DL) {
+        case 6:
+          LOG_D(PHY,"DCI format2A 4 antennas (TDD 1.5 MHz), rnti %x (%"PRIu64"): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi
+               );
+          break;
+
+        case 25:
+          LOG_D(PHY,"DCI format2A 4 antennas (TDD 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
+          break;
+
+        case 50:
+          LOG_D(PHY,"DCI format2A 4 antennas (TDD 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
+          break;
+
+        case 100:
+          LOG_D(PHY,"DCI format2A 4 antennas (TDD 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
+          break;
+
+        default:
+          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+          DevParam (frame_parms->N_RB_DL, 0, 0);
+          break;
+        }
+      }
+    } else if (frame_parms->frame_type == FDD) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        switch(frame_parms->N_RB_DL) {
+        case 6:
+          LOG_D(PHY,"DCI format2A 2 antennas (FDD, 1.5 MHz), rnti %x (%x):  rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n",
+                dci->rnti,
+                ((uint32_t*)&dci->dci_pdu)[0],
+                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 25:
+          LOG_D(PHY,"DCI format2A 2 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 50:
+          LOG_D(PHY,"DCI format2A 2 antennas (FDD, 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 100:
+          LOG_D(PHY,"DCI format2A 2 antennas (FDD, 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        default:
+          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+          DevParam (frame_parms->N_RB_DL, 0, 0);
+          break;
+        }
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+        switch(frame_parms->N_RB_DL) {
+
+        case 6:
+          LOG_D(PHY,"DCI format2A 4 antennas (FDD, 1.5 MHz), rnti %x (%"PRIu64"): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 25:
+          LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 50:
+          LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        case 100:
+          LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
+                dci->rnti,
+                ((uint64_t*)&dci->dci_pdu)[0],
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
+                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
+          break;
+
+        default:
+          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+          DevParam (frame_parms->N_RB_DL, 0, 0);
+          break;
+        }
+      }
+    }
+
+    else
+      LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n");
+
+    break;
+
+  case format1E_2A_M10PRB:
+
+    LOG_D(PHY,"DCI format1E_2A_M10PRB, rnti %x (%8x): harq_pid %d, rah %d, rb_alloc %x, mcs %d, rv %d, tpmi %d, ndi %d, dl_power_offset %d\n",
+          dci->rnti,
+          ((uint32_t *)&dci->dci_pdu)[0],
+          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->harq_pid,
+          //((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->tb_swap,
+          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rah,
+          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rballoc,
+          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->mcs,
+          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rv,
+          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->tpmi,
+          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->ndi,
+          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->dl_power_off
+         );
+
+    break;
+
+  default:
+    LOG_E(PHY,"dci_tools.c: dump_dci, unknown format %d\n",dci->format);
+    return(-1);
+  }
+
+  return(0);
+}
+#endif //(0)
+#ifdef NR_PDCCH_DCI_TOOLS
+int nr_extract_dci_info(PHY_VARS_NR_UE *ue,
+        uint8_t eNB_id,
+        lte_frame_type_t frame_type,
+        uint8_t dci_length,
+        void *dci_pdu,
+        NR_DCI_INFO_EXTRACTED_t *nr_pdci_info_extracted,
+        uint8_t dci_fields_sizes[48],
+        NR_DL_UE_HARQ_t *pdlsch0_harq,
+        NR_UE_DLSCH_t *pdlsch0,
+        NR_UE_ULSCH_t *ulsch0,
+        NR_DCI_format_t dci_format,
+        uint8_t nr_tti_rx,
+        uint16_t rnti,
+        uint16_t si_rnti,
+        uint16_t p_rnti,
+        uint16_t ra_rnti,
+        uint16_t tc_rnti,
+        uint16_t n_RB_ULBWP,
+        uint16_t n_RB_DLBWP)
+{
+/*
+ * This function will extract the different elements of the dci pdu and interpret the values extracted to update correctly the parameters in:
+ *                                                NR_DL_UE_HARQ_t *pdlsch0_harq,
+ *                                                NR_UE_DLSCH_t *pdlsch0,
+ *
+ * We need to know the dci length and the dci_fields_sizes (array containing each field size in number of bits)
+ * In order to get the value of a specific field we will proceed as follows (let's have a look to an example:
+ * If the length of the pdu is 38 bits and the content of the dci_pdu is 0x3A8900789A (pdu is 11 1010 1000 1001 0000 0000 0111 1000 1001 1010)
+ * If the dci_fields_sizes is {0 0 1 0 0 0 0 0 0 13 0 1 0 0 0 0 0 0 0 0 0 0 5 1 2 4 2 0 0 0 2 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0}
+ * This means:
+ *             number bits for carrier_ind field is 0
+ *             number bits for sul_ind_0_1 field is 0
+ *             number bits for identifier_dci_formats field is 0
+ *             number bits for slot_format_ind field is 0
+ *             number bits for pre_emption_ind field is 0
+ *             ...
+ *             number bits for freq_dom_resource_assignment_DL field is 13
+ *             ...
+ *             number bits for padding is 0
+ * In order to extract the information of (e.g.) freq_dom_resource_assignment_DL field,
+ * we will do a left-shift of 1 position (because previous to this field, and according to the dci_fields_sizes array, there is only one non-empty field of size 1 bit) -> (1 1010 1000 1001 0000 0000 0111 1000 1001 1010 0)
+ * then we will do a right-shit of dci_length-13 positions -> (1 1010 1000 1001). And this is the content of the freq_dom_resource_assignment_DL field
+ *
+ *
+ * At the moment we have implemented:
+ * Format 0_0, that contains the following fields according to Specification 38.212 V15.1.1 Section 7.3.1
+ *    2  IDENTIFIER_DCI_FORMATS:
+ *    8  FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered
+ *    10 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits,
+ *    15 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0
+ *    22 MCS:
+ *    23 NDI:
+ *    24 RV:
+ *    25 HARQ_PROCESS_NUMBER:
+ *    29 TPC_PUSCH:
+ *    46 SUL_IND_0_0:
+ *    47 PADDING: (Note 2) If DCI format 0_0 is monitored in common search space
+ *
+ * Format 1_0, that contains the following fields
+ *    2  IDENTIFIER_DCI_FORMATS:
+ *    9  FREQ_DOM_RESOURCE_ASSIGNMENT_DL:
+ *    10 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits,
+ *    11 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0
+ *    22 MCS:
+ *    23 NDI:
+ *    24 RV:
+ *    25 HARQ_PROCESS_NUMBER:
+ *    26 DAI: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI
+ *    30 TPC_PUCCH:
+ *    31 PUCCH_RESOURCE_IND:
+ *    32 PDSCH_TO_HARQ_FEEDBACK_TIME_IND:
+ *    33 SHORT_MESSAGE_IND: 1 bit if crc scrambled with P-RNTI
+ *    47 PADDING: (Note 2) If DCI format 0_0 is monitored in common search space
+ *
+ */
+  uint64_t pdu_bitmap = 0xFFFFFFFFFFFFFFFF;
+  pdu_bitmap = (pdu_bitmap << (64 - dci_length)) >> (64 - dci_length); // this variable will help to remove the bits of other fields when left-switching
+  uint8_t dci_field=0;
+  uint8_t sizes_count=0;
+  uint8_t left_shift=0;
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+  printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> Entering function nr_extract_dci_info() with dci_pdu=%llx with pdu_bitmap=%llx dci_length=%d\n",(*(uint64_t *)dci_pdu), pdu_bitmap, dci_length);
+  printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> dci_fields_sizes {");
+  for (int i=0; i<NBR_NR_DCI_FIELDS; i++) printf("%d ",dci_fields_sizes[i]);
+  printf("}\n");
+#endif
+  uint8_t  prev_ndi = pdlsch0_harq->DCINdi;
+  uint16_t l_RB;
+  uint16_t start_RB;
+  uint16_t tmp_RIV;
+  uint16_t l_symbol;
+  uint16_t start_symbol;
+  uint16_t tmp_symbol;
+
+ /*
+  * Some dci fields need to be interpreted before the others.
+  */
+  if (dci_fields_sizes[HARQ_PROCESS_NUMBER] != 0) { // E.g: 25 HARQ_PROCESS_NUMBER (25 is the position in dci_fields_sizes array for field HARQ_PROCESS_NUMBER)
+    for (int i=0; i<=HARQ_PROCESS_NUMBER; i++) left_shift = left_shift + dci_fields_sizes[i];
+    nr_pdci_info_extracted->harq_process_number = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[HARQ_PROCESS_NUMBER]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[HARQ_PROCESS_NUMBER]));
+    left_shift = 0;
+    #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+      printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->harq_process_number=%x\n",nr_pdci_info_extracted->harq_process_number);
+    #endif
+  }
+
+  if ((dci_format == format1_0) || (dci_format == format1_1)) {
+    if (rnti==si_rnti) {
+      ue->dlsch_SI[eNB_id]->active = 1;
+    } else if (rnti==p_rnti) {
+      ue->dlsch_p[eNB_id]->active  = 1;
+    } else if (rnti==ra_rnti) {
+      ue->dlsch_ra[eNB_id]->active = 1;
+    } else {
+      pdlsch0->active          = 1;
+    }
+    pdlsch0->rnti              = rnti;
+    pdlsch0_harq->codeword     = 0;
+    pdlsch0_harq->Nl           = 1;
+//  pdlsch0_harq->mimo_mode    = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI;
+    pdlsch0_harq->dl_power_off = 1; //no power offset
+
+    if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) {
+      pdlsch0_harq->round    = 0;
+      pdlsch0_harq->status   = ACTIVE;
+    } else {
+    }
+  }
+
+  for (dci_field=0; dci_field<NBR_NR_DCI_FIELDS; dci_field++) {
+    left_shift = left_shift + dci_fields_sizes[dci_field];
+    if (dci_fields_sizes[dci_field] != 0){
+      sizes_count = dci_fields_sizes[dci_field];
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> sizes_count = dci_fields_sizes[%d] = %d\n",dci_field,sizes_count);
+      #endif
+
+      switch (dci_field){
+      case 0: // 0  CARRIER_IND: (field defined for -,format0_1,-,format1_1,-,-,-,-)
+              // 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213]
+        nr_pdci_info_extracted->carrier_ind                      = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->carrier_ind=%x\n",nr_pdci_info_extracted->carrier_ind);
+#endif
+        break;
+      case 1: // 1  SUL_IND_0_1: (field defined for -,format0_1,-,-,-,-,-,-)
+        nr_pdci_info_extracted->sul_ind_0_1                      = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_0_1=%x\n",nr_pdci_info_extracted->sul_ind_0_1);
+#endif
+        break;
+
+      case 2: // 2  IDENTIFIER_DCI_FORMATS: (field defined for format0_0,format0_1,format1_0,format1_1,format2_0,format2_1,format2_2,format2_3)
+              // if format 0_0: The value of this bit field is always set to 0, indicating an UL DCI format (TS38.212 Section 7.3.1.1.1)
+              // if format 1_0: The value of this bit field is always set to 1, indicating a  DL DCI format (TS38.212 Section 7.3.1.2.1)
+        nr_pdci_info_extracted->identifier_dci_formats           = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->identifier_dci_formats=%x\n",nr_pdci_info_extracted->identifier_dci_formats);
+        #endif
+        break;
+
+      case 3: // 3  SLOT_FORMAT_IND: (field defined for -,-,-,-,format2_0,-,-,-)
+              // size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213]
+        nr_pdci_info_extracted->slot_format_ind                  = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->slot_format_ind=%x\n",nr_pdci_info_extracted->slot_format_ind);
+#endif
+        break;
+      case 4: // 4  PRE_EMPTION_IND: (field defined for -,-,-,-,-,format2_1,-,-)
+              // size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits
+        nr_pdci_info_extracted->pre_emption_ind                  = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pre_emption_ind=%x\n",nr_pdci_info_extracted->pre_emption_ind);
+#endif
+        break;
+      case 5: // 5  TPC_CMD_NUMBER: (field defined for -,-,-,-,-,-,format2_2,-)
+              // The parameter xxx provided by higher layers determines the index to the TPC command number for an UL of a cell. Each TPC command number is 2 bits
+        nr_pdci_info_extracted->tpc_cmd_number                   = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_cmd_number=%x\n",nr_pdci_info_extracted->tpc_cmd_number);
+#endif
+        break;
+      case 6: // 6  BLOCK_NUMBER: (field defined for -,-,-,-,-,-,-,format2_3)
+              // starting position of a block is determined by the parameter startingBitOfFormat2_3
+        nr_pdci_info_extracted->block_number                     = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->block_number=%x\n",nr_pdci_info_extracted->block_number);
+#endif
+        break;
+      case 7: // 7  BANDWIDTH_PART_IND: (field defined for -,format0_1,-,format1_1,-,-,-,-)
+        nr_pdci_info_extracted->bandwidth_part_ind               = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->bandwidth_part_ind=%x\n",nr_pdci_info_extracted->bandwidth_part_ind);
+#endif
+        break;
+
+      case 8: // 8  FREQ_DOM_RESOURCE_ASSIGNMENT_UL: (field defined for format0_0,format0_1,-,-,-,-,-,-)
+              // PUSCH hopping with resource allocation type 1 not considered
+              // According to 38.214 V15.1.0 Section 6.1.2.2 Two uplink resource allocation schemes, type 0 and type 1, are supported.
+              // The UE shall assume that when the scheduling PDCCH is received with DCI format 0_0, then uplink resource allocation type 1 is used.
+        nr_pdci_info_extracted->freq_dom_resource_assignment_UL  = (uint16_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        if (dci_format == format0_1){ // uplink resource allocation type 0 or 1 can be used
+        }
+        if (dci_format == format0_0){ // only uplink resource allocation type 1
+              // At the moment we are supporting only format 1_0 (and not format 1_1), so we only support resource allocation type 1 (and not type 0).
+              // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV):
+              // RIV = n_RB_ULBWP * (l_RB - 1) + start_RB                                  if (l_RB - 1) <= floor (n_RB_ULBWP/2)
+              // RIV = n_RB_ULBWP * (n_RB_ULBWP - l_RB + 1) + (n_RB_ULBWP - 1 - start_RB)  if (l_RB - 1)  > floor (n_RB_ULBWP/2)
+          // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_ULBWP/2)
+          l_RB = floor(nr_pdci_info_extracted->freq_dom_resource_assignment_DL/n_RB_ULBWP) + 1;
+          start_RB = nr_pdci_info_extracted->freq_dom_resource_assignment_DL%n_RB_ULBWP;
+          // if (l_RB - 1)  > floor (n_RB_ULBWP/2) we need to recalculate them using the following lines
+          tmp_RIV = n_RB_ULBWP * (l_RB - 1) + start_RB;
+          if (tmp_RIV != nr_pdci_info_extracted->freq_dom_resource_assignment_DL) { // then (l_RB - 1)  > floor (n_RB_ULBWP/2) and we need to recalculate l_RB and start_RB
+            l_RB = n_RB_ULBWP - l_RB + 2;
+            start_RB = n_RB_ULBWP - start_RB - 1;
+          }
+          ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_rb = start_RB;
+          ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->nb_rb    = l_RB;
+        }
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_dom_resource_assignment_UL=%x\n",nr_pdci_info_extracted->freq_dom_resource_assignment_UL);
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> l_RB=%d, start_RB=%d, n_RB_DLBWP=%d\n",l_RB,start_RB,n_RB_ULBWP);
+        #endif
+        break;
+
+      case 9: // 9  FREQ_DOM_RESOURCE_ASSIGNMENT_DL: (field defined for -,-,format1_0,format1_1,-,-,-,-)
+              // According to 38.214 V15.1.0 Section 5.1.2.2 Two downlink resource allocation schemes, type 0 and type 1, are supported.
+              // The UE shall assume that when the scheduling grant is received with DCI format 1_0, then downlink resource allocation type 1 is used.
+        nr_pdci_info_extracted->freq_dom_resource_assignment_DL  = (uint16_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        if (dci_format == format1_1){ // uplink resource allocation type 0 or 1 can be used
+        }
+        if (dci_format == format1_0){ // only uplink resource allocation type 1
+              // At the moment we are supporting only format 0_0 (and not format 0_1), so we only support resource allocation type 1 (and not type 0).
+              // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV):
+              // RIV = n_RB_DLBWP * (l_RB - 1) + start_RB                                  if (l_RB - 1) <= floor (n_RB_DLBWP/2)
+              // RIV = n_RB_DLBWP * (n_RB_DLBWP - l_RB + 1) + (n_RB_DLBWP - 1 - start_RB)  if (l_RB - 1)  > floor (n_RB_DLBWP/2)
+          // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_DLBWP/2)
+          l_RB = floor(nr_pdci_info_extracted->freq_dom_resource_assignment_DL/n_RB_DLBWP) + 1;
+          start_RB = nr_pdci_info_extracted->freq_dom_resource_assignment_DL%n_RB_DLBWP;
+          // if (l_RB - 1)  > floor (n_RB_DLBWP/2) we need to recalculate them using the following lines
+          tmp_RIV = n_RB_DLBWP * (l_RB - 1) + start_RB;
+          if (tmp_RIV != nr_pdci_info_extracted->freq_dom_resource_assignment_DL) { // then (l_RB - 1)  > floor (n_RB_DLBWP/2) and we need to recalculate l_RB and start_RB
+            l_RB = n_RB_DLBWP - l_RB + 2;
+            start_RB = n_RB_DLBWP - start_RB - 1;
+          }
+          pdlsch0_harq->nb_rb = l_RB;
+          pdlsch0->current_harq_pid = nr_pdci_info_extracted->harq_process_number;
+          pdlsch0->active           = 1;
+          pdlsch0->rnti             = rnti;
+        }
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_dom_resource_assignment_DL=%x, RIV = %d\n",nr_pdci_info_extracted->freq_dom_resource_assignment_DL,nr_pdci_info_extracted->freq_dom_resource_assignment_DL);
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> l_RB=%d, start_RB=%d, n_RB_DLBWP=%d\n",l_RB,start_RB,n_RB_DLBWP);
+        /*
+         * The following commented code is used to verify that l_RB and start_RB are correctly calculated
+         *
+         *
+        printf("\ns_RB\t");
+        n_RB_DLBWP = 20;
+        for (int k = 0 ; k < n_RB_DLBWP; k++) printf("%d\t",k);
+        printf("\nl_RB");
+        for (int j = 1 ; j <= n_RB_DLBWP; j++){ // l_RB
+          printf("\n%d\t",j);
+          for (int i = 0 ; i < n_RB_DLBWP; i++) { // start_RB
+            if ((j-1) <= (floor(n_RB_DLBWP/2)) && ((j+i) <= n_RB_DLBWP)) {
+              tmp_RIV = n_RB_DLBWP * (j - 1) + i;
+              l_RB = floor(tmp_RIV/n_RB_DLBWP) + 1;
+              start_RB = tmp_RIV%n_RB_DLBWP;
+              printf("%d(%d,%d)  ",tmp_RIV,l_RB,start_RB);
+            }
+            if ((j-1) >  (floor(n_RB_DLBWP/2)) && ((j+i) <= n_RB_DLBWP)) {
+              tmp_RIV = n_RB_DLBWP * (n_RB_DLBWP - j + 1) + (n_RB_DLBWP - 1 - i);
+              //l_RB = floor(tmp_RIV/n_RB_DLBWP) + 1;
+              //start_RB = tmp_RIV%n_RB_DLBWP;
+              l_RB = n_RB_DLBWP - (floor(tmp_RIV/n_RB_DLBWP) + 1) + 2;
+              start_RB = n_RB_DLBWP - (tmp_RIV%n_RB_DLBWP) - 1;
+              printf("%d*(%d,%d)  ",tmp_RIV,l_RB,start_RB);
+            }
+          }
+        }*/
+        #endif
+        break;
+
+      case 10: // 10 TIME_DOM_RESOURCE_ASSIGNMENT: (field defined for format0_0,format0_1,format1_0,format1_1,-,-,-,-)
+               // 0, 1, 2, 3, or 4 bits as defined in:
+               //         Subclause 6.1.2.1 of [6, TS 38.214] for formats format0_0,format0_1
+               //         Subclause 5.1.2.1 of [6, TS 38.214] for formats format1_0,format1_1
+               // The bitwidth for this field is determined as log2(I) bits,
+               // where I the number of entries in the higher layer parameter pusch-AllocationList
+        nr_pdci_info_extracted->time_dom_resource_assignment     = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        if (dci_format == format0_0 || dci_format == format0_1){ // Subclause 6.1.2.1 of [6, TS 38.214]
+
+        }
+        if (dci_format == format1_0 || dci_format == format1_1){ // Subclause 5.1.2.1 of [6, TS 38.214]
+         //the Time domain resource assignment field of the DCI provides a row index of a higher layer configured table pdsch-symbolAllocation
+         // FIXME! To clarify which parameters to update after reception of row index
+        }
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->time_dom_resource_assignment=%x\n",nr_pdci_info_extracted->time_dom_resource_assignment);
+        #endif
+        break;
+
+      case 11: // 11 VRB_TO_PRB_MAPPING: (field defined for -,format0_1,format1_0,format1_1,-,-,-,-)
+      //0 bit if resource allocation type 0
+      //1 bit if resource allocation type 1
+                             //Table 7.3.1.1.2-33: VRB-to-PRB mapping
+                            // 0  Non-interleaved
+                            // 1  Interleaved
+        nr_pdci_info_extracted->vrb_to_prb_mapping               = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        if (nr_pdci_info_extracted->vrb_to_prb_mapping == 0) { // Non-interleaved
+        } else { // Interleaved
+                 // format 0_1 defined in TS 38.211 Section 6.3.1.7
+                 // formats 1_0 and 1_1 not defined yet
+        }
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->vrb_to_prb_mapping=%x\n",nr_pdci_info_extracted->vrb_to_prb_mapping);
+        #endif
+        break;
+
+      case 12: // 12 PRB_BUNDLING_SIZE_IND: (field defined for -,-,-,format1_1,-,-,-,-)
+               // 0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214]
+        nr_pdci_info_extracted->prb_bundling_size_ind            = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->prb_bundling_size_ind=%x\n",nr_pdci_info_extracted->prb_bundling_size_ind);
+#endif
+        break;
+      case 13: // 13 RATE_MATCHING_IND: (field defined for -,-,-,format1_1,-,-,-,-)
+               // 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set
+        nr_pdci_info_extracted->rate_matching_ind                = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->rate_matching_ind=%x\n",nr_pdci_info_extracted->rate_matching_ind);
+#endif
+        break;
+      case 14: // 14 ZP_CSI_RS_TRIGGER: (field defined for -,-,-,format1_1,-,-,-,-)
+        nr_pdci_info_extracted->zp_csi_rs_trigger                = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->zp_csi_rs_trigger=%x\n",nr_pdci_info_extracted->zp_csi_rs_trigger);
+#endif
+        break;
+
+      case 15: // 15 FREQ_HOPPING_FLAG: (field defined for format0_0,format0_1,-,-,-,-,-,-)
+               // 0 bit if only resource allocation type 0
+               // 1 bit otherwise, only applicable to resource allocation type 1, as defined in Subclause 6.3 of [6, TS 38.214]
+        nr_pdci_info_extracted->freq_hopping_flag                = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        if (nr_pdci_info_extracted->freq_hopping_flag != 0) { // PUSCH frequency hopping is performed     (only resource allocation type 1)
+
+        } else {                                              // PUSCH frequency hopping is not performed (only resource allocation type 1)
+          // At the moment PUSCH hopping is not implemented. We are considering that the bit is present and the value is '0'
+        }
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_hopping_flag=%x\n",nr_pdci_info_extracted->freq_hopping_flag);
+        #endif
+        break;
+
+      case 16: // 16 TB1_MCS: (field defined for -,-,-,format1_1,-,-,-,-)
+        nr_pdci_info_extracted->tb1_mcs                          = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs  = nr_pdci_info_extracted->tb1_mcs;
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_mcs=%x\n",nr_pdci_info_extracted->tb1_mcs);
+        #endif
+        break;
+      case 17: // 17 TB1_NDI: (field defined for -,-,-,format1_1,-,-,-,-)
+        nr_pdci_info_extracted->tb1_ndi                          = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        pdlsch0_harq->DCINdi = nr_pdci_info_extracted->tb1_ndi;
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_ndi=%x\n",nr_pdci_info_extracted->tb1_ndi);
+        #endif
+        break;
+      case 18: // 18 TB1_RV: (field defined for -,-,-,format1_1,-,-,-,-)
+        nr_pdci_info_extracted->tb1_rv                           = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        pdlsch0_harq->rvidx  = nr_pdci_info_extracted->tb1_rv;
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_rv=%x\n",nr_pdci_info_extracted->tb1_rv);
+        #endif
+        break;
+      case 19: // 19 TB2_MCS: (field defined for -,-,-,format1_1,-,-,-,-)
+        nr_pdci_info_extracted->tb2_mcs                          = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs  = nr_pdci_info_extracted->tb2_mcs;
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_mcs=%x\n",nr_pdci_info_extracted->tb2_mcs);
+        #endif
+        break;
+      case 20: // 20 TB2_NDI: (field defined for -,-,-,format1_1,-,-,-,-)
+        nr_pdci_info_extracted->tb2_ndi                          = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        pdlsch0_harq->DCINdi = nr_pdci_info_extracted->tb2_ndi;
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_ndi=%x\n",nr_pdci_info_extracted->tb2_ndi);
+        #endif
+        break;
+      case 21: // 21 TB2_RV: (field defined for -,-,-,format1_1,-,-,-,-)
+        nr_pdci_info_extracted->tb2_rv                           = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        pdlsch0_harq->rvidx  = nr_pdci_info_extracted->tb2_rv;
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_rv=%x\n",nr_pdci_info_extracted->tb2_rv);
+        #endif
+        break;
+
+      case 22: // 22 MCS: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-)
+        nr_pdci_info_extracted->mcs                              = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        if (nr_pdci_info_extracted->mcs < 29) {
+          if (dci_format == format0_0 || dci_format == format0_1)
+            ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->mcs = nr_pdci_info_extracted->mcs;
+          else
+            pdlsch0_harq->mcs = nr_pdci_info_extracted->mcs;
+        } else {
+          return(0);
+        }
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->mcs=%x\n",nr_pdci_info_extracted->mcs);
+        #endif
+        break;
+
+      case 23: // 23 NDI: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-)
+        nr_pdci_info_extracted->ndi                              = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        if (dci_format == format0_0 || dci_format == format0_1) {
+          ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi = nr_pdci_info_extracted->ndi;
+          if (ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_tx==1) {
+            ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_tx=0;
+            ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi= nr_pdci_info_extracted->ndi;
+            ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->round = 0;
+          } else {
+            if (ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi != nr_pdci_info_extracted->ndi) { // new SDU opportunity
+              ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi= nr_pdci_info_extracted->ndi;
+              ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->round = 0;
+            }
+          }
+        } else {
+          if (rnti == tc_rnti) { //fix for standalone Contention Resolution Id
+            pdlsch0_harq->DCINdi = (uint8_t)-1;
+          } else {
+            if ((prev_ndi != nr_pdci_info_extracted->ndi) || (pdlsch0_harq->first_tx==1)) {
+              pdlsch0_harq->round    = 0;
+              pdlsch0_harq->first_tx = 0;
+              pdlsch0_harq->status   = ACTIVE;
+            }
+            pdlsch0_harq->DCINdi = nr_pdci_info_extracted->ndi;
+          }
+        }
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ndi=%x\n",nr_pdci_info_extracted->ndi);
+        #endif
+        break;
+
+      case 24: // 24 RV: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-)
+        nr_pdci_info_extracted->rv                               = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        if (dci_format == format0_0 || dci_format == format0_1)
+          ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->rvidx = nr_pdci_info_extracted->rv;
+        else
+          pdlsch0_harq->rvidx = nr_pdci_info_extracted->rv;
+        if ((prev_ndi == nr_pdci_info_extracted->ndi) && (pdlsch0_harq->rvidx != 0)) { // NDI has not been toggled but rv was increased by eNB: retransmission
+          if (pdlsch0_harq->status == SCH_IDLE) {
+                        // packet was actually decoded in previous transmission (ACK was missed by eNB)
+                        // however, the round is not a good check as it might have been decoded in a retransmission prior to this one.
+                        // skip pdsch decoding and report ack
+            pdlsch0->active       = 0;
+            pdlsch0->harq_ack[nr_tti_rx].ack = 1;
+            pdlsch0->harq_ack[nr_tti_rx].harq_id = nr_pdci_info_extracted->harq_process_number;
+            pdlsch0->harq_ack[nr_tti_rx].send_harq_status = 1;
+          } else { // normal retransmission, nothing special to do
+          }
+        } else {
+          pdlsch0_harq->status   = ACTIVE;
+        }
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+         printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->rv=%x\n",nr_pdci_info_extracted->rv);
+        #endif
+        break;
+
+      case 25: // 25 HARQ_PROCESS_NUMBER: (field defined for format0_0,format0_1,format1_0,format1_1,-,-,-,-)
+        nr_pdci_info_extracted->harq_process_number              = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        pdlsch0->current_harq_pid = nr_pdci_info_extracted->harq_process_number;
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->harq_process_number=%x\n",nr_pdci_info_extracted->harq_process_number);
+        #endif
+        break;
+
+      case 26: // 26 DAI: (field defined for -,-,format1_0,format1_1,-,-,-,-)
+               // For format1_0: 2 bits as defined in Subclause 9.1.3 at TS 38.213
+               // For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI
+               // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI
+               // 0 otherwise
+        nr_pdci_info_extracted->dai                              = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        pdlsch0->harq_ack[nr_tti_rx].vDAI_DL = nr_pdci_info_extracted->dai+1;
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dai=%x\n",nr_pdci_info_extracted->dai);
+        #endif
+        break;
+
+      case 27: // 27 FIRST_DAI: (field defined for -,format0_1,-,-,-,-,-,-)
+               // (1 or 2 bits) 1 bit for semi-static HARQ-ACK
+        nr_pdci_info_extracted->first_dai                        = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+         printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->first_dai=%x\n",nr_pdci_info_extracted->first_dai);
+#endif
+        break;
+      case 28: // 28 SECOND_DAI: (field defined for -,format0_1,-,-,-,-,-,-)
+               // (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks
+        nr_pdci_info_extracted->second_dai                       = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->second_dai=%x\n",nr_pdci_info_extracted->second_dai);
+#endif
+        break;
+
+      case 29: // 29 TPC_PUSCH: (field defined for format0_0,format0_1,-,-,-,-,-,-)
+               // defined in Subclause 7.1.1 TS 38.213
+        nr_pdci_info_extracted->tpc_pusch                        = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC = nr_pdci_info_extracted->tpc_pusch;
+        if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) {
+          ulsch0->f_pusch += delta_PUSCH_acc[ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC];
+        } else {
+          ulsch0->f_pusch  = delta_PUSCH_abs[ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC];
+        }
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_pusch=%x\n",nr_pdci_info_extracted->tpc_pusch);
+        #endif
+        break;
+
+      case 30: // 30 TPC_PUCCH: (field defined for -,-,format1_0,format1_1,-,-,-,-)
+               // defined in Subclause 7.2.1 TS 38.213
+        nr_pdci_info_extracted->tpc_pucch                        = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        pdlsch0_harq->delta_PUCCH  = delta_PUCCH_lut[nr_pdci_info_extracted->tpc_pucch &3];
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_pucch=%x\n",nr_pdci_info_extracted->tpc_pucch);
+        #endif
+        break;
+
+      case 31: // 31 PUCCH_RESOURCE_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-)
+               // defined in Subclause 9.2.3 TS 38.213
+               // PUCCH_RESOURCE_IND points to PUCCH-ResourceId, but PUCCH-ResourceId is not defined yet
+        nr_pdci_info_extracted->pucch_resource_ind               = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pucch_resource_ind=%x\n",nr_pdci_info_extracted->pucch_resource_ind);
+        #endif
+        break;
+
+      case 32: // 32 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-)
+               // defined in Subclause 9.2.3 TS 38.213
+               // PDSCH_TO_HARQ_FEEDBACK_TIME_IND points to DL-data-DL-acknowledgement, but DL-data-DL-acknowledgement is not defined yet
+        nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind  = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind=%x\n",nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind);
+        #endif
+        break;
+
+      case 33: // 33 SHORT_MESSAGE_IND: (field defined for -,-,format1_0,-,-,-,-,-)
+               // 1 bit if crc scrambled with P-RNTI
+        if (rnti == p_rnti) {
+          nr_pdci_info_extracted->short_message_ind                = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+          // short message indication flag not implemented in NR_UE_DLSCH_t
+        }
+        #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+          printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->short_message_ind=%x\n",nr_pdci_info_extracted->short_message_ind);
+        #endif
+        break;
+
+      case 34: // 34 SRS_RESOURCE_IND: (field defined for -,format0_1,-,-,-,-,-,-)
+        nr_pdci_info_extracted->srs_resource_ind                 = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->srs_resource_ind=%x\n",nr_pdci_info_extracted->srs_resource_ind);
+#endif
+        break;
+      case 35: // 35 PRECOD_NBR_LAYERS: (field defined for -,format0_1,-,-,-,-,-,-)
+        nr_pdci_info_extracted->precod_nbr_layers                = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->precod_nbr_layers=%x\n",nr_pdci_info_extracted->precod_nbr_layers);
+#endif
+        break;
+      case 36: // 36 ANTENNA_PORTS: (field defined for -,format0_1,-,format1_1,-,-,-,-)
+        nr_pdci_info_extracted->antenna_ports                    = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->antenna_ports=%x\n",nr_pdci_info_extracted->antenna_ports);
+#endif
+        break;
+      case 37: // 37 TCI: (field defined for -,-,-,format1_1,-,-,-,-)
+               // 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits
+        nr_pdci_info_extracted->tci                              = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tci=%x\n",nr_pdci_info_extracted->tci);
+#endif
+        break;
+      case 38: // 38 SRS_REQUEST: (field defined for -,format0_1,-,format1_1,-,-,-,format2_3)
+        nr_pdci_info_extracted->srs_request                      = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->srs_request=%x\n",nr_pdci_info_extracted->srs_request);
+#endif
+        break;
+      case 39: // 39 TPC_CMD_NUMBER_FORMAT2_3: (field defined for -,-,-,-,-,-,-,format2_3)
+        nr_pdci_info_extracted->tpc_cmd_number_format2_3         = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_cmd_number_format2_3=%x\n",nr_pdci_info_extracted->tpc_cmd_number_format2_3);
+#endif
+        break;
+      case 40: // 40 CSI_REQUEST: (field defined for -,format0_1,-,-,-,-,-,-)
+        nr_pdci_info_extracted->csi_request                      = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->csi_request=%x\n",nr_pdci_info_extracted->csi_request);
+#endif
+        break;
+      case 41: // 41 CBGTI: (field defined for -,format0_1,-,format1_1,-,-,-,-)
+               // 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH
+        nr_pdci_info_extracted->cbgti                            = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->cbgti=%x\n",nr_pdci_info_extracted->cbgti);
+#endif
+        break;
+      case 42: // 42 CBGFI: (field defined for -,-,-,format1_1,-,-,-,-)
+               // 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator
+        nr_pdci_info_extracted->cbgfi                            = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->cbgfi=%x\n",nr_pdci_info_extracted->cbgfi);
+#endif
+        break;
+      case 43: // 43 PTRS_DMRS: (field defined for -,format0_1,-,-,-,-,-,-)
+        nr_pdci_info_extracted->ptrs_dmrs                        = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ptrs_dmrs=%x\n",nr_pdci_info_extracted->ptrs_dmrs);
+#endif
+        break;
+      case 44: // 44 BETA_OFFSET_IND: (field defined for -,format0_1,-,-,-,-,-,-)
+        nr_pdci_info_extracted->beta_offset_ind                  = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->beta_offset_ind=%x\n",nr_pdci_info_extracted->beta_offset_ind);
+#endif
+        break;
+      case 45: // 45 DMRS_SEQ_INI: (field defined for -,format0_1,-,format1_1,-,-,-,-)
+               // 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise
+        nr_pdci_info_extracted->dmrs_seq_ini                     = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dmrs_seq_ini=%x\n",nr_pdci_info_extracted->dmrs_seq_ini);
+#endif
+        break;
+      case 46: // 46 SUL_IND_0_0: (field defined for format0_0,-,-,-,-,-,-,-)
+        nr_pdci_info_extracted->sul_ind_0_0                      = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_0_0=%x\n",nr_pdci_info_extracted->sul_ind_0_0);
+#endif
+        break;
+      case 47: // 47 PADDING: (field defined for format0_0,-,format1_0,-,-,-,-,-)
+               // (Note 2) If DCI format 0_0 is monitored in common search space
+        nr_pdci_info_extracted->padding                          = (uint16_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[dci_field]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field]));
+#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->padding=%x\n",nr_pdci_info_extracted->padding);
+#endif
+        break;
+      }
+    }
+  }
+  #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+    printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> Ending function nr_extract_dci_info()\n");
+  #endif
+  return(1);
+}
+#endif
+
+#if 0
+void extract_dci1A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
+{
+    uint8_t harq_pid=0;
+    uint32_t rballoc=0;
+    uint8_t vrb_type=0;
+    uint8_t mcs=0;
+    uint8_t rv=0;
+    uint8_t ndi=0;
+    uint8_t TPC=0;
+
+    uint8_t dai=0;
+
+    switch (N_RB_DL) {
+    case 6:
+        if (frame_type == TDD) {
+            vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
+            mcs      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
+            rballoc  = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv;
+            ndi      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi;
+            TPC      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
+            harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
+            dai      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai;
+            //  printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
+        } else {
+            vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type;
+            mcs      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs;
+            rballoc  = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv;
+            ndi      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->ndi;
+            TPC      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC;
+            harq_pid  = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
+            //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
+        }
+        break;
+
+    case 25:
+
+        if (frame_type == TDD) {
+            vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
+            mcs      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
+            rballoc  = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv;
+            ndi      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi;
+            TPC      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
+            harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
+            dai      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai;
+            //printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
+        } else {
+            vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type;
+            mcs      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs;
+            rballoc  = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv;
+            ndi      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->ndi;
+            TPC      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC;
+            harq_pid  = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid;
+            //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
+        }
+
+        break;
+
+    case 50:
+        if (frame_type == TDD) {
+            vrb_type = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
+            mcs      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs;
+            rballoc  = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv;
+            ndi      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi;
+            TPC      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC;
+            harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
+            dai      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai;
+            //  printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
+        } else {
+            vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type;
+            mcs      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs;
+            rballoc  = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv;
+            ndi      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->ndi;
+            TPC      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC;
+            harq_pid  = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid;
+            //printf("FDD 1A: mcs %d, vrb_type %d, rballoc %x,ndi %d, rv %d, TPC %d\n",mcs,vrb_type,rballoc,ndi,rv,TPC);
+        }
+        break;
+
+    case 100:
+        if (frame_type == TDD) {
+            vrb_type = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
+            mcs      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs;
+            rballoc  = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv;
+            ndi      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi;
+            TPC      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC;
+            harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
+            dai      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai;
+            //  printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
+        } else {
+            vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type;
+            mcs      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs;
+            rballoc  = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv;
+            ndi      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->ndi;
+            TPC      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC;
+            harq_pid = ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid;
+            //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
+        }
+        break;
+    }
+
+    pdci_info_extarcted->vrb_type = vrb_type;
+    pdci_info_extarcted->mcs1     = mcs;
+    pdci_info_extarcted->rballoc  = rballoc;
+    pdci_info_extarcted->rv1      = rv;
+    pdci_info_extarcted->ndi1     = ndi;
+    pdci_info_extarcted->TPC      = TPC;
+    pdci_info_extarcted->harq_pid = harq_pid;
+    pdci_info_extarcted->dai      = dai;
+}
+
+void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
+{
+
+    uint32_t rballoc=0;
+    uint8_t mcs=0;
+
+    switch (N_RB_DL) {
+        case 6:
+          mcs             = ((DCI1C_5MHz_t *)dci_pdu)->mcs;
+          rballoc         = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6);
+
+          break;
+
+        case 25:
+            mcs             = ((DCI1C_5MHz_t *)dci_pdu)->mcs;
+            rballoc         = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6);
+
+          break;
+
+        case 50:
+            mcs             = ((DCI1C_10MHz_t *)dci_pdu)->mcs;
+            rballoc         = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,6);
+
+          break;
+
+        case 100:
+            mcs             = ((DCI1C_20MHz_t *)dci_pdu)->mcs;
+            rballoc         = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,6);
+          break;
+
+        default:
+          AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",N_RB_DL);
+          break;
+        }
+
+    pdci_info_extarcted->mcs1     = mcs;
+    pdci_info_extarcted->rballoc  = rballoc;
+}
+
+void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
+{
+
+    uint32_t rballoc=0;
+    uint8_t mcs=0;
+    uint8_t rah=0;
+    uint8_t rv=0;
+    uint8_t TPC=0;
+    uint8_t ndi=0;
+    uint8_t harq_pid=0;
+
+    switch (N_RB_DL) {
+    case 6:
+        if (frame_type == TDD) {
+            mcs       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs;
+            rballoc   = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc;
+            rah       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah;
+            rv        = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv;
+            TPC       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->TPC;
+            ndi       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->ndi;
+            harq_pid  = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
+        } else {
+            mcs      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs;
+            rah      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah;
+            rballoc  = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv;
+            TPC       = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->TPC;
+            ndi      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->ndi;
+            harq_pid = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
+        }
+
+        break;
+
+    case 25:
+        if (frame_type == TDD) {
+            mcs       = ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs;
+            rballoc   = ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc;
+            rah       = ((DCI1_5MHz_TDD_t *)dci_pdu)->rah;
+            rv        = ((DCI1_5MHz_TDD_t *)dci_pdu)->rv;
+            TPC       = ((DCI1_5MHz_TDD_t *)dci_pdu)->TPC;
+            ndi       = ((DCI1_5MHz_TDD_t *)dci_pdu)->ndi;
+            harq_pid  = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid;
+        } else {
+            mcs      = ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs;
+            rah      = ((DCI1_5MHz_FDD_t *)dci_pdu)->rah;
+            rballoc  = ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1_5MHz_FDD_t *)dci_pdu)->rv;
+            TPC      = ((DCI1_5MHz_FDD_t *)dci_pdu)->TPC;
+            ndi      = ((DCI1_5MHz_FDD_t *)dci_pdu)->ndi;
+            harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid;
+        }
+
+        break;
+
+    case 50:
+        if (frame_type == TDD) {
+            mcs       = ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs;
+            rballoc   = ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc;
+            rah       = ((DCI1_10MHz_TDD_t *)dci_pdu)->rah;
+            rv        = ((DCI1_10MHz_TDD_t *)dci_pdu)->rv;
+            TPC       = ((DCI1_10MHz_TDD_t *)dci_pdu)->TPC;
+            ndi       = ((DCI1_10MHz_TDD_t *)dci_pdu)->ndi;
+            harq_pid  = ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid;
+        } else {
+            mcs      = ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs;
+            rah      = ((DCI1_10MHz_FDD_t *)dci_pdu)->rah;
+            rballoc  = ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1_10MHz_FDD_t *)dci_pdu)->rv;
+            TPC      = ((DCI1_10MHz_FDD_t *)dci_pdu)->TPC;
+            ndi      = ((DCI1_10MHz_FDD_t *)dci_pdu)->ndi;
+            harq_pid = ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid;
+        }
+
+        break;
+
+    case 100:
+        if (frame_type == TDD) {
+            mcs       = ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs;
+            rballoc   = ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc;
+            rah       = ((DCI1_20MHz_TDD_t *)dci_pdu)->rah;
+            rv        = ((DCI1_20MHz_TDD_t *)dci_pdu)->rv;
+            TPC        = ((DCI1_20MHz_TDD_t *)dci_pdu)->TPC;
+            ndi       = ((DCI1_20MHz_TDD_t *)dci_pdu)->ndi;
+            harq_pid  = ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid;
+        } else {
+            mcs      = ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs;
+            rah      = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah;
+            rballoc  = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc;
+            rv       = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv;
+            TPC      = ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC;
+            ndi      = ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi;
+            harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid;
+        }
+
+        break;
+    }
+
+    pdci_info_extarcted->mcs1     = mcs;
+    pdci_info_extarcted->rah      = rah;
+    pdci_info_extarcted->rballoc  = rballoc;
+    pdci_info_extarcted->rv1      = rv;
+    pdci_info_extarcted->TPC      = TPC;
+    pdci_info_extarcted->ndi1     = ndi;
+    pdci_info_extarcted->harq_pid = harq_pid;
+
+}
+
+void extract_dci2_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
+{
+
+    uint32_t rballoc=0;
+    uint8_t rah=0;
+    uint8_t mcs1=0;
+    uint8_t mcs2=0;
+    uint8_t rv1=0;
+    uint8_t rv2=0;
+    uint8_t ndi1=0;
+    uint8_t ndi2=0;
+    uint8_t tbswap=0;
+    uint8_t tpmi=0;
+    uint8_t harq_pid=0;
+    uint8_t TPC=0;
+
+    switch (N_RB_DL) {
+
+    case 6:
+        if (nb_antenna_ports_eNB == 2) {
+            if (frame_type == TDD) {
+                rah       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2;
+            } else {
+                rah       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2;
+            }
+        } else if (nb_antenna_ports_eNB == 4) {
+            if (frame_type == TDD) {
+                rah       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi2;
+            } else {
+                rah       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2;
+            }
+        } else {
+            LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB);
+        }
+
+        break;
+
+    case 25:
+        if (nb_antenna_ports_eNB == 2) {
+            if (frame_type == TDD) {
+                rah       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2;
+            } else {
+                rah       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2;
+            }
+        } else if (nb_antenna_ports_eNB == 4) {
+            if (frame_type == TDD) {
+                rah       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2;
+            } else {
+                rah       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2;
+            }
+        } else {
+            LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB);
+        }
+
+        break;
+
+    case 50:
+        if (nb_antenna_ports_eNB == 2) {
+            if (frame_type == TDD) {
+                rah       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2;
+            } else {
+                rah       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2;
+            }
+        } else if (nb_antenna_ports_eNB == 4) {
+            if (frame_type == TDD) {
+                rah       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi2;
+            } else {
+                rah       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi2;
+            }
+        } else {
+            LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB);
+        }
+
+        break;
+
+    case 100:
+        if (nb_antenna_ports_eNB == 2) {
+            if (frame_type == TDD) {
+                rah       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2;
+            } else {
+                rah       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2;
+            }
+        } else if (nb_antenna_ports_eNB == 4) {
+            if (frame_type == TDD) {
+                rah       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi2;
+            } else {
+                rah       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah;
+                mcs1      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1;
+                mcs2      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2;
+                rballoc   = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc;
+                rv1       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1;
+                rv2       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2;
+                harq_pid  = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+                tbswap    = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+                tpmi      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
+                TPC       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->TPC;
+                ndi1      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi1;
+                ndi2      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi2;
+            }
+        } else {
+            LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB);
+        }
+
+        break;
+    }
+
+    pdci_info_extarcted->rah      = rah;
+    pdci_info_extarcted->mcs1     = mcs1;
+    pdci_info_extarcted->mcs2     = mcs2;
+    pdci_info_extarcted->rv1      = rv1;
+    pdci_info_extarcted->rv2      = rv2;
+    pdci_info_extarcted->harq_pid = harq_pid;
+    pdci_info_extarcted->rballoc  = rballoc;
+    pdci_info_extarcted->tb_swap  = tbswap;
+    pdci_info_extarcted->tpmi     = tpmi;
+    pdci_info_extarcted->TPC      = TPC;
+    pdci_info_extarcted->ndi1     = ndi1;
+    pdci_info_extarcted->ndi2     = ndi2;
+
+}
+
+void extract_dci2A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
+{
+
+    uint32_t rballoc=0;
+    uint8_t rah=0;
+    uint8_t mcs1=0;
+    uint8_t mcs2=0;
+    uint8_t rv1=0;
+    uint8_t rv2=0;
+    uint8_t ndi1=0;
+    uint8_t ndi2=0;
+    uint8_t tbswap=0;
+    uint8_t tpmi=0;
+    uint8_t harq_pid=0;
+    uint8_t TPC=0;
+
+    AssertFatal( (nb_antenna_ports_eNB == 2) || (nb_antenna_ports_eNB == 4), "unsupported nb_antenna_ports_eNB %d\n", nb_antenna_ports_eNB);
+    switch (N_RB_DL) {
+
+    case 6:
+      if (nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+          TPC       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->TPC;
+        } else {
+          mcs1      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+          TPC       = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->TPC;
+        }
+      } else if (nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
+          TPC       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->TPC;
+        } else {
+          mcs1      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
+          TPC       = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->TPC;
+        }
+      }
+
+      break;
+
+    case 25:
+      if (nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+          TPC       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->TPC;
+        } else {
+          mcs1      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+          TPC       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->TPC;
+        }
+      } else if (nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
+          TPC       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->TPC;
+        } else {
+          mcs1      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
+          TPC       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->TPC;
+        }
+      }
+      break;
+
+    case 50:
+      if (nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+          TPC       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->TPC;
+        } else {
+          mcs1      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+          TPC       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->TPC;
+        }
+      } else if (nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tpmi;
+          TPC       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->TPC;
+        } else {
+          mcs1      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
+          TPC       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->TPC;
+        }
+      }
+
+      break;
+
+    case 100:
+      if (nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap;
+          TPC       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->TPC;
+        } else {
+          mcs1      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
+          TPC       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->TPC;
+        }
+      } else if (nb_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tb_swap;
+          tpmi      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tpmi;
+          TPC       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->TPC;
+        } else {
+          mcs1      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv2;
+          ndi1      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi1;
+          ndi2      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi2;
+          harq_pid  = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->harq_pid;
+          tbswap    = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tb_swap;
+          tpmi    = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
+          TPC     = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->TPC;
+        }
+      }
+
+      break;
+    }
+
+    pdci_info_extarcted->mcs1     = mcs1;
+    pdci_info_extarcted->mcs2     = mcs2;
+    pdci_info_extarcted->rballoc  = rballoc;
+    pdci_info_extarcted->rah      = rah;
+    pdci_info_extarcted->rv1      = rv1;
+    pdci_info_extarcted->rv2      = rv2;
+    pdci_info_extarcted->ndi1     = ndi1;
+    pdci_info_extarcted->ndi2     = ndi2;
+    pdci_info_extarcted->harq_pid = harq_pid;
+    pdci_info_extarcted->tb_swap  = tbswap;
+    pdci_info_extarcted->TPC      = TPC;
+    pdci_info_extarcted->tpmi     = tpmi;
+}
+
+int check_dci_format1_1a_coherency(DCI_format_t dci_format,
+        uint8_t N_RB_DL,
+        uint16_t rnti,
+        uint16_t tc_rnti,
+        uint16_t si_rnti,
+        uint16_t ra_rnti,
+        uint16_t p_rnti,
+        uint32_t frame,
+        uint8_t  nr_tti_rx,
+        DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
+        NR_DL_UE_HARQ_t *pdlsch0_harq)
+{
+    uint8_t  harq_pid  = pdci_info_extarcted->harq_pid;
+    uint32_t rballoc   = pdci_info_extarcted->rballoc;
+    uint8_t  mcs1      = pdci_info_extarcted->mcs1;
+    uint8_t  TPC       = pdci_info_extarcted->TPC;
+    uint8_t  rah       = pdci_info_extarcted->rah;
+#ifdef DEBUG_DCI
+    uint8_t  rv1       = pdci_info_extarcted->rv1;
+    uint8_t  ndi1      = pdci_info_extarcted->ndi1;
+#endif
+
+    uint8_t  NPRB    = 0;
+    long long int RIV_max = 0;
+
+#ifdef DEBUG_DCI
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] AbsSubframe %d.%d dci_format %d\n", frame, nr_tti_rx, dci_format);
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] rnti       %x\n",  rnti);
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] harq_pid   %d\n", harq_pid);
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] rah        %d\n", rah);
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc    %x\n", rballoc);
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1       %d\n", mcs1);
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1        %d\n", rv1);
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1       %d\n", ndi1);
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC        %d\n", TPC);
+#endif
+
+
+    // I- check dci content minimum coherency
+    if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0)
+    {
+        return(0);
+    }
+
+    if(harq_pid>=8)
+    {
+        LOG_I(PHY,"bad harq id \n");
+        return(0);
+    }
+
+    if(dci_format == format1 && ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) )
+    {
+        LOG_I(PHY,"bad dci format \n");
+        return(0);
+    }
+
+
+    if( mcs1 > 28)
+    {
+        if(pdlsch0_harq->round == 0)
+        {
+            LOG_I(PHY,"bad dci mcs + round \n");
+            return(0);
+        }
+
+        if((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
+        {
+            LOG_I(PHY,"bad dci mcs + rnti  \n");
+            return(0);
+        }
+    }
+
+    if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
+    {
+        NPRB = (TPC&1) + 2;
+        switch (N_RB_DL) {
+        case 6:
+            RIV_max  = RIV_max6;
+            break;
+        case 25:
+            RIV_max  = RIV_max25;
+            break;
+        case 50:
+            RIV_max  = RIV_max50;
+            break;
+        case 100:
+            RIV_max  = RIV_max100;
+            break;
+        }
+    }
+    /*else
+    {
+        switch (N_RB_DL) {
+        case 6:
+            NPRB     = RIV2nb_rb_LUT6[rballoc];//NPRB;
+            if(rah)
+              RIV_max  = RIV_max6;
+            else
+              RIV_max  = 0x3F;
+            break;
+        case 25:
+            NPRB     = RIV2nb_rb_LUT25[rballoc];//NPRB;
+            if(rah)
+              RIV_max  = RIV_max25;
+            else
+              RIV_max  = 0x1FFF;
+            break;
+        case 50:
+            NPRB     = RIV2nb_rb_LUT50[rballoc];//NPRB;
+            if(rah)
+              RIV_max  = RIV_max50;
+            else
+              RIV_max  = 0x1FFFF;
+            break;
+        case 100:
+            NPRB     = RIV2nb_rb_LUT100[rballoc];//NPRB;
+            if(rah)
+              RIV_max  = RIV_max100;
+            else
+              RIV_max  =  0x1FFFFFF;
+            break;
+        }
+	}*/
+
+
+    if(dci_format == format1)
+    {
+        NPRB = conv_nprb(rah, rballoc, N_RB_DL);
+    }
+
+    /*
+    if(rballoc > RIV_max)
+    {
+        LOG_I(PHY,"bad dci rballoc rballoc %d  RIV_max %lld \n",rballoc, RIV_max);
+        // DCI false detection
+        return(0);
+    }
+    */
+
+    if(NPRB == 0)
+    {
+        // DCI false detection
+        LOG_I(PHY,"bad NPRB = 0 \n");
+        return(0);
+    }
+
+    // this a retransmission
+    if(pdlsch0_harq->round>0)
+    {
+        // compare old TBS to new TBS
+        if((mcs1<29) && (pdlsch0_harq->TBS != TBStable[get_I_TBS(mcs1)][NPRB-1]))
+        {
+            // this is an eNB issue
+            // retransmisison but old and new TBS are different !!!
+            // work around, consider it as a new transmission
+            LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n");
+            pdlsch0_harq->round = 0;
+            //return(0); // ?? to cross check
+        }
+    }
+
+    return(1);
+}
+
+int check_dci_format1c_coherency(uint8_t N_RB_DL,
+                                 DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
+                                 uint16_t rnti,
+                                 uint16_t si_rnti,
+                                 uint16_t ra_rnti,
+                                 uint16_t p_rnti,
+                                 NR_DL_UE_HARQ_t *pdlsch0_harq)
+{
+    uint32_t rballoc = pdci_info_extarcted->rballoc;
+
+    uint8_t  NPRB    = 0;
+    uint32_t RIV_max = 0;
+
+    // I- check dci content minimum coherency
+
+    if((rnti!=si_rnti) && (rnti!=p_rnti) && (rnti!=ra_rnti))
+      return(0);
+
+    switch (N_RB_DL) {
+    case 6:
+      NPRB     = RIV2nb_rb_LUT6[rballoc];//NPRB;
+      RIV_max  = RIV_max6;
+    break;
+    case 25:
+      NPRB     = RIV2nb_rb_LUT25[rballoc];//NPRB;
+      RIV_max  = RIV_max25;
+    break;
+    case 50:
+      NPRB     = RIV2nb_rb_LUT50[rballoc];//NPRB;
+      RIV_max  = RIV_max50;
+    break;
+    case 100:
+      NPRB     = RIV2nb_rb_LUT100[rballoc];//NPRB;
+      RIV_max  = RIV_max100;
+    break;
+    }
+
+   if(rballoc > RIV_max)
+   {
+      // DCI false detection
+      return(0);
+   }
+
+   if(NPRB == 0)
+   {
+      // DCI false detection
+      return(0);
+   }
+
+   return(1);
+}
+
+int check_dci_format2_2a_coherency(DCI_format_t dci_format,
+                                   uint8_t N_RB_DL,
+                                   DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
+                                   uint16_t rnti,
+                                   uint16_t si_rnti,
+                                   uint16_t ra_rnti,
+                                   uint16_t p_rnti,
+                                   NR_DL_UE_HARQ_t *pdlsch0_harq,
+                                   NR_DL_UE_HARQ_t *pdlsch1_harq)
+{
+    uint8_t  rah  = pdci_info_extarcted->rah;
+    uint8_t  mcs1 = pdci_info_extarcted->mcs1;
+    uint8_t  mcs2 = pdci_info_extarcted->mcs2;
+    uint8_t  rv1  = pdci_info_extarcted->rv1;
+    uint8_t  rv2  = pdci_info_extarcted->rv2;
+    uint8_t  harq_pid = pdci_info_extarcted->harq_pid;
+    uint32_t rballoc  = pdci_info_extarcted->rballoc;
+
+#ifdef DEBUG_DCI
+    uint8_t  ndi1     = pdci_info_extarcted->ndi1;
+    uint8_t  ndi2     = pdci_info_extarcted->ndi2;
+#endif
+
+    uint8_t  NPRB    = 0;
+    long long RIV_max = 0;
+
+#ifdef DEBUG_DCI
+    LOG_I(PHY, "extarcted dci - dci_format %d \n", dci_format);
+    LOG_I(PHY, "extarcted dci - rnti       %d \n", rnti);
+    LOG_I(PHY, "extarcted dci - rah        %d \n", rah);
+    LOG_I(PHY, "extarcted dci - mcs1       %d \n", mcs1);
+    LOG_I(PHY, "extarcted dci - mcs2       %d \n", mcs2);
+    LOG_I(PHY, "extarcted dci - rv1        %d \n", rv1);
+    LOG_I(PHY, "extarcted dci - rv2        %d \n", rv2);
+    //LOG_I(PHY, "extarcted dci - ndi1       %d \n", ndi1);
+    //LOG_I(PHY, "extarcted dci - ndi2       %d \n", ndi2);
+    LOG_I(PHY, "extarcted dci - rballoc    %x \n", rballoc);
+    LOG_I(PHY, "extarcted dci - harq pid   %d \n", harq_pid);
+    LOG_I(PHY, "extarcted dci - round0     %d \n", pdlsch0_harq->round);
+    LOG_I(PHY, "extarcted dci - round1     %d \n", pdlsch1_harq->round);
+#endif
+
+    // I- check dci content minimum coherency
+    if(harq_pid>=8)
+    {
+        LOG_I(PHY,"bad harq pid\n");
+      return(0);
+    }
+
+    if( (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) )
+    {
+        LOG_I(PHY,"bad rnti\n");
+        return(0);
+    }
+
+
+    if( mcs1 > 28)
+    {
+      if(pdlsch0_harq->round == 0)
+      {
+          LOG_I(PHY,"bad mcs1\n");
+        return(0);
+      }
+    }
+
+    if( mcs2 > 28)
+    {
+      if(pdlsch1_harq->round == 0)
+      {
+          LOG_I(PHY,"bad mcs2\n");
+          return(0);
+      }
+
+    }
+
+
+    if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0))
+    {
+      // DCI false detection
+        LOG_I(PHY,"bad rv1\n");
+      return(0);
+    }
+
+    if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0))
+    {
+      // DCI false detection
+        LOG_I(PHY,"bad rv2\n");
+      return(0);
+    }
+
+
+    switch (N_RB_DL) {
+    case 6:
+        if (rah == 0)
+        {
+            //RBG = 1;
+            RIV_max = 0x3F;
+        }
+        else
+        {
+            RIV_max  = RIV_max6;
+        }
+        break;
+    case 25:
+        if (rah == 0)
+        {
+            //RBG = 2;
+            RIV_max = 0x1FFF;
+        }
+        else
+        {
+            RIV_max  = RIV_max25;
+        }
+        break;
+    case 50:
+        if (rah == 0)
+        {
+            //RBG = 3;
+            RIV_max = 0x1FFFF;
+        }
+        else
+        {
+            RIV_max  = RIV_max50;
+        }
+        break;
+    case 100:
+        if (rah == 0)
+        {
+            //RBG = 4;
+            RIV_max  = 0x1FFFFFF;
+        }
+        else
+        {
+            RIV_max  = RIV_max100;
+        }
+        break;
+    }
+
+    NPRB = conv_nprb(rah,
+                     rballoc,
+                     N_RB_DL);
+
+
+
+   if( (rballoc > RIV_max) && (rah == 1) )
+   {
+      // DCI false detection
+       LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max);
+      return(0);
+   }
+
+   if(NPRB == 0)
+   {
+      // DCI false detection
+       LOG_I(PHY,"bad NPRB\n");
+      return(0);
+   }
+
+   return(1);
+}
+
+void compute_llr_offset(NR_DL_FRAME_PARMS *frame_parms,
+                        NR_UE_PDCCH *pdcch_vars,
+                        NR_UE_PDSCH *pdsch_vars,
+                        NR_DL_UE_HARQ_t *dlsch0_harq,
+                        uint8_t nb_rb_alloc,
+                        uint8_t nr_tti_rx)
+{
+    uint32_t pbch_pss_sss_re;
+    uint32_t crs_re;
+    uint32_t granted_re;
+    uint32_t data_re;
+    uint32_t llr_offset;
+    uint8_t symbol;
+    uint8_t symbol_mod;
+
+    pdsch_vars->llr_offset[pdcch_vars->num_pdcch_symbols] = 0;
+
+    //LOG_I(PHY,"compute_llr_offset:  nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm);
+
+    //dlsch0_harq->rb_alloc_even;
+    //dlsch0_harq->rb_alloc_odd;
+
+    for(symbol=pdcch_vars->num_pdcch_symbols; symbol<frame_parms->symbols_per_tti; symbol++)
+    {
+        symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
+        if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp))
+        {
+            if (frame_parms->mode1_flag==0)
+                crs_re = 4;
+            else
+                crs_re = 2;
+        }
+        else
+        {
+            crs_re = 0;
+        }
+
+        granted_re = nb_rb_alloc * (12-crs_re);
+        pbch_pss_sss_re = adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,nr_tti_rx,symbol);
+        pbch_pss_sss_re = (double)pbch_pss_sss_re * ((double)(12-crs_re)/12);
+        data_re = granted_re - pbch_pss_sss_re;
+        llr_offset = data_re * dlsch0_harq->Qm * 2;
+
+        pdsch_vars->llr_length[symbol]   = data_re;
+        if(symbol < (frame_parms->symbols_per_tti-1))
+          pdsch_vars->llr_offset[symbol+1] = pdsch_vars->llr_offset[symbol] + llr_offset;
+
+        //LOG_I(PHY,"Granted Re nr_tti_rx %d / symbol %d => %d (%d RBs)\n", nr_tti_rx, symbol_mod, granted_re,dlsch0_harq->nb_rb);
+        //LOG_I(PHY,"Pbch/PSS/SSS Re nr_tti_rx %d / symbol %d => %d \n", nr_tti_rx, symbol_mod, pbch_pss_sss_re);
+        //LOG_I(PHY,"CRS Re Per PRB nr_tti_rx %d / symbol %d => %d \n", nr_tti_rx, symbol_mod, crs_re);
+        //LOG_I(PHY,"Data Re nr_tti_rx %d / symbol %d => %d \n", nr_tti_rx, symbol_mod, data_re);
+
+
+
+        //LOG_I(PHY,"Data Re nr_tti_rx %d-symbol %d => llr length %d, llr offset %d \n", nr_tti_rx, symbol,
+        //      pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]);
+    }
+}
+void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
+                                    uint8_t N_RB_DL,
+                                    DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
+                                    NR_DL_FRAME_PARMS *frame_parms,
+                                    NR_UE_PDCCH *pdcch_vars,
+                                    NR_UE_PDSCH *pdsch_vars,
+                                    uint8_t  nr_tti_rx,
+                                    uint16_t rnti,
+									uint16_t tc_rnti,
+                                    uint16_t si_rnti,
+                                    uint16_t ra_rnti,
+                                    uint16_t p_rnti,
+                                    NR_DL_UE_HARQ_t *pdlsch0_harq,
+                                    NR_UE_DLSCH_t *pdlsch0)
+{
+
+    uint8_t  harq_pid  = pdci_info_extarcted->harq_pid;
+    uint8_t  vrb_type  = pdci_info_extarcted->vrb_type;
+    uint32_t rballoc   = pdci_info_extarcted->rballoc;
+    uint8_t  mcs1      = pdci_info_extarcted->mcs1;
+    uint8_t  rv1       = pdci_info_extarcted->rv1;
+    uint8_t  ndi1      = pdci_info_extarcted->ndi1;
+    uint8_t  TPC       = pdci_info_extarcted->TPC;
+    uint8_t  rah       = pdci_info_extarcted->rah;
+    uint8_t  dai       = pdci_info_extarcted->dai;
+
+    uint8_t  NPRB    = 0;
+    uint8_t  nb_rb_alloc = 0;
+
+    if(dci_format == format1A)
+    {
+        if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
+        {
+            NPRB = (TPC&1) + 2;
+            switch (N_RB_DL) {
+            case 6:
+                nb_rb_alloc     = RIV2nb_rb_LUT6[rballoc];//NPRB;
+                break;
+            case 25:
+                nb_rb_alloc     = RIV2nb_rb_LUT25[rballoc];//NPRB;
+                break;
+            case 50:
+                nb_rb_alloc     = RIV2nb_rb_LUT50[rballoc];//NPRB;
+                break;
+            case 100:
+                nb_rb_alloc     = RIV2nb_rb_LUT100[rballoc];//NPRB;
+                break;
+        }
+        }
+        else
+        {
+            switch (N_RB_DL) {
+            case 6:
+                NPRB     = RIV2nb_rb_LUT6[rballoc];//NPRB;
+                break;
+            case 25:
+                NPRB     = RIV2nb_rb_LUT25[rballoc];//NPRB;
+                break;
+            case 50:
+                NPRB     = RIV2nb_rb_LUT50[rballoc];//NPRB;
+                break;
+            case 100:
+                NPRB     = RIV2nb_rb_LUT100[rballoc];//NPRB;
+                break;
+            }
+            nb_rb_alloc = NPRB;
+        }
+    }
+    else // format1
+    {
+        NPRB = conv_nprb(rah, rballoc, N_RB_DL);
+        nb_rb_alloc = NPRB;
+    }
+
+    pdlsch0->current_harq_pid = harq_pid;
+    pdlsch0->active           = 1;
+    pdlsch0->rnti             = rnti;
+    if(dci_format == format1A)
+        pdlsch0->harq_ack[nr_tti_rx].vDAI_DL = dai+1;
+
+    if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
+    {
+        pdlsch0_harq->round    = 0;
+        pdlsch0_harq->status   = ACTIVE;
+    }
+    else //CRNTI
+    {
+    	if (rnti == tc_rnti) {
+			//fix for standalone Contention Resolution Id
+			pdlsch0_harq->DCINdi = (uint8_t)-1;
+			 LOG_D(PHY,"UE (%x/%d): Format1A DCI: C-RNTI is temporary. Set NDI = %d and to be ignored\n",
+				 rnti,harq_pid,pdlsch0_harq->DCINdi);
+    	}
+
+        // NDI has been toggled or this is the first transmission
+        if ((ndi1!=pdlsch0_harq->DCINdi) || (pdlsch0_harq->first_tx==1))
+        {
+            pdlsch0_harq->round    = 0;
+            pdlsch0_harq->first_tx = 0;
+            pdlsch0_harq->status   = ACTIVE;
+
+        }else if (rv1  != 0 )
+            //NDI has not been toggled but rv was increased by eNB: retransmission
+        {
+            if (pdlsch0_harq->status == SCH_IDLE)
+                //packet was actually decoded in previous transmission (ACK was missed by eNB)
+                //However, the round is not a good check as it might have been decoded in a retransmission prior to this one.
+            {
+                LOG_D(PHY,"skip pdsch decoding and report ack\n");
+                // skip pdsch decoding and report ack
+                //pdlsch0_harq->status   = SCH_IDLE;
+                pdlsch0->active       = 0;
+                pdlsch0->harq_ack[nr_tti_rx].ack = 1;
+                pdlsch0->harq_ack[nr_tti_rx].harq_id = harq_pid;
+                pdlsch0->harq_ack[nr_tti_rx].send_harq_status = 1;
+
+                //pdlsch0_harq->first_tx = 0;
+            }
+            else  //normal retransmission
+            {
+                // nothing special to do
+            }
+        }
+        else
+        {
+            pdlsch0_harq->status   = ACTIVE;
+        }
+    }
+
+    pdlsch0_harq->DCINdi = ndi1;
+    pdlsch0_harq->mcs    = mcs1;
+    pdlsch0_harq->rvidx  = rv1;
+    pdlsch0_harq->nb_rb  = NPRB;
+
+    pdlsch0_harq->codeword     = 0;
+    pdlsch0_harq->Nl           = 1;
+    pdlsch0_harq->mimo_mode    = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI;
+    pdlsch0_harq->dl_power_off = 1; //no power offset
+    pdlsch0_harq->delta_PUCCH  = delta_PUCCH_lut[TPC &3];
+
+    // compute resource allocation
+    if(dci_format == format1A)
+    {
+        switch (N_RB_DL) {
+        case 6:
+            if (vrb_type == LOCALIZED) {
+                pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT6[rballoc];
+                pdlsch0_harq->rb_alloc_odd[0]  = localRIV2alloc_LUT6[rballoc];
+            }
+            else {
+                pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc];
+                pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_odd_LUT6[rballoc];
+            }
+            break;
+
+        case 25:
+            if (vrb_type == LOCALIZED) {
+                pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT25[rballoc];
+                pdlsch0_harq->rb_alloc_odd[0]  = localRIV2alloc_LUT25[rballoc];
+            }
+            else {
+                pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc];
+                pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_odd_LUT25[rballoc];
+            }
+            break;
+
+        case 50:
+            if (vrb_type == LOCALIZED) {
+                pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc];
+                pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc];
+                pdlsch0_harq->rb_alloc_odd[0]  = localRIV2alloc_LUT50_0[rballoc];
+                pdlsch0_harq->rb_alloc_odd[1]  = localRIV2alloc_LUT50_1[rballoc];
+                //      printf("rballoc: %08x.%08x\n",pdlsch0_harq->rb_alloc_even[0],pdlsch0_harq->rb_alloc_even[1]);
+            } else { // DISTRIBUTED
+                if ((rballoc&(1<<10)) == 0) {
+                    rballoc = rballoc&(~(1<<10));
+                    pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc];
+                    pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap0_odd_LUT50_0[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap0_odd_LUT50_1[rballoc];
+                }
+                else {
+                    rballoc = rballoc&(~(1<<10));
+                    pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc];
+                    pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap0_odd_LUT50_0[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap0_odd_LUT50_1[rballoc];
+                }
+            }
+            break;
+
+        case 100:
+            if (vrb_type == LOCALIZED) {
+                pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT100_0[rballoc];
+                pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT100_1[rballoc];
+                pdlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc];
+                pdlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc];
+                pdlsch0_harq->rb_alloc_odd[0]  = localRIV2alloc_LUT100_0[rballoc];
+                pdlsch0_harq->rb_alloc_odd[1]  = localRIV2alloc_LUT100_1[rballoc];
+                pdlsch0_harq->rb_alloc_odd[2]  = localRIV2alloc_LUT100_2[rballoc];
+                pdlsch0_harq->rb_alloc_odd[3]  = localRIV2alloc_LUT100_3[rballoc];
+            } else {
+                if ((rballoc&(1<<10)) == 0) { //Gap 1
+                    rballoc = rballoc&(~(1<<12));
+                    pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc];
+                    pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc];
+                    pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc];
+                    pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap0_odd_LUT100_0[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap0_odd_LUT100_1[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[2]  = distRIV2alloc_gap0_odd_LUT100_2[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[3]  = distRIV2alloc_gap0_odd_LUT100_3[rballoc];
+                }
+                else { //Gap 2
+                    rballoc = rballoc&(~(1<<12));
+                    pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc];
+                    pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc];
+                    pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc];
+                    pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap1_odd_LUT100_0[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap1_odd_LUT100_1[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[2]  = distRIV2alloc_gap1_odd_LUT100_2[rballoc];
+                    pdlsch0_harq->rb_alloc_odd[3]  = distRIV2alloc_gap1_odd_LUT100_3[rballoc];
+                }
+            }
+            break;
+        }
+    }
+    else // format1
+    {
+        conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,pdlsch0_harq->rb_alloc_even);
+        pdlsch0_harq->rb_alloc_odd[0]= pdlsch0_harq->rb_alloc_even[0];
+        pdlsch0_harq->rb_alloc_odd[1]= pdlsch0_harq->rb_alloc_even[1];
+        pdlsch0_harq->rb_alloc_odd[2]= pdlsch0_harq->rb_alloc_even[2];
+        pdlsch0_harq->rb_alloc_odd[3]= pdlsch0_harq->rb_alloc_even[3];
+    }
+    if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
+    {
+        pdlsch0_harq->TBS = TBStable[mcs1][NPRB-1];
+        pdlsch0_harq->Qm  = 2;
+    }
+    else
+    {
+        if(mcs1 < 29)
+        {
+            pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB-1];
+            pdlsch0_harq->Qm  = get_Qm(mcs1);
+        }
+    }
+
+    compute_llr_offset(frame_parms,
+                       pdcch_vars,
+                       pdsch_vars,
+                       pdlsch0_harq,
+                       nb_rb_alloc,
+                       nr_tti_rx);
+}
+
+void prepare_dl_decoding_format1C(uint8_t N_RB_DL,
+                                  DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
+                                  NR_DL_FRAME_PARMS *frame_parms,
+                                  NR_UE_PDCCH *pdcch_vars,
+                                  NR_UE_PDSCH *pdsch_vars,
+                                  uint32_t rnti,
+                                  uint32_t si_rnti,
+                                  uint32_t ra_rnti,
+                                  uint32_t p_rnti,
+                                  uint32_t frame,
+                                  uint8_t  nr_tti_rx,
+                                  NR_DL_UE_HARQ_t *pdlsch0_harq,
+                                  NR_UE_DLSCH_t *pdlsch0)
+{
+
+    uint8_t  harq_pid  = pdci_info_extarcted->harq_pid;
+    uint32_t rballoc   = pdci_info_extarcted->rballoc;
+    uint8_t  mcs1      = pdci_info_extarcted->mcs1;
+    uint8_t  Ngap      = pdci_info_extarcted->Ngap;
+
+      pdlsch0_harq->round     = 0;
+      pdlsch0_harq->first_tx  = 1;
+      pdlsch0_harq->vrb_type  = DISTRIBUTED;
+
+      if (rnti==si_rnti) { // rule from Section 5.3.1 of 36.321
+        if (((frame&1) == 0) && (nr_tti_rx == 5))
+           pdlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3;  // SIB1
+        else
+           pdlsch0_harq->rvidx = (((3*(nr_tti_rx&3))+1)>>1)&3;  // other SIBs
+      }
+      else if ((rnti==p_rnti) || (rnti==ra_rnti)) { // Section 7.1.7.3
+        pdlsch0_harq->rvidx = 0;
+      }
+
+
+      pdlsch0_harq->Nl           = 1;
+      pdlsch0_harq->mimo_mode    = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI;
+      pdlsch0_harq->dl_power_off = 1; //no power offset
+
+      pdlsch0_harq->codeword = 0;
+      pdlsch0_harq->mcs      = mcs1;
+      pdlsch0_harq->TBS      = TBStable1C[mcs1];
+      pdlsch0_harq->Qm       = 2;
+
+
+      pdlsch0->current_harq_pid = harq_pid;
+      pdlsch0->active = 1;
+      pdlsch0->rnti   = rnti;
+
+    switch (N_RB_DL) {
+    case 6:
+        pdlsch0_harq->nb_rb            = RIV2nb_rb_LUT6[rballoc];
+        pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc];
+        pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_odd_LUT6[rballoc];
+
+        break;
+
+    case 25:
+        pdlsch0_harq->nb_rb            = RIV2nb_rb_LUT25[rballoc];
+        pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc];
+        pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_odd_LUT25[rballoc];
+        break;
+
+    case 50:
+        pdlsch0_harq->nb_rb            = RIV2nb_rb_LUT50[rballoc];
+        if (Ngap == 0) {
+            pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc];
+            pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap0_odd_LUT50_0[rballoc];
+            pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc];
+            pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap0_odd_LUT50_1[rballoc];
+        }
+        else {
+            pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc];
+            pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap1_odd_LUT50_0[rballoc];
+            pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc];
+            pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap1_odd_LUT50_1[rballoc];
+        }
+        break;
+
+    case 100:
+        pdlsch0_harq->nb_rb       = RIV2nb_rb_LUT100[rballoc];
+        if (Ngap==0) {
+            pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc];
+            pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap0_odd_LUT100_0[rballoc];
+            pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc];
+            pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap0_odd_LUT100_1[rballoc];
+            pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc];
+            pdlsch0_harq->rb_alloc_odd[2]  = distRIV2alloc_gap0_odd_LUT100_2[rballoc];
+            pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc];
+            pdlsch0_harq->rb_alloc_odd[3]  = distRIV2alloc_gap0_odd_LUT100_3[rballoc];
+        }
+        else {
+            pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc];
+            pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap1_odd_LUT100_0[rballoc];
+            pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc];
+            pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap1_odd_LUT100_1[rballoc];
+            pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc];
+            pdlsch0_harq->rb_alloc_odd[2]  = distRIV2alloc_gap1_odd_LUT100_2[rballoc];
+            pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc];
+            pdlsch0_harq->rb_alloc_odd[3]  = distRIV2alloc_gap1_odd_LUT100_3[rballoc];
+        }
+        break;
+
+    default:
+        AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL);
+        break;
+    }
+
+    compute_llr_offset(frame_parms,
+                       pdcch_vars,
+                       pdsch_vars,
+                       pdlsch0_harq,
+                       pdlsch0_harq->nb_rb,
+                       nr_tti_rx);
+
+}
+
+void compute_precoding_info_2cw(uint8_t tpmi, uint8_t tbswap, uint16_t pmi_alloc, NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq)
+{
+
+switch (tpmi) {
+          case 0:
+            dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
+            dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
+            dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,0, 1);
+            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,0, 1);
+          break;
+          case 1:
+            dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
+            dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
+            dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1, 1);
+            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,1, 1);
+          break;
+          case 2: // PUSCH precoding
+            dlsch0_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
+            dlsch1_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
+            if (tbswap==0){
+              dlsch0_harq->pmi_alloc   = pmi_alloc;
+              dlsch1_harq->pmi_alloc   = pmi_alloc^0x1555;
+            } else {
+                dlsch1_harq->pmi_alloc   = pmi_alloc;
+                dlsch0_harq->pmi_alloc   = pmi_alloc^0x1555;
+            }
+#ifdef DEBUG_HARQ
+              printf ("\n \n compute_precoding_info_2cw pmi_alloc_new = %d\n", dlsch0_harq->pmi_alloc);
+  #endif
+          break;
+          default:
+          break;
+        }
+}
+
+void compute_precoding_info_1cw(uint8_t tpmi, uint16_t pmi_alloc, NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch_harq)
+{
+
+switch (tpmi) {
+            case 0 :
+              dlsch_harq->mimo_mode   = ALAMOUTI;
+            break;
+            case 1:
+              dlsch_harq->mimo_mode   = UNIFORM_PRECODING11;
+              dlsch_harq->pmi_alloc   = pmi_extend(frame_parms,0, 0);
+            break;
+            case 2:
+              dlsch_harq->mimo_mode   = UNIFORM_PRECODING1m1;
+              dlsch_harq->pmi_alloc   = pmi_extend(frame_parms,1, 0);
+            break;
+            case 3:
+              dlsch_harq->mimo_mode   = UNIFORM_PRECODING1j;
+              dlsch_harq->pmi_alloc   = pmi_extend(frame_parms,2, 0);
+            break;
+            case 4:
+              dlsch_harq->mimo_mode   = UNIFORM_PRECODING1mj;
+              dlsch_harq->pmi_alloc   = pmi_extend(frame_parms,3, 0);
+            break;
+            case 5:
+              dlsch_harq->mimo_mode   = PUSCH_PRECODING0;
+              dlsch_harq->pmi_alloc   = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0);
+            break;
+            case 6:
+              dlsch_harq->mimo_mode   = PUSCH_PRECODING1;
+              dlsch_harq->pmi_alloc   = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1);
+            break;
+            }
+  #ifdef DEBUG_HARQ
+              printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d with tpmi %d\n", dlsch_harq->pmi_alloc, tpmi);
+  #endif
+            }
+
+void compute_precoding_info_format2A(uint8_t tpmi,
+                                     uint8_t nb_antenna_ports_eNB,
+                                     uint8_t tb0_active,
+                                     uint8_t tb1_active,
+                                     NR_DL_UE_HARQ_t *dlsch0_harq,
+                                     NR_DL_UE_HARQ_t *dlsch1_harq)
+{
+
+    dlsch0_harq->dl_power_off = 0;
+    dlsch1_harq->dl_power_off = 0;
+
+    if (nb_antenna_ports_eNB == 2) {
+        if ((tb0_active==1) && (tb1_active==1)) {
+          dlsch0_harq->mimo_mode = LARGE_CDD;
+          dlsch1_harq->mimo_mode = LARGE_CDD;
+          dlsch0_harq->dl_power_off = 1;
+          dlsch1_harq->dl_power_off = 1;
+        } else {
+          dlsch0_harq->mimo_mode   = ALAMOUTI;
+          dlsch1_harq->mimo_mode   = ALAMOUTI;
+        }
+      } else if (nb_antenna_ports_eNB == 4) { // 4 antenna case
+        if ((tb0_active==1) && (tb1_active==1)) {
+          switch (tpmi) {
+          case 0: // one layer per transport block
+            dlsch0_harq->mimo_mode   = LARGE_CDD;
+            dlsch1_harq->mimo_mode   = LARGE_CDD;
+            dlsch0_harq->dl_power_off = 1;
+            dlsch1_harq->dl_power_off = 1;
+            break;
+
+          case 1: // one-layers on TB 0, two on TB 1
+            dlsch0_harq->mimo_mode   = LARGE_CDD;
+            dlsch1_harq->mimo_mode   = LARGE_CDD;
+            dlsch1_harq->Nl          = 2;
+            dlsch0_harq->dl_power_off = 1;
+            dlsch1_harq->dl_power_off = 1;
+            break;
+
+          case 2: // two-layers on TB 0, two on TB 1
+            dlsch0_harq->mimo_mode   = LARGE_CDD;
+            dlsch1_harq->mimo_mode   = LARGE_CDD;
+            dlsch0_harq->Nl          = 2;
+            dlsch0_harq->dl_power_off = 1;
+            dlsch1_harq->dl_power_off = 1;
+            break;
+
+          case 3: //
+            LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n");
+            break;
+          }
+        } else if (tb0_active == 1) {
+          switch (tpmi) {
+          case 0: // one layer per transport block
+            dlsch0_harq->mimo_mode   = ALAMOUTI;
+            dlsch1_harq->mimo_mode   = ALAMOUTI;
+            break;
+
+          case 1: // two-layers on TB 0
+            dlsch0_harq->mimo_mode   = LARGE_CDD;
+            dlsch0_harq->Nl          = 2;
+            dlsch0_harq->dl_power_off = 1;
+            break;
+
+          case 2: // two-layers on TB 0, two on TB 1
+          case 3: //
+            LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi);
+            break;
+          }
+        } else if (tb1_active == 1) {
+          switch (tpmi) {
+          case 0: // one layer per transport block
+            dlsch0_harq->mimo_mode   = ALAMOUTI;
+            dlsch1_harq->mimo_mode   = ALAMOUTI;
+            break;
+
+          case 1: // two-layers on TB 0
+            dlsch1_harq->mimo_mode   = LARGE_CDD;
+            dlsch1_harq->Nl          = 2;
+            dlsch0_harq->dl_power_off = 1;
+            break;
+
+          case 2: // two-layers on TB 0, two on TB 1
+          case 3: //
+            LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi);
+            break;
+          }
+        }
+      }
+      //    printf("Format 2A: NPRB=%d (rballoc %x,mcs1 %d, mcs2 %d, frame_type %d N_RB_DL %d,active %d/%d)\n",NPRB,rballoc,mcs1,mcs2,frame_parms->frame_type,frame_parms->N_RB_DL,dlsch0->active,dlsch1->active);
+      //printf("UE (%x/%d): nr_tti_rx %d Format2A DCI: ndi1 %d, old_ndi1 %d, ndi2 %d, old_ndi2 %d (first tx1 %d, first tx2 %d) harq_status1 %d, harq_status2 %d\n",dlsch0->rnti,harq_pid,nr_tti_rx,ndi,dlsch0_harq->DCINdi,
+      //    dlsch0_harq->first_tx,dlsch1_harq->first_tx,dlsch0_harq->status,dlsch1_harq->status);
+      //printf("TBS0 %d, TBS1 %d\n",dlsch0_harq->TBS,dlsch1_harq->TBS);
+
+}
+
+void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
+                                    DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
+                                    NR_DL_FRAME_PARMS *frame_parms,
+                                    NR_UE_PDCCH *pdcch_vars,
+                                    NR_UE_PDSCH *pdsch_vars,
+                                    uint16_t rnti,
+                                    uint8_t nr_tti_rx,
+                                    NR_DL_UE_HARQ_t *dlsch0_harq,
+                                    NR_DL_UE_HARQ_t *dlsch1_harq,
+                                    NR_UE_DLSCH_t *pdlsch0,
+                                    NR_UE_DLSCH_t *pdlsch1)
+{
+
+    uint8_t  rah  = pdci_info_extarcted->rah;
+    uint8_t  mcs1 = pdci_info_extarcted->mcs1;
+    uint8_t  mcs2 = pdci_info_extarcted->mcs2;
+    uint8_t  rv1  = pdci_info_extarcted->rv1;
+    uint8_t  rv2  = pdci_info_extarcted->rv2;
+    uint8_t  harq_pid = pdci_info_extarcted->harq_pid;
+    uint32_t rballoc  = pdci_info_extarcted->rballoc;
+    uint8_t  tbswap   = pdci_info_extarcted->tb_swap;
+    uint8_t  tpmi     = pdci_info_extarcted->tpmi;
+    uint8_t  TPC      = pdci_info_extarcted->TPC;
+    uint8_t  ndi1     = pdci_info_extarcted->ndi1;
+    uint8_t  ndi2     = pdci_info_extarcted->ndi2;
+
+    uint8_t TB0_active = 1;
+    uint8_t TB1_active = 1;
+
+   // printf("inside prepare pdlsch1->pmi_alloc %d \n",pdlsch1->pmi_alloc);
+
+
+      if ((rv1 == 1) && (mcs1 == 0)) {
+        TB0_active=0;
+      }
+      if ((rv2 == 1) && (mcs2 == 0)) {
+        TB1_active=0;
+      }
+
+#ifdef DEBUG_HARQ
+      printf("[DCI UE]: TB0 status %d , TB1 status %d\n", TB0_active, TB1_active);
+#endif
+
+        dlsch0_harq->mcs      = mcs1;
+        dlsch1_harq->mcs      = mcs2;
+        dlsch0_harq->rvidx    = rv1;
+        dlsch1_harq->rvidx    = rv2;
+        dlsch0_harq->DCINdi   = ndi1;
+        dlsch1_harq->DCINdi   = ndi2;
+
+        dlsch0_harq->codeword = 0;
+        dlsch1_harq->codeword = 1;
+        dlsch0_harq->Nl       = 1;
+        dlsch1_harq->Nl       = 1;
+        dlsch0_harq->delta_PUCCH  = delta_PUCCH_lut[TPC&3];
+        dlsch1_harq->delta_PUCCH  = delta_PUCCH_lut[TPC&3];
+        dlsch0_harq->dl_power_off = 1;
+        dlsch1_harq->dl_power_off = 1;
+
+        pdlsch0->current_harq_pid = harq_pid;
+        pdlsch0->harq_ack[nr_tti_rx].harq_id     = harq_pid;
+        pdlsch1->current_harq_pid = harq_pid;
+        pdlsch1->harq_ack[nr_tti_rx].harq_id     = harq_pid;
+
+        // assume two CW are active
+        dlsch0_harq->status   = ACTIVE;
+        dlsch1_harq->status   = ACTIVE;
+        pdlsch0->active = 1;
+        pdlsch1->active = 1;
+        pdlsch0->rnti = rnti;
+        pdlsch1->rnti = rnti;
+
+
+      if (TB0_active && TB1_active && tbswap==1) {
+        dlsch0_harq->codeword = 1;
+        dlsch1_harq->codeword = 0;
+      }
+
+
+      if (!TB0_active && TB1_active){
+        dlsch1_harq->codeword = 0;
+      }
+
+      if (TB0_active && !TB1_active){
+        dlsch0_harq->codeword = 0;
+      }
+
+
+      if (TB0_active==0) {
+        dlsch0_harq->status = SCH_IDLE;
+        pdlsch0->active     = 0;
+  #ifdef DEBUG_HARQ
+        printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n");
+  #endif
+      }
+
+      if (TB1_active==0) {
+        dlsch1_harq->status = SCH_IDLE;
+        pdlsch1->active     = 0;
+      }
+
+#ifdef DEBUG_HARQ
+      printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
+#endif
+
+      // compute resource allocation
+      if (TB0_active == 1){
+
+        dlsch0_harq->nb_rb = conv_nprb(rah,
+                                       rballoc,
+                                       frame_parms->N_RB_DL);
+        conv_rballoc(rah,
+                     rballoc,
+                     frame_parms->N_RB_DL,
+                     dlsch0_harq->rb_alloc_even);
+
+        dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0];
+        dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1];
+        dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2];
+        dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3];
+
+        if (TB1_active == 1){
+          dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0];
+          dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1];
+          dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2];
+          dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3];
+          dlsch1_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_odd[0];
+          dlsch1_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_odd[1];
+          dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2];
+          dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3];
+
+          dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
+
+          //dlsch0_harq->Nl       = 1;
+          //dlsch1_harq->Nl       = 1;
+        }
+      } else if ((TB0_active == 0) && (TB1_active == 1)){
+
+          conv_rballoc(rah,
+                       rballoc,
+                       frame_parms->N_RB_DL,
+                       dlsch1_harq->rb_alloc_even);
+
+          dlsch1_harq->rb_alloc_odd[0]= dlsch1_harq->rb_alloc_even[0];
+          dlsch1_harq->rb_alloc_odd[1]= dlsch1_harq->rb_alloc_even[1];
+          dlsch1_harq->rb_alloc_odd[2]= dlsch1_harq->rb_alloc_even[2];
+          dlsch1_harq->rb_alloc_odd[3]= dlsch1_harq->rb_alloc_even[3];
+          dlsch1_harq->nb_rb = conv_nprb(rah,
+                                         rballoc,
+                                         frame_parms->N_RB_DL);
+        }
+
+
+      // compute precoding matrix + mimo mode
+      if(dci_format == format2)
+      {
+      if ((TB0_active) && (TB1_active)){  //two CW active
+        compute_precoding_info_2cw(tpmi, tbswap, pdlsch0->pmi_alloc,frame_parms, dlsch0_harq, dlsch1_harq);
+
+   //   printf("[DCI UE 1]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
+      } else if ((TB0_active) && (!TB1_active))  { // only CW 0 active
+        compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch0_harq);
+      } else {
+        compute_precoding_info_1cw(tpmi, pdlsch1->pmi_alloc, frame_parms, dlsch1_harq);
+       // printf("I am doing compute_precoding_info_1cw with tpmi %d \n", tpmi);
+      }
+      //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode);
+      if ((frame_parms->mode1_flag == 1) && (TB0_active))
+        dlsch0_harq->mimo_mode   = SISO;
+      }
+      else
+      {
+        compute_precoding_info_format2A( tpmi,
+                                      frame_parms->nb_antenna_ports_eNB,
+                                      TB0_active,
+                                      TB1_active,
+                                      dlsch0_harq,
+                                      dlsch1_harq);
+      }
+  //    printf("[DCI UE 2]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
+      // reset round + compute Qm
+      if (TB0_active) {
+       // printf("TB0 ndi1 =%d, dlsch0_harq->DCINdi =%d, dlsch0_harq->first_tx = %d\n", ndi1, dlsch0_harq->DCINdi, dlsch0_harq->first_tx);
+        if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1))  {
+          dlsch0_harq->round = 0;
+           dlsch0_harq->status = ACTIVE;
+           dlsch0_harq->DCINdi = ndi1;
+
+          //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n",
+          //           subframe,harq_pid,dlsch0_harq->round);
+          if ( dlsch0_harq->first_tx==1) {
+            LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n");
+            dlsch0_harq->first_tx = 0;
+          }
+        }
+	/*else if (rv1  != 0 )
+	  //NDI has not been toggled but rv was increased by eNB: retransmission
+	  {
+	    if(dlsch0_harq->status == SCH_IDLE) {
+            // skip pdsch decoding and report ack
+	      //dlsch0_harq->status   = SCH_IDLE;
+            pdlsch0->active       = 0;
+            pdlsch0->harq_ack[subframe].ack = 1;
+            pdlsch0->harq_ack[subframe].harq_id = harq_pid;
+            pdlsch0->harq_ack[subframe].send_harq_status = 1;
+	    }*/
+
+        // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
+        // PDCCH for the same trasport block using Imcs in [0 .. 28]
+        if(dlsch0_harq->mcs <= 28)
+        {
+            dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+            LOG_D(PHY,"[UE] DLSCH: New TBS CW0 nr_tti_rx %d (pid %d, round %d) TBS %d \n",
+                       nr_tti_rx,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS);
+        }
+        else
+        {
+            LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW0 nr_tti_rx %d (pid %d, round %d) TBS %d \n",
+                       nr_tti_rx,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS);
+        }
+        //if(dlsch0_harq->Nl == 2)
+        //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
+        if (mcs1 <= 28)
+            dlsch0_harq->Qm = get_Qm(mcs1);
+        else if (mcs1<=31)
+            dlsch0_harq->Qm = (mcs1-28)<<1;
+      }
+
+   //   printf("[DCI UE 3]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
+
+      if (TB1_active) {
+       // printf("TB1 ndi2 =%d, dlsch1_harq->DCINdi =%d, dlsch1_harq->first_tx = %d\n", ndi2, dlsch1_harq->DCINdi, dlsch1_harq->first_tx);
+        if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) {
+          dlsch1_harq->round = 0;
+          dlsch1_harq->status = ACTIVE;
+          dlsch1_harq->DCINdi = ndi2;
+          //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n",
+          //           subframe,harq_pid,dlsch0_harq->round);
+          if (dlsch1_harq->first_tx==1) {
+            LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n");
+            dlsch1_harq->first_tx = 0;
+          }
+        }
+	/*else if (rv1  != 0 )
+	//NDI has not been toggled but rv was increased by eNB: retransmission
+	  {
+	    if(dlsch1_harq->status == SCH_IDLE) {
+            // skip pdsch decoding and report ack
+	      //dlsch1_harq->status   = SCH_IDLE;
+            pdlsch1->active       = 0;
+            pdlsch1->harq_ack[subframe].ack = 1;
+            pdlsch1->harq_ack[subframe].harq_id = harq_pid;
+            pdlsch1->harq_ack[subframe].send_harq_status = 1;
+         }
+	  }*/
+
+        // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
+        // PDCCH for the same trasport block using Imcs in [0 .. 28]
+        if(dlsch1_harq->mcs <= 28)
+        {
+            dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
+            LOG_D(PHY,"[UE] DLSCH: New TBS CW1 nr_tti_rx %d (pid %d, round %d) TBS %d \n",
+                       nr_tti_rx,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS);
+        }
+        else
+        {
+            LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW1 nr_tti_rx %d (pid %d, round %d) TBS %d \n",
+                       nr_tti_rx,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS);
+        }
+        if (mcs2 <= 28)
+            dlsch1_harq->Qm = get_Qm(mcs2);
+        else if (mcs1<=31)
+            dlsch1_harq->Qm = (mcs2-28)<<1;
+      }
+
+
+      compute_llr_offset(frame_parms,
+                         pdcch_vars,
+                         pdsch_vars,
+                         dlsch0_harq,
+                         dlsch0_harq->nb_rb,
+                         nr_tti_rx);
+
+
+ /* #ifdef DEBUG_HARQ
+      printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
+      printf("[DCI UE]: TB0_active %d , TB1_active %d\n", TB0_active, TB1_active);
+      if (dlsch0 != NULL && dlsch1 != NULL)
+        printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status);
+      else if (dlsch0 == NULL && dlsch1 != NULL)
+        printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status);
+      else if (dlsch0 != NULL && dlsch1 == NULL)
+        printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status);
+  #endif*/
+}
+#endif //(0)
+
+#ifdef NR_PDCCH_DCI_TOOLS
+int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue,
+        uint8_t eNB_id,
+        int frame,
+        uint8_t nr_tti_rx,
+        void *dci_pdu,
+        uint16_t rnti,
+        NR_DCI_format_t dci_format,
+        NR_UE_PDCCH *pdcch_vars,
+        NR_UE_PDSCH *pdsch_vars,
+        NR_UE_DLSCH_t **dlsch,
+        NR_UE_ULSCH_t *ulsch,
+        NR_DL_FRAME_PARMS *frame_parms,
+        PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+        uint16_t si_rnti,
+        uint16_t ra_rnti,
+        uint16_t p_rnti,
+        uint8_t beamforming_mode,
+        uint16_t tc_rnti,
+        uint8_t dci_length,
+        uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS],
+        uint16_t n_RB_ULBWP,
+        uint16_t n_RB_DLBWP)
+{
+  /*
+   * Note only format0_0 and format1_0 are implemented
+   */
+
+  uint8_t harq_pid=0;
+  uint8_t frame_type=frame_parms->frame_type;
+  uint8_t tpmi=0;
+  NR_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
+  NR_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
+  NR_UE_ULSCH_t *ulsch0=NULL,*ulsch1=NULL;
+  NR_DCI_INFO_EXTRACTED_t nr_dci_info_extracted;
+  uint8_t status=0,left_shift=0;
+  uint64_t pdu_bitmap = 0xFFFFFFFFFFFFFFFF;
+  pdu_bitmap = (pdu_bitmap << (64 - dci_length)) >> (64 - dci_length); // this variable will help to remove the bits of other fields when left-switching
+
+  dlsch0 = dlsch[0];
+  dlsch0->active = 0;
+  if (dci_fields_sizes[HARQ_PROCESS_NUMBER] != 0) { // 25 HARQ_PROCESS_NUMBER (25 is the position in dci_fields_sizes array for field HARQ_PROCESS_NUMBER)
+    for (int i=0; i<=HARQ_PROCESS_NUMBER; i++) left_shift = left_shift + dci_fields_sizes[i];
+    nr_dci_info_extracted.harq_process_number = (uint8_t)(((((*(uint64_t *)dci_pdu)  << (left_shift - dci_fields_sizes[HARQ_PROCESS_NUMBER]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[HARQ_PROCESS_NUMBER]));
+    left_shift = 0;
+    #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+      printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> nr_dci_info_extracted->harq_process_number=%x\n",nr_dci_info_extracted.harq_process_number);
+    #endif
+  }
+  dlsch0_harq   = dlsch[0]->harq_processes[nr_dci_info_extracted.harq_process_number];
+  ulsch0 = ulsch;
+/*  printf("nr_dci_info_extracted.harq_process_number = %d\n",nr_dci_info_extracted.harq_process_number);
+  printf("dlsch0 = %d\n",dlsch0);
+  printf("dlsch0_harq = %d\n",dlsch0_harq);*/
+
+  if (!dlsch[0]) return -1;
+  if (!ulsch) return -1;
+
+  memset(&nr_dci_info_extracted,0,sizeof(nr_dci_info_extracted));
+//  printf("we reach this point\n");
+  switch (dci_format) {
+
+    case format0_0:
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Entering function nr_extract_dci_info(dci_format=%d) for PUSCH allocation\n",dci_format);
+      #endif
+      status = nr_extract_dci_info(ue,
+                                   eNB_id,
+                                   frame_type,
+                                   dci_length,
+                                   dci_pdu,
+                                   &nr_dci_info_extracted,
+                                   dci_fields_sizes,
+                                   dlsch0_harq,
+                                   dlsch0,
+                                   ulsch0,
+                                   dci_format,
+                                   nr_tti_rx,
+                                   rnti,
+                                   si_rnti,
+                                   p_rnti,
+                                   ra_rnti,
+                                   tc_rnti,
+                                   n_RB_ULBWP,
+                                   n_RB_DLBWP);
+      //status = check_dci_format1_1a_coherency(format1_1, frame_parms->N_RB_DL, rnti, tc_rnti, si_rnti, ra_rnti, p_rnti,frame,nr_tti_rx, &nr_dci_info_extracted, dlsch0_harq);
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+      if(status == 0)
+      {
+        printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> bad DCI %d !!! \n",dci_format);
+        return(-1);
+      }
+      #endif
+      break;
+
+    case format0_1:
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+      printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format);
+      #endif
+      break;
+
+    case format1_0:
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+        printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Entering function nr_extract_dci_info(dci_format=%d)for PDSCH allocation\n",dci_format);
+      #endif
+      status = nr_extract_dci_info(ue,
+                                   eNB_id,
+                                   frame_type,
+                                   dci_length,
+                                   dci_pdu,
+                                   &nr_dci_info_extracted,
+                                   dci_fields_sizes,
+                                   dlsch0_harq,
+                                   dlsch0,
+                                   ulsch0,
+                                   dci_format,
+                                   nr_tti_rx,
+                                   rnti,
+                                   si_rnti,
+                                   p_rnti,
+                                   ra_rnti,
+                                   tc_rnti,
+                                   n_RB_ULBWP,
+                                   n_RB_DLBWP);
+      //status = check_dci_format1_1a_coherency(format1_1, frame_parms->N_RB_DL, rnti, tc_rnti, si_rnti, ra_rnti, p_rnti,frame,nr_tti_rx, &nr_dci_info_extracted, dlsch0_harq);
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+      if(status == 0)
+      {
+        printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> bad DCI %d !!! \n",dci_format);
+        return(-1);
+      }
+      #endif
+      break;
+
+    case format1_1:
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+      printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format);
+      #endif
+      break;
+
+    case format2_0:
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+      printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format);
+      #endif
+      break;
+
+    case format2_1:
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+      printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format);
+      #endif
+      break;
+
+    case format2_2:
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+      printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format);
+      #endif
+      break;
+
+    case format2_3:
+      #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+      printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format);
+      #endif
+      break;
+
+    default:
+      printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> we go to the default in switch\n");
+      //LOG_E(PHY,"format %d not yet implemented\n",dci_format);
+      return(-1);
+      break;
+  }
+  #ifdef NR_PDCCH_DCI_TOOLS_DEBUG
+    printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Ending function nr_extract_dci_info()\n");
+  #endif
+  return(0);
+}
+#endif
+#if 0
+int generate_ue_dlsch_params_from_dci(int frame,
+                                      uint8_t nr_tti_rx,
+                                      void *dci_pdu,
+                                      uint16_t rnti,
+                                      DCI_format_t dci_format,
+                                      NR_UE_PDCCH *pdcch_vars,
+                                      NR_UE_PDSCH *pdsch_vars,
+                                      NR_UE_DLSCH_t **dlsch,
+                                      NR_DL_FRAME_PARMS *frame_parms,
+                                      PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+                                      uint16_t si_rnti,
+                                      uint16_t ra_rnti,
+                                      uint16_t p_rnti,
+                                      uint8_t beamforming_mode,
+                                      uint16_t tc_rnti)
+{
+
+    uint8_t harq_pid=0;
+    uint8_t frame_type=frame_parms->frame_type;
+    uint8_t tpmi=0;
+    NR_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
+    NR_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
+
+    DCI_INFO_EXTRACTED_t dci_info_extarcted;
+    uint8_t status=0;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    printf("####################### verifying pointer\n");
+    dlsch0 = dlsch[0];
+    dlsch0->active = 0;
+    dlsch0_harq   = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid];
+    printf("####################### verifying pointer, dlsch0 = %p, dlsch0_harq = %p\n",dlsch0,dlsch0_harq);
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    if (!dlsch[0]) return -1;
+
+  #ifdef DEBUG_DCI
+    LOG_D(PHY,"dci_tools.c: Filling ue dlsch params -> rnti %x, SFN/SF %d/%d, dci_format %s\n",
+        rnti,
+        frame%1024,
+        nr_tti_rx,
+        (dci_format==format0?  "Format 0":(
+         dci_format==format1?  "format 1":(
+         dci_format==format1A? "format 1A":(
+         dci_format==format1B? "format 1B":(
+         dci_format==format1C? "format 1C":(
+         dci_format==format1D? "format 1D":(
+         dci_format==format1E_2A_M10PRB? "format 1E_2A_M10PRB":(
+         dci_format==format2?  "format 2":(
+         dci_format==format2A? "format 2A":(
+         dci_format==format2B? "format 2B":(
+         dci_format==format2C? "format 2C":(
+         dci_format==format2D? "format 2D":(
+         dci_format==format3?  "format 3": "UNKNOWN"
+         ))))))))))))));
+  #endif
+
+    memset(&dci_info_extarcted,0,sizeof(dci_info_extarcted));
+    switch (dci_format) {
+
+    case format0:   // This is an ULSCH allocation so nothing here, inform MAC
+      LOG_E(PHY,"format0 not possible\n");
+      return(-1);
+      break;
+
+    case format1A:
+    {
+      // extract dci infomation
+#ifdef DEBUG_DCI
+      LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d extarct dci info \n", frame, nr_tti_rx);
+#endif
+      extract_dci1A_info(frame_parms->N_RB_DL,
+                         frame_type,
+                         dci_pdu,
+                         &dci_info_extarcted);
+
+
+      // check dci content
+      dlsch0 = dlsch[0];
+      dlsch0->active = 0;
+      dlsch0_harq   = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid];
+#ifdef DEBUG_DCI
+      LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d check dci coherency \n", frame, nr_tti_rx);
+#endif
+      status = check_dci_format1_1a_coherency(format1A,
+                                              frame_parms->N_RB_DL,
+                                              rnti,
+                                              tc_rnti,
+                                              si_rnti,
+                                              ra_rnti,
+                                              p_rnti,frame,nr_tti_rx,
+                                              &dci_info_extarcted,
+                                              dlsch0_harq);
+      if(status == 0)
+      {
+        printf("bad DCI 1A !!! \n");
+        return(-1);
+      }
+
+      // dci is correct ==> update internal structure and prepare dl decoding
+#ifdef DEBUG_DCI
+      LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d prepare dl decoding \n", frame, nr_tti_rx);
+#endif
+      prepare_dl_decoding_format1_1A(format1A,
+                                     frame_parms->N_RB_DL,
+                                     &dci_info_extarcted,
+                                     frame_parms,
+                                     pdcch_vars,
+                                     pdsch_vars,
+                                     nr_tti_rx,
+                                     rnti,
+									 tc_rnti,
+                                     si_rnti,
+                                     ra_rnti,
+                                     p_rnti,
+                                     dlsch0_harq,
+                                     dlsch0);
+
+
+
+      break;
+    }
+    case format1C:
+    {
+      // extract dci infomation
+#ifdef DEBUG_DL_DECODING
+      LOG_I(PHY,"[DCI Format-1C] extact dci information \n");
+#endif
+      extract_dci1C_info(frame_parms->N_RB_DL,
+                         frame_type,
+                         dci_pdu,
+                         &dci_info_extarcted);
+
+
+      // check dci content
+#ifdef DEBUG_DL_DECODING
+      LOG_I(PHY,"[DCI Format-1C] check dci content \n");
+#endif
+      dlsch0 = dlsch[0];
+      dlsch0->active = 0;
+      dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid];
+
+      status = check_dci_format1c_coherency(frame_parms->N_RB_DL,
+                                            &dci_info_extarcted,
+                                            rnti,
+                                            si_rnti,
+                                            ra_rnti,
+                                            p_rnti,
+                                            dlsch0_harq);
+      if(status == 0)
+        return(-1);
+
+      // dci is correct ==> update internal structure and prepare dl decoding
+#ifdef DEBUG_DL_DECODING
+      LOG_I(PHY,"[DCI Format-1C] prepare downlink decoding \n");
+#endif
+      prepare_dl_decoding_format1C(frame_parms->N_RB_DL,
+                                   &dci_info_extarcted,
+                                   frame_parms,
+                                   pdcch_vars,
+                                   pdsch_vars,
+                                   rnti,
+                                   si_rnti,
+                                   ra_rnti,
+                                   p_rnti,
+                                   frame,
+                                   nr_tti_rx,
+                                   dlsch0_harq,
+                                   dlsch0);
+
+      break;
+    }
+
+    case format1:
+    {
+      // extract dci infomation
+#ifdef DEBUG_DCI
+      LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d extarct dci info \n", frame, nr_tti_rx);
+#endif
+      extract_dci1_info(frame_parms->N_RB_DL,
+                         frame_type,
+                         dci_pdu,
+                         &dci_info_extarcted);
+
+      // check dci content
+      dlsch0 = dlsch[0];
+      dlsch0->active = 0;
+      dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid];
+
+#ifdef DEBUG_DCI
+      LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d check dci coherency \n", frame, nr_tti_rx);
+#endif
+      status = check_dci_format1_1a_coherency(format1,
+                                              frame_parms->N_RB_DL,
+                                              rnti,
+                                              tc_rnti,
+                                              si_rnti,
+                                              ra_rnti,
+                                              p_rnti,frame,nr_tti_rx,
+                                              &dci_info_extarcted,
+                                              dlsch0_harq);
+      if(status == 0)
+      {
+          printf("bad DCI 1 !!! \n");
+          return(-1);
+      }
+
+
+      // dci is correct ==> update internal structure and prepare dl decoding
+#ifdef DEBUG_DCI
+      LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d prepare dl decoding \n", frame, nr_tti_rx);
+#endif
+      prepare_dl_decoding_format1_1A(format1,
+                                     frame_parms->N_RB_DL,
+                                     &dci_info_extarcted,
+                                     frame_parms,
+                                     pdcch_vars,
+                                     pdsch_vars,
+                                     nr_tti_rx,
+                                     rnti,
+									 tc_rnti,
+                                     si_rnti,
+                                     ra_rnti,
+                                     p_rnti,
+                                     dlsch0_harq,
+                                     dlsch0);
+      break;
+    }
+
+    case format2:
+    {
+        // extract dci infomation
+        //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame, subframe);
+        extract_dci2_info(frame_parms->N_RB_DL,
+                frame_type,
+                frame_parms->nb_antenna_ports_eNB,
+                dci_pdu,
+                &dci_info_extarcted);
+
+
+        // check dci content
+        dlsch[0]->active = 1;
+        dlsch[1]->active = 1;
+
+            dlsch0 = dlsch[0];
+            dlsch1 = dlsch[1];
+
+    dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid];
+    dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid];
+   // printf("before coherency dlsch[1]->pmi_alloc %d\n",dlsch[1]->pmi_alloc);
+   // printf("before coherency dlsch1->pmi_alloc %d\n",dlsch1->pmi_alloc);
+   // printf("before coherency dlsch1_harq->pmi_alloc %d\n",dlsch1_harq->pmi_alloc);
+
+        //LOG_I(PHY,"[DCI-format2] check dci content \n");
+        status = check_dci_format2_2a_coherency(format2,
+                frame_parms->N_RB_DL,
+                &dci_info_extarcted,
+                rnti,
+                si_rnti,
+                ra_rnti,
+                p_rnti,
+                dlsch0_harq,
+                dlsch1_harq);
+        if(status == 0)
+            return(-1);
+
+
+        // dci is correct ==> update internal structure and prepare dl decoding
+        //LOG_I(PHY,"[DCI-format2] update internal structure and prepare dl decoding \n");
+        prepare_dl_decoding_format2_2A(format2,
+                &dci_info_extarcted,
+                frame_parms,
+                pdcch_vars,
+                pdsch_vars,
+                rnti,
+                nr_tti_rx,
+                dlsch0_harq,
+                dlsch1_harq,
+                dlsch0,
+                dlsch1);
+    }
+    break;
+
+    case format2A:
+    {
+    // extract dci infomation
+    LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame%1024, nr_tti_rx);
+    extract_dci2A_info(frame_parms->N_RB_DL,
+                       frame_type,
+                       frame_parms->nb_antenna_ports_eNB,
+                       dci_pdu,
+                       &dci_info_extarcted);
+
+    // check dci content
+    //LOG_I(PHY,"[DCI-format2A] check dci content \n");
+    //LOG_I(PHY,"[DCI-format2A] tb_swap %d harq_pid %d\n", dci_info_extarcted.tb_swap, dci_info_extarcted.harq_pid);
+      //dlsch[0]->active = 0;
+      //dlsch[1]->active = 0;
+
+    if (dci_info_extarcted.tb_swap == 0) {
+      dlsch0 = dlsch[0];
+      dlsch1 = dlsch[1];
+    } else {
+      dlsch0 = dlsch[1];
+      dlsch1 = dlsch[0];
+    }
+    dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid];
+    dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid];
+
+    //LOG_I(PHY,"[DCI-format2A] check dci content \n");
+    status = check_dci_format2_2a_coherency(format2A,
+                                              frame_parms->N_RB_DL,
+                                              &dci_info_extarcted,
+                                              rnti,
+                                              si_rnti,
+                                              ra_rnti,
+                                              p_rnti,
+                                              dlsch0_harq,
+                                              dlsch1_harq);
+    if(status == 0)
+      return(-1);
+
+    // dci is correct ==> update internal structure and prepare dl decoding
+    //LOG_I(PHY,"[DCI-format2A] update internal structure and prepare dl decoding \n");
+    prepare_dl_decoding_format2_2A(format2A,
+                                   &dci_info_extarcted,
+                                   frame_parms,
+                                   pdcch_vars,
+                                   pdsch_vars,
+                                   rnti,
+                                   nr_tti_rx,
+                                   dlsch0_harq,
+                                   dlsch1_harq,
+                                   dlsch0,
+                                   dlsch1);
+    }
+      break;
+
+    case format1E_2A_M10PRB:
+      if (!dlsch[0]) return -1;
+
+      harq_pid  = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid;
+
+      if (harq_pid>=8) {
+        LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid);
+        return(-1);
+      }
+
+      dlsch[0]->current_harq_pid = harq_pid;
+      dlsch[0]->harq_ack[nr_tti_rx].harq_id = harq_pid;
+
+      /*
+        tbswap = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tb_swap;
+        if (tbswap == 0) {
+        dlsch0 = dlsch[0];
+        dlsch1 = dlsch[1];
+        }
+        else{
+        dlsch0 = dlsch[1];
+        dlsch1 = dlsch[0];
+        }
+      */
+      dlsch0 = dlsch[0];
+
+      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+      // Needs to be checked
+      dlsch0_harq->codeword=0;
+      conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah,
+                   ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL,
+                   dlsch0_harq->rb_alloc_even);
+
+      dlsch0_harq->rb_alloc_odd[0]                         = dlsch0_harq->rb_alloc_even[0];
+      dlsch0_harq->rb_alloc_odd[1]                         = dlsch0_harq->rb_alloc_even[1];
+      dlsch0_harq->rb_alloc_odd[2]                         = dlsch0_harq->rb_alloc_even[2];
+      dlsch0_harq->rb_alloc_odd[3]                         = dlsch0_harq->rb_alloc_even[3];
+      /*
+      dlsch1_harq->rb_alloc_even[0]                         = dlsch0_harq->rb_alloc_even[0];
+      dlsch1_harq->rb_alloc_even[1]                         = dlsch0_harq->rb_alloc_even[1];
+      dlsch1_harq->rb_alloc_even[2]                         = dlsch0_harq->rb_alloc_even[2];
+      dlsch1_harq->rb_alloc_even[3]                         = dlsch0_harq->rb_alloc_even[3];
+      */
+      dlsch0_harq->nb_rb                               = conv_nprb(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah,
+          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,
+          frame_parms->N_RB_DL);
+      //dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;
+
+      dlsch0_harq->mcs             = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
+      dlsch0_harq->delta_PUCCH     = delta_PUCCH_lut[((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->TPC&3];
+
+
+
+      /*
+        if (dlsch0_harq->mcs>20) {
+        printf("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs);
+        return(-1);
+        }
+      */
+
+      //dlsch1_harq->mcs       = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs2;
+      dlsch0_harq->rvidx     = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv;
+      //dlsch1_harq->rvidx     = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv2;
+
+      // check if either TB is disabled (see 36-213 V8.6 p. 26)
+
+      if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
+        dlsch0_harq->status = DISABLED;
+      }
+
+      //if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
+      //dlsch1_harq->status = DISABLED;
+      //}
+      dlsch0_harq->Nl        = 1;
+
+      //dlsch0->layer_index                         = tbswap;
+      //dlsch1->layer_index                         = 1-tbswap;
+
+
+      // Fix this
+      tpmi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tpmi;
+      //    printf("ue: tpmi %d\n",tpmi);
+
+      switch (tpmi) {
+      case 0 :
+        dlsch0_harq->mimo_mode   = ALAMOUTI;
+        break;
+
+      case 1:
+        dlsch0_harq->mimo_mode   = UNIFORM_PRECODING11;
+        dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,0,0);
+        break;
+
+      case 2:
+        dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
+        dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1, 0);
+        break;
+
+      case 3:
+        dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
+        dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,2, 0);
+
+        break;
+
+      case 4:
+        dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
+        dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,3, 0);
+        break;
+
+      case 5:
+        dlsch0_harq->mimo_mode   = PUSCH_PRECODING0;
+        // pmi stored from ulsch allocation routine
+        dlsch0_harq->pmi_alloc   = dlsch0->pmi_alloc;
+        //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc));
+        break;
+
+      case 6:
+        dlsch0_harq->mimo_mode   = PUSCH_PRECODING1;
+        LOG_E(PHY,"Unsupported TPMI\n");
+        return(-1);
+        break;
+      }
+
+
+      if (frame_parms->mode1_flag == 1)
+        dlsch0_harq->mimo_mode   = SISO;
+
+
+      if ((dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) ||
+	(dlsch0_harq->first_tx==1)) {
+
+        dlsch0_harq->round = 0;
+	dlsch0_harq->first_tx = 0;
+        dlsch0_harq->status = ACTIVE;
+      }
+      /*
+	else if (dlsch0_harq->status == SCH_IDLE) { // we got same ndi for a previously decoded process,
+        // this happens if either another harq process in the same
+        // is NAK or an ACK was not received
+
+        dlsch0->harq_ack[subframe].ack              = 1;
+        dlsch0->harq_ack[subframe].harq_id          = harq_pid;
+        dlsch0->harq_ack[subframe].send_harq_status = 1;
+        dlsch0->active = 0;
+        return(0);
+      }
+      */
+
+      dlsch0_harq->DCINdi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi;
+      dlsch0_harq->mcs    = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
+
+      if (dlsch0_harq->nb_rb>1) {
+        dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+      } else
+        dlsch0_harq->TBS         =0;
+
+      dlsch0->rnti = rnti;
+      //dlsch1->rnti = rnti;
+
+      dlsch0->active = 1;
+      //dlsch1->active = 1;
+
+      dlsch0_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off;
+      //dlsch1_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off;
+
+
+      break;
+
+    default:
+      LOG_E(PHY,"format %d not yet implemented\n",dci_format);
+      return(-1);
+      break;
+    }
+
+#ifdef UE_DEBUG_TRACE
+
+    if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) {
+        LOG_I(PHY,"dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,nr_tti_rx);
+        LOG_I(PHY,"PDSCH dlsch0 UE: rnti     %x\n",dlsch[0]->rnti);
+        LOG_D(PHY,"PDSCH dlsch0 UE: NBRB     %d\n",dlsch0_harq->nb_rb);
+        LOG_D(PHY,"PDSCH dlsch0 UE: rballoc  %x\n",dlsch0_harq->rb_alloc_even[0]);
+        LOG_I(PHY,"PDSCH dlsch0 UE: harq_pid %d\n",dci_info_extarcted.harq_pid);
+        LOG_I(PHY,"PDSCH dlsch0 UE: g        %d\n",dlsch[0]->g_pucch);
+        LOG_D(PHY,"PDSCH dlsch0 UE: round    %d\n",dlsch0_harq->round);
+        LOG_D(PHY,"PDSCH dlsch0 UE: DCINdi   %d\n",dlsch0_harq->DCINdi);
+        LOG_D(PHY,"PDSCH dlsch0 UE: rvidx    %d\n",dlsch0_harq->rvidx);
+        LOG_D(PHY,"PDSCH dlsch0 UE: TBS      %d\n",dlsch0_harq->TBS);
+        LOG_D(PHY,"PDSCH dlsch0 UE: mcs      %d\n",dlsch0_harq->mcs);
+        LOG_D(PHY,"PDSCH dlsch0 UE: pwr_off  %d\n",dlsch0_harq->dl_power_off);
+    }
+#endif
+
+  #if T_TRACER
+    if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti))
+    {
+    T(T_UE_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame%1024), T_INT(nr_tti_rx), T_INT(0),
+            T_INT(dlsch[0]->rnti), T_INT(dci_format),
+            T_INT(harq_pid),
+            T_INT(dlsch0_harq->mcs),
+            T_INT(dlsch0_harq->TBS));
+    }
+  #endif
+
+
+    // compute DL power control parameters
+    if (dlsch0_harq != NULL){
+      computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB);
+      computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off);
+    }
+
+    if (dlsch1_harq != NULL) {
+      computeRhoA_UE(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB);
+      computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off);
+    }
+
+
+    return(0);
+}
+
+#endif //(0)
+uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t nr_tti_rx)
+{
+  /*
+    #ifdef DEBUG_DCI
+    if (frame_parms->frame_type == TDD)
+    printf("dci_tools.c: subframe2_harq_pid, subframe %d for TDD configuration %d\n",subframe,frame_parms->tdd_config);
+    else
+    printf("dci_tools.c: subframe2_harq_pid, subframe %d for FDD \n",subframe);
+    #endif
+  */
+
+  uint8_t ret = 255;
+  uint8_t subframe = nr_tti_rx>>((int)(log2 (frame_parms->ttis_per_subframe)));
+
+  if (frame_parms->frame_type == FDD) {
+    ret = (((frame<<1)+nr_tti_rx)&7);
+  } else {
+
+    switch (frame_parms->tdd_config) {
+
+    case 1:
+      if ((subframe==2) ||
+          (subframe==3) ||
+          (subframe==7) ||
+          (subframe==8))
+        switch (subframe) {
+        case 2:
+        case 3:
+          ret = (subframe-2);
+          break;
+
+        case 7:
+        case 8:
+          ret = (subframe-5);
+          break;
+
+        default:
+          LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
+          ret = (255);
+          break;
+        }
+
+      break;
+
+    case 2:
+      if ((subframe!=2) && (subframe!=7)) {
+        LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
+        //mac_xface->macphy_exit("subframe2_harq_pid, Illegal subframe");
+        ret = (255);
+      }
+
+      ret = (subframe/7);
+      break;
+
+    case 3:
+      if ((subframe<2) || (subframe>4)) {
+        LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
+        ret = (255);
+      }
+
+      ret = (subframe-2);
+      break;
+
+    case 4:
+      if ((subframe<2) || (subframe>3)) {
+        LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
+        ret = (255);
+      }
+
+      ret = (subframe-2);
+      break;
+
+    case 5:
+      if (subframe!=2) {
+        LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
+        ret = (255);
+      }
+
+      ret = (subframe-2);
+      break;
+
+    default:
+      LOG_E(PHY,"subframe2_harq_pid, Unsupported TDD mode %d\n",frame_parms->tdd_config);
+      ret = (255);
+
+    }
+  }
+
+  if (ret == 255) {
+    LOG_E(PHY, "invalid harq_pid(%d) at SFN/SF = %d/%d\n", ret, frame, subframe);
+    //mac_xface->macphy_exit("invalid harq_pid");
+  }
+  return ret;
+}
+
+
+uint8_t nr_pdcch_alloc2ul_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t n)
+{
+  uint8_t ul_subframe = 255;
+
+  if ((frame_parms->frame_type == TDD) &&
+      (frame_parms->tdd_config == 1) &&
+      ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
+    ul_subframe = ((n+6)%10);
+  else if ((frame_parms->frame_type == TDD) &&
+           (frame_parms->tdd_config == 6) &&
+           ((n==0)||(n==1)||(n==5)||(n==6)))
+    ul_subframe = ((n+7)%10);
+  else if ((frame_parms->frame_type == TDD) &&
+           (frame_parms->tdd_config == 6) &&
+           (n==9)) // tdd_config 6 SF 9
+    ul_subframe = ((n+5)%10);
+  else
+    ul_subframe = ((n+4)%10);
+
+  LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe);
+  return ul_subframe;
+}
+#if 0
+uint8_t ul_subframe2pdcch_alloc_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t n)
+{
+  if ((frame_parms->frame_type == TDD) &&
+      (frame_parms->tdd_config == 1) &&
+      ((n==7)||(n==2))) // tdd_config 0,1 SF 1,5
+    return((n==7)? 1 : 6);
+  else if ((frame_parms->frame_type == TDD) &&
+           (frame_parms->tdd_config == 6) &&
+           ((n==7)||(n==8)||(n==2)||(n==3)))
+    return((n+3)%10);
+  else if ((frame_parms->frame_type == TDD) &&
+           (frame_parms->tdd_config == 6) &&
+           (n==4)) // tdd_config 6 SF 9
+    return(9);
+  else
+    return((n+6)%10);
+
+}
+#endif //(0)
+
+uint32_t nr_pdcch_alloc2ul_frame(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n)
+{
+  uint32_t ul_frame = 255;
+
+  if ((frame_parms->frame_type == TDD) &&
+      (frame_parms->tdd_config == 1) &&
+      ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
+    ul_frame = (frame + (n==1 ? 0 : 1));
+  else if ((frame_parms->frame_type == TDD) &&
+           (frame_parms->tdd_config == 6) &&
+           ((n==0)||(n==1)||(n==5)||(n==6)))
+    ul_frame = (frame + (n>=5 ? 1 : 0));
+  else if ((frame_parms->frame_type == TDD) &&
+           (frame_parms->tdd_config == 6) &&
+           (n==9)) // tdd_config 6 SF 9
+    ul_frame = (frame+1);
+  else
+    ul_frame = (frame+(n>=6 ? 1 : 0));
+
+  LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, ul_frame);
+  return ul_frame;
+
+}
+#if 0
+int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb)
+{
+  int nb_subbands = 0;
+  int32_t pmi_alloc_new = 0, pmi_new = 0, pmi_old = 0;
+  int i;
+
+  switch (nb_rb) {
+    case 6:
+      nb_subbands = 6;
+      break;
+    default:
+    case 25:
+      nb_subbands = 7;
+      break;
+    case 50:
+      nb_subbands = 9;
+      break;
+    case 100:
+      nb_subbands = 13;
+      break;
+    }
+
+  for (i = 0; i < nb_subbands; i++) {
+    pmi_old = (pmi_alloc >> i)&1;
+
+    if (pmi_old == 0)
+      if (tpmi == 5)
+        pmi_new = 0;
+      else
+        pmi_new = 1;
+    else
+      if (tpmi == 5)
+        pmi_new = 2;
+      else
+        pmi_new = 3;
+
+    pmi_alloc_new|=pmi_new<<(2*i);
+
+  }
+#ifdef DEBUG_HARQ
+printf("  [DCI UE] pmi_alloc_old %d, pmi_alloc_new %d pmi_old %d , pmi_new %d\n", pmi_alloc, pmi_alloc_new,pmi_old, pmi_new );
+#endif
+return(pmi_alloc_new);
+
+}
+
+uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb)
+{
+
+  int i, aarx;
+  uint16_t pmiq=0;
+  uint32_t pmivect = 0;
+  uint8_t rank = meas->rank[eNB_id];
+  int pmi_re,pmi_im;
+  int  nb_subbands=0;
+
+
+  switch (nb_rb) {
+    case 6:
+      nb_subbands = 6;
+      break;
+    default:
+    case 25:
+      nb_subbands = 7;
+      break;
+    case 50:
+      nb_subbands = 9;
+      break;
+    case 100:
+      nb_subbands = 13;
+      break;
+    }
+
+
+  for (i=0; i<nb_subbands; i++) {
+    pmi_re = 0;
+    pmi_im = 0;
+
+    if (rank == 0) {
+      for (aarx=0; aarx<meas->nb_antennas_rx; aarx++) {
+        pmi_re += meas->subband_pmi_re[eNB_id][i][aarx];
+        pmi_im += meas->subband_pmi_im[eNB_id][i][aarx];
+      }
+
+      //  pmi_re = meas->subband_pmi_re[eNB_id][i][meas->selected_rx_antennas[eNB_id][i]];
+      //  pmi_im = meas->subband_pmi_im[eNB_id][i][meas->selected_rx_antennas[eNB_id][i]];
+
+      //      printf("pmi => (%d,%d)\n",pmi_re,pmi_im);
+      if ((pmi_re > pmi_im) && (pmi_re > -pmi_im))
+        pmiq = PMI_2A_11;
+      else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im))
+        pmiq = PMI_2A_1j;
+      else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im))
+        pmiq = PMI_2A_1m1;
+      else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im))
+        pmiq = PMI_2A_1mj;
+
+      //      printf("subband %d, pmi%d \n",i,pmiq);
+      pmivect |= (pmiq<<(2*i));
+    }
+
+    else if (rank==1) {
+      for (aarx=0; aarx<meas->nb_antennas_rx; aarx++) {
+        pmi_re += meas->subband_pmi_re[eNB_id][i][aarx];
+  //printf("meas->subband_pmi_re[eNB_id][i][%d]=%d\n", aarx, meas->subband_pmi_re[eNB_id][i][aarx]);
+        pmi_im += meas->subband_pmi_im[eNB_id][i][aarx];
+  //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]);
+      }
+     if (pmi_re >= pmi_im) // this is not orthogonal
+     // this is orthogonal
+     //if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re >= -pmi_im)))
+       pmiq = PMI_2A_R1_11;
+     else
+       pmiq = PMI_2A_R1_1j;
+
+     // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq);
+     // printf("subband %d, pmi%d \n",i,pmiq);
+      //According to Section 7.2.4 of 36.213
+
+      pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit
+    }
+    else {
+      LOG_E(PHY,"PMI feedback for rank>1 not supported!\n");
+      pmivect = 0;
+    }
+
+  }
+#ifdef DEBUG_HARQ
+    printf( "quantize_subband_pmi pmivect %d \n", pmivect);
+#endif
+  return(pmivect);
+}
+
+uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands)
+{
+
+  uint8_t i;
+  uint16_t pmiq=0;
+  uint16_t pmivect = 0;
+  uint8_t rank = meas->rank[eNB_id];
+  int pmi_re,pmi_im;
+
+  for (i=0; i<nb_subbands; i++) {
+
+    if (rank == 0) {
+      pmi_re = meas->subband_pmi_re[eNB_id][i][a_id];
+      pmi_im = meas->subband_pmi_im[eNB_id][i][a_id];
+
+      if ((pmi_re > pmi_im) && (pmi_re > -pmi_im))
+        pmiq = PMI_2A_11;
+      else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im))
+        pmiq = PMI_2A_1j;
+      else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im))
+        pmiq = PMI_2A_1m1;
+      else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im))
+        pmiq = PMI_2A_1mj;
+
+      pmivect |= (pmiq<<(2*i));
+    } else {
+      // This needs to be done properly!!!
+      pmivect = 0;
+    }
+  }
+
+  return(pmivect);
+}
+
+uint16_t quantize_wideband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id)
+{
+
+  uint16_t pmiq=0;
+  uint8_t rank = meas->rank[eNB_id];
+  //int pmi;
+  int pmi_re,pmi_im;
+
+  if (rank == 1) {
+    //pmi =
+    pmi_re = meas->wideband_pmi_re[eNB_id][meas->selected_rx_antennas[eNB_id][0]];
+    pmi_im = meas->wideband_pmi_im[eNB_id][meas->selected_rx_antennas[eNB_id][0]];
+
+    if ((pmi_re > pmi_im) && (pmi_re > -pmi_im))
+      pmiq = PMI_2A_11;
+    else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im))
+      pmiq = PMI_2A_1j;
+    else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im))
+      pmiq = PMI_2A_1m1;
+    else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im))
+      pmiq = PMI_2A_1mj;
+
+  } else {
+    // This needs to be done properly!
+    pmiq = PMI_2A_11;
+  }
+
+
+  return(pmiq);
+}
+/*
+  uint8_t sinr2cqi(int sinr) {
+  if (sinr<-3)
+  return(0);
+  if (sinr>14)
+  return(10);
+  else
+  return(3+(sinr>>1));
+  }
+*/
+
+uint8_t sinr2cqi(double sinr,uint8_t trans_mode)
+{
+  // int flag_LA=0;
+
+  uint8_t retValue = 0;
+
+  if(flag_LA==0) {
+    // Ideal Channel Estimation
+    if (sinr<=-4.89)
+      retValue = (0);
+    else if (sinr < -3.53)
+      retValue = (3);
+    else if (sinr <= -1.93)
+      retValue = (4);
+    else if (sinr <= -0.43)
+      retValue = (5);
+    else if (sinr <= 1.11)
+      retValue = (6);
+    else if (sinr <= 3.26)
+      retValue = (7);
+    else if (sinr <= 5.0)
+      retValue = (8);
+    else if (sinr <= 7.0)
+      retValue = (9);
+    else if (sinr <= 9.0)
+      retValue = (10);
+    else if (sinr <= 11.0)
+      retValue = (11);
+    else if (sinr <= 13.0)
+      retValue = (12);
+    else if (sinr <= 15.5)
+      retValue = (13);
+    else if (sinr <= 17.5)
+      retValue = (14);
+    else
+      retValue = (15);
+  } else {
+    int h=0;
+    int trans_mode_tmp;
+
+    if (trans_mode ==5)
+      trans_mode_tmp=2;
+    else if(trans_mode ==6)
+      trans_mode_tmp=3;
+    else
+      trans_mode_tmp = trans_mode-1;
+
+    for(h=0; h<16; h++) {
+      if(sinr<=sinr_to_cqi[trans_mode_tmp][h])
+        retValue = (h);
+    }
+  }
+
+  LOG_D(PHY, "sinr=%f trans_mode=%d cqi=%d\n", sinr, trans_mode, retValue);
+  return retValue;
+}
+//uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id) {
+//
+//  uint8_t i;
+////  uint16_t cqivect = 0;
+//  uint32_t cqivect = 0;
+//
+////  char diff_cqi;
+//  int diff_cqi=0;
+//
+//  for (i=0;i<NUMBER_OF_SUBBANDS;i++) {
+//
+//    diff_cqi = -sinr2cqi(meas->wideband_cqi_dB[eNB_id][0]) + sinr2cqi(meas->subband_cqi_dB[eNB_id][0][i]);
+//
+//    // Note, this is Table 7.2.1-2 from 36.213
+//    if (diff_cqi<=-1)
+//      diff_cqi = 3;
+//    else if (diff_cqi>2)
+//      diff_cqi = 2;
+//    cqivect |= (diff_cqi<<(2*i));
+//
+//  }
+//
+//  return(cqivect);
+//}
+
+
+uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t trans_mode,int nb_subbands)
+{
+
+  uint8_t i;
+
+  uint32_t cqivect = 0,offset=0;
+
+
+  int diff_cqi=0;
+
+  for (i=0; i<nb_subbands; i++) {
+
+    diff_cqi = -sinr2cqi(meas->wideband_cqi_avg[eNB_id],trans_mode) + sinr2cqi(meas->subband_cqi_tot_dB[eNB_id][i],trans_mode);
+
+    // Note, this is Table 7.2.1-2 from 36.213
+    if (diff_cqi<=-1)
+      offset = 3;
+    else if (diff_cqi>=2)
+      offset = 2;
+    else
+      offset=(uint32_t)diff_cqi;
+
+    cqivect |= (offset<<(2*i));
+
+  }
+
+  return(cqivect);
+}
+
+void fill_CQI(NR_UE_ULSCH_t *ulsch,PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t harq_pid,int N_RB_DL,uint16_t rnti, uint8_t trans_mode, double sinr_eff)
+{
+
+  //  printf("[PHY][UE] Filling CQI for eNB %d, meas->wideband_cqi_tot[%d] %d\n",
+  //      eNB_id,eNB_id,meas->wideband_cqi_tot[eNB_id]);
+  double sinr_tmp;
+  uint8_t *o = ulsch->o;
+  UCI_format_t uci_format = ulsch->uci_format;
+
+  if(flag_LA==1)
+    sinr_tmp = sinr_eff;
+  else
+    sinr_tmp = (double) meas->wideband_cqi_avg[eNB_id];
+
+
+
+  //LOG_I(PHY,"[UE][UCI] Filling CQI format %d for eNB %d N_RB_DL %d\n",uci_format,eNB_id,N_RB_DL);
+
+  switch (N_RB_DL) {
+
+  case 6:
+    switch (uci_format) {
+    case wideband_cqi_rank1_2A:
+      ((wideband_cqi_rank1_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode);
+      ((wideband_cqi_rank1_2A_1_5MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,6);
+      break;
+
+    case wideband_cqi_rank2_2A:
+      ((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
+      ((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
+      ((wideband_cqi_rank2_2A_1_5MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,6);
+      break;
+
+    case HLC_subband_cqi_nopmi:
+      ((HLC_subband_cqi_nopmi_1_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_nopmi_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6);
+      break;
+
+    case HLC_subband_cqi_rank1_2A:
+      ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6);
+      ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->pmi      = quantize_wideband_pmi(meas,eNB_id);
+      break;
+
+    case HLC_subband_cqi_rank2_2A:
+      // This has to be improved!!!
+      ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6);
+      ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi2     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,6);
+      ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->pmi      = quantize_subband_pmi(meas,eNB_id,6);
+      break;
+
+    case HLC_subband_cqi_mcs_CBA:
+      // this is the cba mcs uci for cba transmission
+      ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->mcs     = ulsch->harq_processes[harq_pid]->mcs;
+      ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti  = rnti;
+      LOG_D(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs);
+      break;
+
+    case ue_selected:
+      LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n");
+      mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!");
+      break;
+
+    default:
+      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
+      mac_xface->macphy_exit("unsupported CQI mode !!!");
+      break;
+
+    }
+
+    break;
+
+  case 25:
+    switch (uci_format) {
+    case wideband_cqi_rank1_2A:
+      ((wideband_cqi_rank1_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode);
+      ((wideband_cqi_rank1_2A_5MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,7);
+      break;
+
+    case wideband_cqi_rank2_2A:
+      ((wideband_cqi_rank2_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
+      ((wideband_cqi_rank2_2A_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
+      ((wideband_cqi_rank2_2A_5MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,7);
+      break;
+
+    case HLC_subband_cqi_nopmi:
+      ((HLC_subband_cqi_nopmi_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_nopmi_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7);
+      break;
+
+    case HLC_subband_cqi_rank1_2A:
+      ((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7);
+      ((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi      = quantize_wideband_pmi(meas,eNB_id);
+      break;
+
+    case HLC_subband_cqi_rank2_2A:
+      // This has to be improved!!!
+      ((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7);
+      ((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi2     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,7);
+      ((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi      = quantize_subband_pmi(meas,eNB_id,7);
+      break;
+
+    case HLC_subband_cqi_mcs_CBA:
+      // this is the cba mcs uci for cba transmission
+      ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs     = ulsch->harq_processes[harq_pid]->mcs;
+      ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti  = rnti;
+      LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs);
+      break;
+
+    case ue_selected:
+      LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n");
+      mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!");
+      break;
+
+    default:
+      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
+      mac_xface->macphy_exit("unsupported CQI mode !!!");
+      break;
+
+    }
+
+    break;
+
+  case 50:
+    switch (uci_format) {
+    case wideband_cqi_rank1_2A:
+      ((wideband_cqi_rank1_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode);
+      ((wideband_cqi_rank1_2A_10MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,9);
+      break;
+
+    case wideband_cqi_rank2_2A:
+      ((wideband_cqi_rank2_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
+      ((wideband_cqi_rank2_2A_10MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
+      ((wideband_cqi_rank2_2A_10MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,9);
+      break;
+
+    case HLC_subband_cqi_nopmi:
+      ((HLC_subband_cqi_nopmi_10MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_nopmi_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9);
+      break;
+
+    case HLC_subband_cqi_rank1_2A:
+      ((HLC_subband_cqi_rank1_2A_10MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank1_2A_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9);
+      ((HLC_subband_cqi_rank1_2A_10MHz *)o)->pmi      = quantize_wideband_pmi(meas,eNB_id);
+      break;
+
+    case HLC_subband_cqi_rank2_2A:
+      // This has to be improved!!!
+      ((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9);
+      ((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi2     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,9);
+      ((HLC_subband_cqi_rank2_2A_10MHz *)o)->pmi      = quantize_subband_pmi(meas,eNB_id,9);
+      break;
+
+    case HLC_subband_cqi_mcs_CBA:
+      // this is the cba mcs uci for cba transmission
+      ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->mcs     = ulsch->harq_processes[harq_pid]->mcs;
+      ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti  = rnti;
+      LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs);
+      break;
+
+    case ue_selected:
+      LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n");
+      mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!");
+      break;
+
+    default:
+      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
+      mac_xface->macphy_exit("unsupported CQI mode !!!");
+      break;
+
+    }
+
+    break;
+
+  case 100:
+    switch (uci_format) {
+    case wideband_cqi_rank1_2A:
+      ((wideband_cqi_rank1_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode);
+      ((wideband_cqi_rank1_2A_20MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,13);
+      break;
+
+    case wideband_cqi_rank2_2A:
+      ((wideband_cqi_rank2_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
+      ((wideband_cqi_rank2_2A_20MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
+      ((wideband_cqi_rank2_2A_20MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,13);
+      break;
+
+    case HLC_subband_cqi_nopmi:
+      ((HLC_subband_cqi_nopmi_20MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_nopmi_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13);
+      break;
+
+    case HLC_subband_cqi_rank1_2A:
+      ((HLC_subband_cqi_rank1_2A_20MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank1_2A_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13);
+      ((HLC_subband_cqi_rank1_2A_20MHz *)o)->pmi      = quantize_wideband_pmi(meas,eNB_id);
+      break;
+
+    case HLC_subband_cqi_rank2_2A:
+      // This has to be improved!!!
+      ((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13);
+      ((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi2     = sinr2cqi(sinr_tmp,trans_mode);
+      ((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,13);
+      ((HLC_subband_cqi_rank2_2A_20MHz *)o)->pmi      = quantize_subband_pmi(meas,eNB_id,13);
+      break;
+
+    case HLC_subband_cqi_mcs_CBA:
+      // this is the cba mcs uci for cba transmission
+      ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->mcs     = ulsch->harq_processes[harq_pid]->mcs;
+      ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti  = rnti;
+      LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs);
+      break;
+
+    case ue_selected:
+      LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n");
+      mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!");
+      break;
+
+    default:
+      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
+      mac_xface->macphy_exit("unsupported CQI mode !!!");
+      break;
+
+    }
+
+    break;
+
+  }
+
+
+}
+
+void reset_cba_uci(void *o)
+{
+  // this is the cba mcs uci for cba transmission
+  ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs     = 0; //fixme
+  ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti  = 0x0;
+}
+
+
+uint32_t pmi_extend(NR_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank)
+{
+
+  uint8_t i,wideband_pmi2;
+  uint32_t pmi_ex = 0;
+
+  if (frame_parms->N_RB_DL!=25) {
+    LOG_E(PHY,"pmi_extend not yet implemented for anything else than 25PRB\n");
+    return(-1);
+  }
+
+  if (rank==0) {
+    wideband_pmi2=wideband_pmi&3;
+    for (i=0; i<14; i+=2)
+      pmi_ex|=(wideband_pmi2<<i);
+  }
+  else if (rank==1) {
+    wideband_pmi2=wideband_pmi&1;
+    for (i=0; i<7; i++)
+      pmi_ex|=(wideband_pmi2<<i);
+  }
+  else {
+    LOG_E(PHY,"unsupported rank\n");
+    return(-1);
+  }
+
+  return(pmi_ex);
+}
+
+
+int generate_ue_ulsch_params_from_dci(void *dci_pdu,
+                                      uint16_t rnti,
+                                      uint8_t nr_tti_rx,
+                                      DCI_format_t dci_format,
+                                      PHY_VARS_NR_UE *ue,
+                                      UE_nr_rxtx_proc_t *proc,
+                                      uint16_t si_rnti,
+                                      uint16_t ra_rnti,
+                                      uint16_t p_rnti,
+                                      uint16_t cba_rnti,
+                                      uint8_t eNB_id,
+                                      uint8_t use_srs)
+{
+
+  uint8_t harq_pid;
+  uint8_t transmission_mode = ue->transmission_mode[eNB_id];
+  ANFBmode_t AckNackFBMode;
+  NR_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id];
+  NR_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][0];
+  PHY_MEASUREMENTS *meas = &ue->measurements;
+  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  //  uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id];
+
+  if(frame_parms->frame_type == TDD)
+  {
+      AckNackFBMode = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
+  }
+  else
+  {
+      AckNackFBMode = 1; // 1: multiplexing for FDD
+  }
+
+  uint32_t cqi_req;
+  uint32_t dai=3;
+  uint32_t cshift;
+  uint32_t TPC;
+  uint32_t ndi;
+  uint32_t mcs;
+  uint32_t rballoc,RIV_max;
+  uint16_t* RIV2first_rb_LUT;
+  uint16_t* RIV2nb_rb_LUT;
+
+  //  uint32_t hopping;
+  //  uint32_t type;
+
+  if (dci_format == format0) {
+
+    if (!ulsch)
+      return -1;
+
+    if (rnti == ra_rnti)
+      harq_pid = 0;
+    else
+      harq_pid = nr_subframe2harq_pid(frame_parms,
+                                   nr_pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,nr_tti_rx),
+                                   nr_pdcch_alloc2ul_subframe(frame_parms,nr_tti_rx));
+
+    if (harq_pid == 255) {
+      LOG_E(PHY, "frame %d, nr_tti_rx %d, rnti %x, format %d: illegal harq_pid!\n",
+            proc->frame_rx, nr_tti_rx, rnti, dci_format);
+      return(-1);
+    }
+
+    switch (frame_parms->N_RB_DL) {
+    case 6:
+      if (frame_parms->frame_type == TDD) {
+        cqi_req = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
+        dai     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai;
+        cshift  = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        ndi     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi;
+        mcs     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type;
+      } else {
+        cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req;
+        cshift  = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC;
+        ndi     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->ndi;
+        mcs     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type;
+      }
+
+      RIV_max = RIV_max6;
+      RIV2first_rb_LUT = RIV2first_rb_LUT6;
+      RIV2nb_rb_LUT = RIV2nb_rb_LUT6;
+
+      break;
+
+    case 25:
+      if (frame_parms->frame_type == TDD) {
+        cqi_req = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
+        dai     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai;
+        cshift  = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        ndi     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi;
+        mcs     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type;
+      } else {
+        cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req;
+        cshift  = ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC;
+        ndi     = ((DCI0_5MHz_FDD_t *)dci_pdu)->ndi;
+        mcs     = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_5MHz_FDD_t *)dci_pdu)->type;
+      }
+
+      RIV_max = RIV_max25;
+      RIV2first_rb_LUT = RIV2first_rb_LUT25;
+      RIV2nb_rb_LUT = RIV2nb_rb_LUT25;
+      //      printf("***********rballoc %d, first_rb %d, nb_rb %d (dci %p)\n",rballoc,ulsch->harq_processes[harq_pid]->first_rb,ulsch->harq_processes[harq_pid]->nb_rb,dci_pdu);
+      break;
+
+    case 50:
+      if (frame_parms->frame_type == TDD) {
+        cqi_req = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
+        dai     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai;
+        cshift  = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        ndi     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->ndi;
+        mcs     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type;
+      } else {
+        cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req;
+        cshift  = ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC;
+        ndi     = ((DCI0_10MHz_FDD_t *)dci_pdu)->ndi;
+        mcs     = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_10MHz_FDD_t *)dci_pdu)->type;
+      }
+
+      RIV_max = RIV_max50;
+      RIV2first_rb_LUT = RIV2first_rb_LUT50;
+      RIV2nb_rb_LUT = RIV2nb_rb_LUT50;
+
+      break;
+
+    case 100:
+      if (frame_parms->frame_type == TDD) {
+        cqi_req = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
+        dai     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai;
+        cshift  = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        ndi     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->ndi;
+        mcs     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type;
+      } else {
+        cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req;
+        cshift  = ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC;
+        ndi     = ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi;
+        mcs     = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_20MHz_FDD_t *)dci_pdu)->type;
+      }
+
+      RIV_max = RIV_max100;
+      RIV2first_rb_LUT = RIV2first_rb_LUT100;
+      RIV2nb_rb_LUT = RIV2nb_rb_LUT100;
+
+      //      printf("rb_alloc (20 MHz dci) %d\n",rballoc);
+      break;
+
+    default:
+      LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+      DevParam (frame_parms->N_RB_DL, 0, 0);
+      break;
+    }
+
+
+    if (rballoc > RIV_max) {
+      LOG_E(PHY,"frame %d, nr_tti_rx %d, rnti %x, format %d: FATAL ERROR: generate_ue_ulsch_params_from_dci, rb_alloc[%d] > RIV_max[%d]\n",
+            proc->frame_rx, nr_tti_rx, rnti, dci_format,rballoc,RIV_max);
+      LOG_E(PHY,"Wrong DCI0 detection, do not transmit PUSCH for HARQID: %d\n",harq_pid);
+      ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+      return(-1);
+    }
+
+
+    // indicate that this process is to be serviced in subframe n+4
+    if ((rnti >= cba_rnti) && (rnti < p_rnti))
+      ulsch->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1; //+=1 this indicates the number of dci / cba group: not supported in the data struct
+    else
+    {
+        ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+        //LOG_I(PHY,"[HARQ-UL harqId: %d] DCI0 ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
+
+    }
+
+    ulsch->harq_processes[harq_pid]->TPC                                   = TPC;
+    ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT[rballoc];
+    ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT[rballoc];
+
+    if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) {
+      LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d nr_tti_rx %d: f_pusch (ACC) %d, adjusting by %d (TPC %d)\n",
+            ue->Mod_id,harq_pid,proc->frame_rx,nr_tti_rx,ulsch->f_pusch,
+            delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC],
+            ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC);
+      ulsch->f_pusch += delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC];
+    } else {
+      LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d nr_tti_rx %d: f_pusch (ABS) %d, adjusting to %d (TPC %d)\n",
+            ue->Mod_id,harq_pid,proc->frame_rx,nr_tti_rx,ulsch->f_pusch,
+            delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC],
+            ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC);
+      ulsch->f_pusch = delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC];
+    }
+
+    if (ulsch->harq_processes[harq_pid]->first_tx==1) {
+      //      ulsch->harq_processes[harq_pid]->Ndi                                   = 1;
+      ulsch->harq_processes[harq_pid]->first_tx=0;
+      ulsch->harq_processes[harq_pid]->DCINdi= ndi;
+      ulsch->harq_processes[harq_pid]->round = 0;
+    } else {
+      if (ulsch->harq_processes[harq_pid]->DCINdi!=ndi) { // new SDU opportunity
+        //  ulsch->harq_processes[harq_pid]->Ndi = 1;
+        ulsch->harq_processes[harq_pid]->DCINdi= ndi;
+        ulsch->harq_processes[harq_pid]->round = 0;
+      } else {
+        //  ulsch->harq_processes[harq_pid]->Ndi = 0;
+        //ulsch->harq_processes[harq_pid]->round++;  // This is done in phich RX
+
+        //#ifdef DEBUG_PHICH
+        //LOG_I(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d Adaptative Retrans, NDI not toggled => Nack. maxHARQ_Tx %d \n",
+        //      ue->Mod_id,harq_pid,
+        //      proc->frame_rx,
+        //      subframe,
+        //      ulsch->Mlimit);
+        //#endif
+/*
+        if (ulsch->harq_processes[harq_pid]->round > 0) // NACK detected on phich
+        {
+            // ulsch->harq_processes[harq_pid]->round++; already done on phich_rx
+            // ulsch->harq_processes[harq_pid] = ulsch->harq_processes[8];
+            // LOG_I(PHY,"          Adaptative retransmission - copy temporary harq Process to current harq process. [harqId %d round %d] \n",harq_pid, ulsch->harq_processes[8]->round);
+
+            if (ulsch->harq_processes[harq_pid]->round >= ulsch->Mlimit) //UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx)
+            {
+                ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+                ulsch->harq_processes[harq_pid]->round  = 0;
+                ulsch->harq_processes[harq_pid]->status = IDLE;
+                //LOG_I(PHY,"          PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid);
+                //LOG_I(PHY,"          [HARQ-UL harqId: %d] Adaptative retransmission NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
+            }
+            else
+            {
+                // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+                uint8_t rv_table[4] = {0, 2, 3, 1};
+                ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3];
+                ulsch->O_RI = 0;
+                ulsch->O    = 0;
+                ulsch->uci_format = HLC_subband_cqi_nopmi;
+                //LOG_I(PHY,"          [HARQ-UL harqId: %d] Adaptative retransmission NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round);
+            }
+        }
+*/
+      }
+    }
+
+    ulsch->harq_processes[harq_pid]->n_DMRS                                = cshift;
+
+    //printf("nb_rb %d, first_rb %d (RIV %d)\n",ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb,rballoc);
+    if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+      // ulsch->cba_rnti[0]=rnti;
+    } else {
+      ulsch->rnti = rnti;
+    }
+
+    //    printf("[PHY][UE] DCI format 0: harq_pid %d nb_rb %d, rballoc %d\n",harq_pid,ulsch->harq_processes[harq_pid]->nb_rb,
+    //     ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc);
+    //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1)
+    if(cshift == 0)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 0;
+    else if(cshift == 1)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 6;
+    else if(cshift == 2)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 3;
+    else if(cshift == 3)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 4;
+    else if(cshift == 4)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 2;
+    else if(cshift == 5)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 8;
+    else if(cshift == 6)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 10;
+    else if(cshift == 7)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 9;
+
+
+    //reserved for cooperative communication
+    /*
+      if(ulsch->n_DMRS2 == 6)
+      ulsch->cooperation_flag = 2;
+      else
+      ulsch->cooperation_flag = 0;
+    */
+
+    if ((ulsch->harq_processes[harq_pid]->nb_rb>0) && (ulsch->harq_processes[harq_pid]->nb_rb < 25))
+      ulsch->power_offset = ue_power_offsets[ulsch->harq_processes[harq_pid]->nb_rb-1];
+
+    //    if (ulsch->harq_processes[harq_pid]->Ndi == 1)
+    //    ulsch->harq_processes[harq_pid]->status = ACTIVE;
+
+
+    if (cqi_req == 1) {
+
+      if( (AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) )
+      {
+          ulsch->O_RI = 1;
+      }
+      else
+      {
+          ulsch->O_RI = 0;
+      }
+      //ulsch->O_RI = 0; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table
+
+      switch(transmission_mode) {
+        // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling
+      case 1:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
+          ulsch->o_RI[0]                             = 0;
+        } else  if(meas->rank[eNB_id] == 0) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
+          ulsch->o_RI[0]                             = 0;
+        } else {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
+          ulsch->o_RI[0]                             = 1;
+        }
+
+        break;
+
+      case 2:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
+          ulsch->o_RI[0]                             = 0;
+        } else if(meas->rank[eNB_id] == 0) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
+          ulsch->o_RI[0]                             = 0;
+        } else {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
+          ulsch->o_RI[0]                             = 1;
+        }
+
+        break;
+
+      case 3:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
+          ulsch->o_RI[0]                             = 0;
+        } else if(meas->rank[eNB_id] == 0) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
+          ulsch->o_RI[0]                             = 0;
+        } else {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
+          ulsch->o_RI[0]                             = 1;
+        }
+
+        break;
+
+      case 4:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
+          ulsch->o_RI[0]                             = 0;
+        } else if(meas->rank[eNB_id] == 0) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = wideband_cqi_rank1_2A;
+          ulsch->o_RI[0]                             = 0;
+        } else {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = wideband_cqi_rank2_2A;
+          ulsch->o_RI[0]                             = 1;
+        }
+
+        break;
+
+      case 5:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
+          ulsch->o_RI[0]                             = 0;
+        } else if(meas->rank[eNB_id] == 0) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = wideband_cqi_rank1_2A;
+          ulsch->o_RI[0]                             = 0;
+        } else {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = wideband_cqi_rank2_2A;
+          ulsch->o_RI[0]                             = 1;
+        }
+
+        break;
+
+      case 6:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
+          ulsch->o_RI[0]                             = 0;
+        } else if(meas->rank[eNB_id] == 0) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = wideband_cqi_rank1_2A;
+          ulsch->o_RI[0]                             = 0;
+        } else {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = wideband_cqi_rank2_2A;
+          ulsch->o_RI[0]                             = 1;
+        }
+
+        break;
+
+      case 7:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
+          ulsch->o_RI[0]                             = 0;
+        } else if(meas->rank[eNB_id] == 0) {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
+          ulsch->o_RI[0]                             = 0;
+        } else {
+          switch (ue->frame_parms.N_RB_DL) {
+          case 6:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
+          ulsch->o_RI[0]                             = 1;
+        }
+
+        break;
+
+      default:
+        LOG_E(PHY,"Incorrect Transmission Mode \n");
+        break;
+      }
+    } else {
+      ulsch->O_RI = 0;
+      ulsch->O                                   = 0;
+      ulsch->uci_format                          = HLC_subband_cqi_nopmi;
+    }
+
+    print_CQI(ulsch->o,ulsch->uci_format,eNB_id,ue->frame_parms.N_RB_DL);
+
+    ulsch->bundling = 1-AckNackFBMode;
+
+    if (frame_parms->frame_type == FDD) {
+      //int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4);
+      int dl_tti = nr_tti_rx;
+
+      if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_ack[dl_tti].send_harq_status>0) { // we have downlink transmission
+        ulsch->harq_processes[harq_pid]->O_ACK = 1;
+      } else {
+        ulsch->harq_processes[harq_pid]->O_ACK = 0;
+      }
+      /*LOG_I(PHY,"DCI 0 Processing: dl_subframe %d send_harq_status Odd %d send_harq_status Even %d harq_pid %d O_ACK %d\n", dl_subframe,
+              ue->dlsch[0][eNB_id][0]->harq_ack[dl_subframe].send_harq_status,
+              ue->dlsch[1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status,
+              harq_pid,
+              ulsch->harq_processes[harq_pid]->O_ACK);*/
+
+    } else {
+      if (ulsch->bundling)
+        ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1;
+      else
+        ulsch->harq_processes[harq_pid]->O_ACK = (dai >= 2)? 2 : (dai+1)&3; //(dai+1)&3;
+
+      //      ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1;
+    }
+
+    dlsch[0]->harq_ack[nr_tti_rx].vDAI_UL = dai+1;
+
+
+    /*LOG_I(PHY, "[PUSCH %d] Format0 DCI %s, CQI_req=%d, cshift=%d, TPC=%d, DAI=%d, vDAI_UL[sf#%d]=%d, NDI=%d, MCS=%d, RBalloc=%d, first_rb=%d, harq_pid=%d, nb_rb=%d, subframe_scheduling_flag=%d"
+            "   ulsch->bundling %d, O_ACK %d \n",
+        harq_pid,
+        (frame_parms->frame_type == TDD? "TDD" : "FDD"),
+        cqi_req, cshift, TPC, dai, subframe, dlsch[0]->harq_ack[subframe].vDAI_UL, ndi, mcs, rballoc,
+        ulsch->harq_processes[harq_pid]->first_rb, harq_pid, ulsch->harq_processes[harq_pid]->nb_rb,
+        ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,
+        ulsch->bundling,
+        ulsch->harq_processes[harq_pid]->O_ACK);*/
+
+    ulsch->beta_offset_cqi_times8                = beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index];//18;
+    ulsch->beta_offset_ri_times8                 = beta_ri[ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index];//10;
+    ulsch->beta_offset_harqack_times8            = beta_ack[ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index];//16;
+
+    ulsch->Nsymb_pusch                             = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1);
+    ulsch->srs_active                              = use_srs;
+
+    if ((rnti >= cba_rnti) && (rnti < p_rnti))
+      ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE;
+    else
+      ulsch->harq_processes[harq_pid]->status = ACTIVE;
+
+    ulsch->harq_processes[harq_pid]->rvidx = 0;
+
+    //      ulsch->harq_processes[harq_pid]->calibration_flag =0;
+    if (mcs < 29) {
+      ulsch->harq_processes[harq_pid]->mcs = mcs;
+      // ulsch->harq_processes[harq_pid]->round = 0;
+    } else {
+      ulsch->harq_processes[harq_pid]->rvidx = mcs - 28;
+      if (ulsch->harq_processes[harq_pid]->round == 0) {
+        LOG_W(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round);
+      } else {
+        LOG_D(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round);
+      }
+      //LOG_E(PHY,"Fatal: mcs(%d) > 28!!! and round == 0\n", mcs);
+    }
+    ulsch->harq_processes[harq_pid]->TBS = TBStableUL[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1];
+
+    /*
+       else if (ulsch->harq_processes[harq_pid]->mcs == 29) {
+       ulsch->harq_processes[harq_pid]->mcs = 4;
+       ulsch->harq_processes[harq_pid]->TBS         = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1];
+    // ulsch->harq_processes[harq_pid]->calibration_flag =1;
+    // printf("Auto-Calibration (UE): mcs %d, TBS %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->TBS,ulsch->harq_processes[harq_pid]->nb_rb);
+    }*/
+    ulsch->harq_processes[harq_pid]->Msc_initial   = 12*ulsch->harq_processes[harq_pid]->nb_rb;
+    ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->Nsymb_pusch;
+
+    // a Ndi=1 automatically acknowledges previous PUSCH transmission
+    if (ue->ulsch_Msg3_active[eNB_id] == 1)
+      ue->ulsch_Msg3_active[eNB_id] = 0;
+
+    LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d, nr_tti_rx %d : Programming PUSCH with n_DMRS2 %d (cshift %d), nb_rb %d, first_rb %d, mcs %d, round %d, rv %d, ulsch_ue_Msg3_active %d\n",
+        ue->Mod_id,harq_pid,
+        proc->frame_rx,nr_tti_rx,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb,
+        ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->rvidx, ue->ulsch_Msg3_active[eNB_id]);
+
+  // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
+
+//printf("Format 0 DCI : ulsch (ue): AbsSubframe  %d.%d nrb %d harq_pid %d round %d mcs %d\n",proc->frame_rx%1024,nr_tti_rx,ulsch->harq_processes[harq_pid]->nb_rb,
+ //       harq_pid,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->mcs);
+
+#ifdef UE_DEBUG_TRACE
+
+    LOG_I(PHY,"Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,nr_tti_rx);
+    LOG_D(PHY,"Format 0 DCI : ulsch (ue): NBRB        %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_rb    %d\n",ulsch->harq_processes[harq_pid]->first_rb);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): rballoc     %d\n",rballoc);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): harq_pid    %d\n",harq_pid);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_tx       %d\n",ulsch->harq_processes[harq_pid]->first_tx);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): DCINdi       %d\n",ulsch->harq_processes[harq_pid]->DCINdi);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): round       %d\n",ulsch->harq_processes[harq_pid]->round);
+    //LOG_I(PHY,"Format 0 DCI :ulsch (ue): TBS         %d\n",ulsch->harq_processes[harq_pid]->TBS);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): mcs         %d\n",ulsch->harq_processes[harq_pid]->mcs);
+    //LOG_I(PHY,"Format 0 DCI :ulsch (ue): O           %d\n",ulsch->O);
+    //LOG_I(PHY,"Format 0 DCI :ulsch (ue): cqiReq      %d\n",cqi_req);
+    //if (frame_parms->frame_type == TDD)
+    //  LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK/DAI   %d/%d\n",ulsch->harq_processes[harq_pid]->O_ACK,dai);
+    //else
+    //  LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK       %d\n",ulsch->harq_processes[harq_pid]->O_ACK);
+
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): Nsymb_pusch   %d\n",ulsch->Nsymb_pusch);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): cshift        %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): phich status  %d\n",ulsch->harq_processes[harq_pid]->status);
+#else
+    UNUSED_VARIABLE(dai);
+#endif
+    return(0);
+  } else {
+    LOG_E(PHY,"frame %d, nr_tti_rx %d: FATAL ERROR, generate_ue_ulsch_params_from_dci, Illegal dci_format %d\n",
+          proc->frame_rx, nr_tti_rx,dci_format);
+    return(-1);
+  }
+
+}
+
+int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
+                                       eNB_rxtx_proc_t *proc,
+                                       void *dci_pdu,
+                                       uint16_t rnti,
+                                       DCI_format_t dci_format,
+                                       uint8_t UE_id,
+                                       uint16_t si_rnti,
+                                       uint16_t ra_rnti,
+                                       uint16_t p_rnti,
+                                       uint16_t cba_rnti,
+                                       uint8_t use_srs)
+{
+
+  uint8_t harq_pid;
+  uint32_t rb_alloc;
+  uint8_t transmission_mode=eNB->transmission_mode[UE_id];
+  ANFBmode_t AckNackFBMode = eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode;
+  LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id];
+  NR_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
+  int subframe = proc->subframe_tx;
+
+  uint32_t cqi_req = 0;
+  uint32_t dai = 0;
+  uint32_t cshift = 0;
+  uint32_t TPC = 0;
+  uint32_t mcs = 0;
+  uint32_t rballoc = UINT32_MAX;
+  uint32_t RIV_max = 0;
+  //  uint32_t hopping;
+  //  uint32_t type;
+
+#ifdef DEBUG_DCI
+  printf("filling eNB ulsch params for rnti %x, dci format %d, dci %x, subframe %d\n",
+        rnti,dci_format,*(uint32_t*)dci_pdu,subframe);
+#endif
+
+  if (dci_format == format0) {
+
+    harq_pid = nr_subframe2harq_pid(frame_parms,
+                                 nr_pdcch_alloc2ul_frame(frame_parms,
+                                                      proc->frame_tx,
+                                                      subframe),
+                                 nr_pdcch_alloc2ul_subframe(frame_parms,subframe));
+    switch (frame_parms->N_RB_DL) {
+    case 6:
+      if (frame_parms->frame_type == TDD) {
+        cqi_req = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
+        dai     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai;
+        cshift  = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        mcs     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type;
+      } else {
+        cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req;
+        cshift  = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC;
+        mcs     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type;
+      }
+
+      RIV_max = RIV_max6;
+      ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT6[rballoc];
+      ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT6[rballoc];
+
+      break;
+
+    case 25:
+      if (frame_parms->frame_type == TDD) {
+        cqi_req = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
+        dai     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai;
+        cshift  = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        mcs     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type;
+      } else {
+        cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req;
+        cshift  = ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC;
+        mcs     = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_5MHz_FDD_t *)dci_pdu)->type;
+      }
+
+      RIV_max = RIV_max25;
+      ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT25[rballoc];
+      ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT25[rballoc];
+
+      break;
+
+    case 50:
+      if (frame_parms->frame_type == TDD) {
+        cqi_req = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
+        dai     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai;
+        cshift  = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        mcs     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type;
+      } else {
+        cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req;
+        cshift  = ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC;
+        mcs     = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_10MHz_FDD_t *)dci_pdu)->type;
+      }
+
+      RIV_max = RIV_max50;
+      ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT50[rballoc];
+      ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT50[rballoc];
+
+      break;
+
+    case 100:
+      if (frame_parms->frame_type == TDD) {
+        cqi_req = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
+        dai     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai;
+        cshift  = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC;
+        mcs     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type;
+      } else {
+        cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req;
+        cshift  = ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift;
+        TPC     = ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC;
+        mcs     = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs;
+        rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc;
+        //  hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping;
+        //  type    = ((DCI0_20MHz_FDD_t *)dci_pdu)->type;
+      }
+
+      RIV_max = RIV_max100;
+      ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT100[rballoc];
+      ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT100[rballoc];
+
+      //printf("eNB: rb_alloc (20 MHz dci) %d\n",rballoc);
+      break;
+
+    default:
+      LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+      DevParam (frame_parms->N_RB_DL, 0, 0);
+      break;
+    }
+
+    rb_alloc = rballoc;
+
+    if (rb_alloc>RIV_max) {
+      LOG_E(PHY,"Format 0: rb_alloc (%d) > RIV_max (%d)\n",rb_alloc,RIV_max);
+      mac_xface->macphy_exit("Format 0: error");
+      return(-1);
+    }
+
+#ifdef DEBUG_DCI
+    printf("generate_eNB_ulsch_params_from_dci: subframe %d, rnti %x,harq_pid %d,cqi_req %d\n",subframe,rnti,harq_pid,cqi_req);
+#endif
+
+    ulsch->harq_processes[harq_pid]->dci_alloc                             = 1;
+    ulsch->harq_processes[harq_pid]->rar_alloc                             = 0;
+    ulsch->harq_processes[harq_pid]->TPC                                   = TPC;
+    ulsch->harq_processes[harq_pid]->n_DMRS                                = cshift;
+
+
+    if (cqi_req == 1) {
+      /* 36.213 7.2.1 (release 10) says:
+       * "RI is only reported for transmission modes 3 and 4,
+       * as well as transmission modes 8 and 9 with PMI/RI reporting"
+       * This is for aperiodic reporting.
+       * TODO: deal with TM 8&9 correctly when they are implemented.
+       * TODO: deal with periodic reporting if we implement it.
+       */
+      if (transmission_mode == 3 || transmission_mode == 4)
+        ulsch->harq_processes[harq_pid]->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table
+      else
+        ulsch->harq_processes[harq_pid]->O_RI = 0;
+
+      switch(transmission_mode) {
+        // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling
+      case 1:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
+        } else {
+          ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
+        }
+
+        break;
+
+      case 2:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
+        } else {
+          ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
+        }
+
+        break;
+
+      case 3:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
+        } else {
+          ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
+        }
+
+        break;
+
+      case 4:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
+        } else {
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_1_5MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_5MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_10MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_20MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_20MHz;
+            break;
+
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                          = wideband_cqi_rank1_2A;
+        }
+
+        break;
+
+      case 5:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
+        } else {
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_1_5MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_5MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_10MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_20MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                          = wideband_cqi_rank1_2A;
+        }
+
+        break;
+
+      case 6:
+        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+          ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
+        } else {
+          switch (frame_parms->N_RB_DL) {
+          case 6:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_1_5MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_1_5MHz;
+            break;
+
+          case 25:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_5MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_5MHz;
+            break;
+
+          case 50:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_10MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_10MHz;
+            break;
+
+          case 100:
+            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_20MHz;
+            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_20MHz;
+            break;
+          }
+
+          ulsch->harq_processes[harq_pid]->uci_format                          = wideband_cqi_rank1_2A;
+        }
+
+        break;
+
+      case 7:
+        ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+
+        switch (frame_parms->N_RB_DL) {
+        case 6:
+          ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
+          break;
+
+        case 25:
+          ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
+          break;
+
+        case 50:
+          ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
+          break;
+
+        case 100:
+          ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
+          break;
+        }
+
+        ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
+        break;
+
+      default:
+        LOG_E(PHY,"Incorrect Transmission Mode \n");
+        break;
+      }
+    } else {
+      ulsch->harq_processes[harq_pid]->O_RI = 0;
+      ulsch->harq_processes[harq_pid]->Or2                                   = 0;
+      ulsch->harq_processes[harq_pid]->Or1                                   = 0;
+      ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
+    }
+
+    ulsch->bundling = 1-AckNackFBMode;
+
+    if (frame_parms->frame_type == FDD) {
+      int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4);
+
+      if (eNB->dlsch[UE_id][0]->subframe_tx[dl_subframe]>0) { // we have downlink transmission
+        ulsch->harq_processes[harq_pid]->O_ACK = 1;
+      } else {
+        ulsch->harq_processes[harq_pid]->O_ACK = 0;
+      }
+    } else {
+      if (ulsch->bundling)
+        ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1;
+      else
+        ulsch->harq_processes[harq_pid]->O_ACK = (dai+1)&3;
+
+      ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1;
+    }
+
+    ulsch->beta_offset_cqi_times8                = beta_cqi[eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index];//18;
+    ulsch->beta_offset_ri_times8                 = beta_ri[eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index];//10;
+    ulsch->beta_offset_harqack_times8            = beta_ack[eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index];//16;
+
+    ulsch->harq_processes[harq_pid]->Nsymb_pusch                             = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1);
+    ulsch->harq_processes[harq_pid]->srs_active                            = use_srs;
+
+    //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1)
+    if(cshift == 0)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 0;
+    else if(cshift == 1)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 6;
+    else if(cshift == 2)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 3;
+    else if(cshift == 3)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 4;
+    else if(cshift == 4)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 2;
+    else if(cshift == 5)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 8;
+    else if(cshift == 6)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 10;
+    else if(cshift == 7)
+      ulsch->harq_processes[harq_pid]->n_DMRS2 = 9;
+
+
+    LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d)\n",
+          eNB->Mod_id,harq_pid,proc->frame_tx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift);
+
+
+
+    if (ulsch->harq_processes[harq_pid]->round == 0) {
+      if ((rnti >= cba_rnti) && (rnti < p_rnti))
+        ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE;
+      else
+        ulsch->harq_processes[harq_pid]->status = ACTIVE;
+
+      ulsch->harq_processes[harq_pid]->rvidx = 0;
+      ulsch->harq_processes[harq_pid]->mcs         = mcs;
+      //      ulsch->harq_processes[harq_pid]->calibration_flag = 0;
+      //if (ulsch->harq_processes[harq_pid]->mcs)
+      /*
+      if (ulsch->harq_processes[harq_pid]->mcs == 29) {
+      ulsch->harq_processes[harq_pid]->mcs = 4;
+      // ulsch->harq_processes[harq_pid]->calibration_flag = 1;
+      // printf("Auto-Calibration (eNB): mcs %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->nb_rb);
+      }
+      */
+      ulsch->harq_processes[harq_pid]->TBS         = TBStableUL[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1];
+
+      ulsch->harq_processes[harq_pid]->Msc_initial   = 12*ulsch->harq_processes[harq_pid]->nb_rb;
+      ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch;
+      ulsch->harq_processes[harq_pid]->round = 0;
+    } else {
+      if (mcs>28)
+        ulsch->harq_processes[harq_pid]->rvidx = mcs - 28;
+      else {
+        ulsch->harq_processes[harq_pid]->rvidx = 0;
+        ulsch->harq_processes[harq_pid]->mcs = mcs;
+      }
+
+      //      ulsch->harq_processes[harq_pid]->round++;
+    }
+
+    if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
+      ulsch->cba_rnti[0] = rnti;
+    } else {
+      ulsch->rnti = rnti;
+    }
+
+    //ulsch->n_DMRS2 = cshift;
+
+#ifdef DEBUG_DCI
+    printf("ulsch (eNB): NBRB          %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
+    printf("ulsch (eNB): first_rb      %d\n",ulsch->harq_processes[harq_pid]->first_rb);
+    printf("ulsch (eNB): harq_pid      %d\n",harq_pid);
+    printf("ulsch (eNB): round         %d\n",ulsch->harq_processes[harq_pid]->round);
+    printf("ulsch (eNB): TBS           %d\n",ulsch->harq_processes[harq_pid]->TBS);
+    printf("ulsch (eNB): mcs           %d\n",ulsch->harq_processes[harq_pid]->mcs);
+    printf("ulsch (eNB): Or1           %d\n",ulsch->harq_processes[harq_pid]->Or1);
+    printf("ulsch (eNB): Nsymb_pusch   %d\n",ulsch->harq_processes[harq_pid]->Nsymb_pusch);
+    printf("ulsch (eNB): cshift        %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
+#else
+    UNUSED_VARIABLE(dai);
+#endif
+    return(0);
+  } else {
+    LOG_E(PHY,"generate_eNB_ulsch_params_from_dci, Illegal dci_format %d\n",dci_format);
+    return(-1);
+  }
+
+}
+
+
+double sinr_eff_cqi_calc(PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t nr_tti_rx)
+{
+  uint8_t transmission_mode = ue->transmission_mode[eNB_id];
+  PHY_MEASUREMENTS *meas = &ue->measurements;
+  NR_DL_FRAME_PARMS *frame_parms =  &ue->frame_parms;
+  int32_t **dl_channel_est = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id];
+  double *s_dB;
+  s_dB = ue->sinr_CQI_dB;
+  //  NR_UE_ULSCH_t *ulsch  = ue->ulsch[eNB_id];
+  //for the calculation of SINR_eff for CQI calculation
+  int count,a_rx,a_tx;
+  double abs_channel=0;
+  double channelx=0;
+  double channely=0;
+  double channelx_i=0;
+  double channely_i=0;
+  uint16_t q = quantize_subband_pmi(meas,eNB_id,7);
+  uint8_t qq;
+
+  switch(transmission_mode) {
+  case 1:
+    for (count=0; count<frame_parms->N_RB_DL*12; count++) {
+      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
+        for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
+          s_dB[count] = 10*log10(pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2],
+                                 2)) - meas->n0_power_avg_dB;
+        }
+      }
+    }
+
+    break;
+
+  case 2:
+    for (count=0; count<frame_parms->N_RB_DL*12; count++) {
+      abs_channel=0;
+
+      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
+        for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
+          abs_channel += (pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2],2));
+        }
+      }
+
+      s_dB[count] = 10*log10(abs_channel/2) - meas->n0_power_avg_dB;
+    }
+
+    break;
+
+  case 5:
+    for (count=0; count<frame_parms->N_RB_DL*12; count++) {
+      channelx=0;
+      channely=0;
+      channelx_i=0;
+      channely_i=0;
+      qq = (q>>(((count/12)>>2)<<1))&3;
+
+      //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq);
+      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
+        for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
+          switch(qq) {
+          case 0:
+            if (channelx==0 || channely==0) {
+              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            } else {
+              channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channelx_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            }
+
+            break;
+
+          case 1:
+            if (channelx==0 || channely==0) {
+              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            } else {
+              channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channelx_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            }
+
+            break;
+
+          case 2:
+            if (channelx==0 || channely==0) {
+              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            } else {
+              channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channelx_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channely_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+            }
+
+            break;
+
+          case 3:
+            if (channelx==0 || channely==0) {
+              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            } else {
+              channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channelx_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channely_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+            }
+
+            break;
+
+          default:
+            printf("Problem in SINR Calculation for TM5 \n");
+            break;
+          }//switch(qq)
+        }//a_rx
+      }//a_tx
+
+      s_dB[count] =  10 * log10 ((pow(channelx,2) + pow(channely,2))/2) - 10 * log10 ((pow(channelx_i,2) + pow(channely_i,2))/2) - meas->n0_power_avg_dB;
+    }//count
+
+    break;
+
+  case 6:
+    for (count=0; count<frame_parms->N_RB_DL*12; count++) {
+      channelx=0;
+      channely=0;
+      qq = (q>>(((count/12)>>2)<<1))&3;
+
+      //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq);
+      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
+        for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
+          switch(qq) {
+          case 0:
+            if (channelx==0 || channely==0) {
+              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            } else {
+              channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            }
+
+            break;
+
+          case 1:
+            if (channelx==0 || channely==0) {
+              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            } else {
+              channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            }
+
+            break;
+
+          case 2:
+            if (channelx==0 || channely==0) {
+              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            } else {
+              channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+            }
+
+            break;
+
+          case 3:
+            if (channelx==0 || channely==0) {
+              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+            } else {
+              channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
+              channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
+            }
+
+            break;
+
+          default:
+            printf("Problem in SINR Calculation for TM6 \n");
+            break;
+          }//switch(qq)
+        }//a_rx
+      }//a_tx
+
+      s_dB[count] =  10 * log10 ((pow(channelx,2) + pow(channely,2))/2) - meas->n0_power_avg_dB;
+    }//count
+
+    break;
+
+  default:
+    printf("Problem in SINR Calculation for CQI \n");
+    break;
+  }
+
+  int ii;
+  double sinr_eff = 0;
+  double sinr_eff_qpsk=0;
+  double sinr_eff_qam16=0;
+  double sinr_eff_qam64=0;
+  double x = 0;
+  double I_qpsk=0;
+  double I_qam16=0;
+  double I_qam64=0;
+  double I_qpsk_avg=0;
+  double I_qam16_avg=0;
+  double I_qam64_avg=0;
+  double qpsk_max=12.2;
+  double qam16_max=19.2;
+  double qam64_max=25.2;
+  double sinr_min = -20;
+  int offset=0;
+
+
+  for (offset = 0; offset <= 24; offset++) {
+    for(ii=0; ii<12; ii++) {
+      //x is the sinr_dB in dB
+      x = s_dB[(offset*12)+ii];
+
+      if(x<sinr_min) {
+        I_qpsk +=0;
+        I_qam16 +=0;
+        I_qam64 +=0;
+      } else {
+        if(x>qpsk_max)
+          I_qpsk += 1;
+        else
+          I_qpsk += (q_qpsk[0]*pow(x,7) + q_qpsk[1]*pow(x,6) + q_qpsk[2]*pow(x,5) + q_qpsk[3]*pow(x,4) + q_qpsk[4]*pow(x,3) + q_qpsk[5]*pow(x,2) + q_qpsk[6]*x + q_qpsk[7]);
+
+        if(x>qam16_max)
+          I_qam16 += 1;
+        else
+          I_qam16 += (q_qam16[0]*pow(x,7) + q_qam16[1]*pow(x,6) + q_qam16[2]*pow(x,5) + q_qam16[3]*pow(x,4) + q_qam16[4]*pow(x,3) + q_qam16[5]*pow(x,2) + q_qam16[6]*x + q_qam16[7]);
+
+        if(x>qam64_max)
+          I_qam64 += 1;
+        else
+          I_qam64 += (q_qam64[0]*pow(x,7) + q_qam64[1]*pow(x,6) + q_qam64[2]*pow(x,5) + q_qam64[3]*pow(x,4) + q_qam64[4]*pow(x,3) + q_qam64[5]*pow(x,2) + q_qam64[6]*x + q_qam64[7]);
+
+      }
+    }
+  }
+
+  // averaging of accumulated MI
+  I_qpsk_avg = I_qpsk/(12*frame_parms->N_RB_DL);
+  I_qam16_avg = I_qam16/(12*frame_parms->N_RB_DL);
+  I_qam64_avg = I_qam64/(12*frame_parms->N_RB_DL);
+
+  // I->SINR_effective Mapping
+
+  sinr_eff_qpsk = (p_qpsk[0]*pow(I_qpsk_avg,7) + p_qpsk[1]*pow(I_qpsk_avg,6) + p_qpsk[2]*pow(I_qpsk_avg,5) + p_qpsk[3]*pow(I_qpsk_avg,4) + p_qpsk[4]*pow(I_qpsk_avg,3) + p_qpsk[5]*pow(I_qpsk_avg,
+                   2) + p_qpsk[6]*I_qpsk_avg + p_qpsk[7]);
+
+  sinr_eff_qam16 = (p_qam16[0]*pow(I_qam16_avg,7) + p_qam16[1]*pow(I_qam16_avg,6) + p_qam16[2]*pow(I_qam16_avg,5) + p_qam16[3]*pow(I_qam16_avg,4) + p_qam16[4]*pow(I_qam16_avg,
+                    3) + p_qam16[5]*pow(I_qam16_avg,2) + p_qam16[6]*I_qam16_avg + p_qam16[7]);
+
+  sinr_eff_qam64 = (p_qam64[0]*pow(I_qam64_avg,7) + p_qam64[1]*pow(I_qam64_avg,6) + p_qam64[2]*pow(I_qam64_avg,5) + p_qam64[3]*pow(I_qam64_avg,4) + p_qam64[4]*pow(I_qam64_avg,
+                    3) + p_qam64[5]*pow(I_qam64_avg,2) + p_qam64[6]*I_qam64_avg + p_qam64[7]);
+  sinr_eff = cmax3(sinr_eff_qpsk,sinr_eff_qam16,sinr_eff_qam64);
+
+  //printf("SINR_Eff = %e\n",sinr_eff);
+
+  return(sinr_eff);
+}
+//
+
+
+#ifdef DEBUG_DLSCH_TOOLS
+main()
+{
+
+  int i;
+  uint8_t rah;
+  uint32_t rballoc;
+
+  generate_RIV_tables();
+
+  rah = 0;
+  rballoc = 0x1fff;
+  printf("rballoc 0 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
+  rah = 1;
+
+  rballoc = 0x1678;
+  printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
+
+  rballoc = 0xfffc;
+  printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
+  rballoc = 0xfffd;
+  printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
+  rballoc = 0xffff;
+  printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
+  rballoc = 0xfffe;
+  printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
+}
+
+#endif
+#endif //(0)
+
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index 3ff99c12d6f7a8d64dddba1884cf7fd1ff87853e..96806fbe82619a83870f748cbf5ccde5803d0fc8 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -328,8 +328,43 @@ typedef struct {
   int8_t               g_pucch;
 } NR_UE_DLSCH_t;
 
+typedef enum {format0_0,
+              format0_1,
+              format1_0,
+              format1_1,
+              format2_0,
+              format2_1,
+              format2_2,
+              format2_3
+             } NR_DCI_format_t;
 
 
+typedef enum {nr_pucch_format0=0,
+              nr_pucch_format1,
+              nr_pucch_format2,
+              nr_pucch_format3,
+              nr_pucch_format4
+             } NR_PUCCH_FMT_t;
+
+typedef struct {
+  /// Length of DCI in bits
+  uint8_t dci_length;
+  /// Aggregation level
+  uint8_t L;
+  /// Position of first CCE of the dci
+  int firstCCE;
+  /// flag to indicate that this is a RA response
+  boolean_t ra_flag;
+  /// rnti
+  rnti_t rnti;
+  /// Format
+  NR_DCI_format_t format;
+  /// search space
+  dci_space_t search_space;
+  /// DCI pdu
+  uint8_t dci_pdu[8];
+} NR_DCI_ALLOC_t;
+
 
 /**@}*/
 #endif
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index bf8020ecdae251e1adcdab1453759d7f779eabe8..3666bcf56b55de1252c586c4ffb20fe1620f9ed8 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -21,7 +21,7 @@
 
 /*! \file PHY/defs_nr_UE.h
  \brief Top-level defines and structure definitions for nr ue
- \author Guy De Souza, H. WANG
+ \author Guy De Souza, H. WANG, A. Mico Pereperez
  \date 2018
  \version 0.1
  \company Eurecom
@@ -140,7 +140,9 @@
 
 #endif
 
+#include "PHY/NR_UE_TRANSPORT/dci_nr.h"
 //#include "PHY/LTE_TRANSPORT/defs.h"
+//#include "PHY/NR_UE_TRANSPORT/defs_nr.h"
 #include <pthread.h>
 
 #include "targets/ARCH/COMMON/common_lib.h"
@@ -569,6 +571,207 @@ typedef struct {
   //MIMO_mode_t mimo_mode;
 } NR_UE_PDSCH_FLP;
 
+#define NR_PDCCH_DEFS_NR_UE
+#define NR_NBR_CORESET_ACT_BWP 3      // The number of CoreSets per BWP is limited to 3 (including initial CORESET: ControlResourceId 0)
+#define NR_NBR_SEARCHSPACE_ACT_BWP 10 // The number of SearchSpaces per BWP is limited to 10 (including initial SEARCHSPACE: SearchSpaceId 0)
+#ifdef NR_PDCCH_DEFS_NR_UE
+
+#define NBR_NR_FORMATS         8
+#define NBR_NR_DCI_FIELDS     48
+// The following parameters define 'position' of each DCI field described in TS 38.212
+#define CARRIER_IND                      0
+#define SUL_IND_0_1                      1
+#define IDENTIFIER_DCI_FORMATS           2
+#define SLOT_FORMAT_IND                  3
+#define PRE_EMPTION_IND                  4
+#define TPC_CMD_NUMBER                   5
+#define BLOCK_NUMBER                     6
+#define BANDWIDTH_PART_IND               7
+#define FREQ_DOM_RESOURCE_ASSIGNMENT_UL  8
+#define FREQ_DOM_RESOURCE_ASSIGNMENT_DL  9
+#define TIME_DOM_RESOURCE_ASSIGNMENT    10
+#define VRB_TO_PRB_MAPPING              11
+#define PRB_BUNDLING_SIZE_IND           12
+#define RATE_MATCHING_IND               13
+#define ZP_CSI_RS_TRIGGER               14
+#define FREQ_HOPPING_FLAG               15
+#define TB1_MCS                         16
+#define TB1_NDI                         17
+#define TB1_RV                          18
+#define TB2_MCS                         19
+#define TB2_NDI                         20
+#define TB2_RV                          21
+#define MCS                             22
+#define NDI                             23
+#define RV                              24
+#define HARQ_PROCESS_NUMBER             25
+#define DAI_                            26
+#define FIRST_DAI                       27
+#define SECOND_DAI                      28
+#define TPC_PUSCH                       29
+#define TPC_PUCCH                       30
+#define PUCCH_RESOURCE_IND              31
+#define PDSCH_TO_HARQ_FEEDBACK_TIME_IND 32
+#define SHORT_MESSAGE_IND               33
+#define SRS_RESOURCE_IND                34
+#define PRECOD_NBR_LAYERS               35
+#define ANTENNA_PORTS                   36
+#define TCI                             37
+#define SRS_REQUEST                     38
+#define TPC_CMD_NUMBER_FORMAT2_3        39
+#define CSI_REQUEST                     40
+#define CBGTI                           41
+#define CBGFI                           42
+#define PTRS_DMRS                       43
+#define BETA_OFFSET_IND                 44
+#define DMRS_SEQ_INI                    45
+#define SUL_IND_0_0                     46
+#define PADDING                         47
+
+typedef enum {bundle_n2=2,bundle_n3=3,bundle_n6=6} NR_UE_CORESET_REG_bundlesize_t;
+
+typedef enum {interleave_n2=2,interleave_n3=3,interleave_n6=6} NR_UE_CORESET_interleaversize_t;
+
+typedef struct {
+  //Corresponds to L1 parameter 'CORESET-REG-bundle-size' (see 38.211, section FFS_Section)
+  NR_UE_CORESET_REG_bundlesize_t reg_bundlesize;
+  //Corresponds to L1 parameter 'CORESET-interleaver-size' (see 38.211, 38.213, section FFS_Section)
+  NR_UE_CORESET_interleaversize_t interleaversize;
+  //Corresponds to L1 parameter 'CORESET-shift-index' (see 38.211, section 7.3.2.2)
+  int shiftIndex;
+} NR_UE_CORESET_CCE_REG_MAPPING_t;
+
+typedef enum {allContiguousRBs=0,sameAsREGbundle=1} NR_UE_CORESET_precoder_granularity_t;
+
+typedef struct {
+  /*
+   * define CORESET structure according to 38.331
+   *
+   * controlResourceSetId: 		Corresponds to L1 parameter 'CORESET-ID'
+   * 							Value 0 identifies the common CORESET configured in MIB and in ServingCellConfigCommon
+   *                       		Values 1..maxNrofControlResourceSets-1 identify CORESETs configured by dedicated signalling
+   * frequencyDomainResources: 	BIT STRING (SIZE (45))
+   * 							Corresponds to L1 parameter 'CORESET-freq-dom'(see 38.211, section 7.3.2.2)
+   * 							Frequency domain resources for the CORESET. Each bit corresponds a group of 6 RBs, with grouping starting from PRB 0,
+   * 							which is fully contained in the bandwidth part within which the CORESET is configured.
+   * duration:					INTEGER (1..maxCoReSetDuration)
+   * 							Corresponds to L1 parameter 'CORESET-time-duration' (see 38.211, section 7.3.2.2FFS_Section)
+   * 							Contiguous time duration of the CORESET in number of symbols
+   * cce-REG-MappingType:		interleaved
+   *								reg-BundleSize: ENUMERATED {n2, n3, n6}
+   *								interleaverSize: ENUMERATED {n2, n3, n6}
+   *								shiftIndex: INTEGER
+   *							nonInterleaved NULL
+   * precoderGranularity:		ENUMERATED {sameAsREG-bundle, allContiguousRBs}
+   * 							Corresponds to L1 parameter 'CORESET-precoder-granuality' (see 38.211, sections 7.3.2.2 and 7.4.1.3.2)
+   * tci-StatesPDCCH:			SEQUENCE(SIZE (1..maxNrofTCI-StatesPDCCH)) OF TCI-StateId OPTIONAL
+   * 							A subset of the TCI states defined in TCI-States used for providing QCL relationships between the DL RS(s)
+   * 							in one RS Set (TCI-State) and the PDCCH DMRS ports.
+   * 							Corresponds to L1 parameter 'TCI-StatesPDCCH' (see 38.214, section FFS_Section)
+   * tci-PresentInDCI:			ENUMERATED {enabled} OPTIONAL
+   * 							Corresponds to L1 parameter 'TCI-PresentInDCI' (see 38,213, section 5.1.5)
+   * pdcch-DMRS-ScramblingID:	BIT STRING (SIZE (16)) OPTIONAL
+   * 							PDCCH DMRS scrambling initalization.
+   * 							Corresponds to L1 parameter 'PDCCH-DMRS-Scrambling-ID' (see 38.214, section 5.1)
+   * 							When the field is absent the UE applies the value '0'.
+   */
+  int controlResourceSetId;
+  uint64_t frequencyDomainResources;
+  int duration;
+  NR_UE_CORESET_CCE_REG_MAPPING_t cce_reg_mappingType;
+  NR_UE_CORESET_precoder_granularity_t precoderGranularity;
+  int tciStatesPDCCH;
+  int tciPresentInDCI;
+  uint16_t pdcchDMRSScramblingID;
+
+} NR_UE_PDCCH_CORESET;
+
+// Slots for PDCCH Monitoring configured as periodicity and offset
+typedef enum {nr_sl1=1,nr_sl2=2,nr_sl4=4,nr_sl5=5,nr_sl8=8,nr_sl10=10,nr_sl16=16,nr_sl20=20} NR_UE_SLOT_PERIOD_OFFSET_t;
+typedef enum {nc0=0,nc1=1,nc2=2,nc3=3,nc4=4,nc5=5,nc6=6,nc8=8} NR_UE_SEARCHSPACE_nbrCAND_t;
+typedef enum {nsfi1=1,nsfi2=2} NR_UE_SEARCHSPACE_nbrCAND_SFI_t;
+typedef enum {n2_3_1=1,n2_3_2=2} NR_UE_SEARCHSPACE_nbrCAND_2_3_t;
+typedef enum {cformat0_0_and_1_0=0,cformat2_0=2,cformat2_1=3,cformat2_2=4,cformat2_3=5} NR_UE_SEARCHSPACE_CSS_DCI_FORMAT_t;
+typedef enum {uformat0_0_and_1_0=0,uformat0_1_and_1_1=1} NR_UE_SEARCHSPACE_USS_DCI_FORMAT_t;
+// Monitoring periodicity of SRS PDCCH in number of slots for DCI format 2-3
+// Corresponds to L1 parameter 'SRS-Num-PDCCH-cand' (see 38.212, 38.213, section 7.3.1, 11.3)
+typedef enum {mp1=1,mp2=2,mp4=4,mp5=5,mp8=8,mp10=10,mp16=16,mp20=20} NR_UE_SEARCHSPACE_MON_PERIOD_t;
+//typedef enum {n1=1,n2=2} NR_UE_SEARCHSPACE_nbrCAND_2_3_t;
+             // The number of PDCCH candidates for DCI format 2-3 for the configured aggregation level.
+             // Corresponds to L1 parameter 'SRS-Num-PDCCH-cand' (see 38.212, 38.213, section 7.3.1, 11.3)
+typedef enum {common=0,ue_specific=1} NR_SEARCHSPACE_TYPE_t;
+
+typedef struct {
+
+/*
+ * searchSpaceType:      Indicates whether this is a common search space (present) or a UE specific search space (CHOICE)
+ *                       as well as DCI formats to monitor for (description in struct NR_UE_PDCCH_SEARCHSPACE_TYPE
+ *      common:          Configures this search space as common search space (CSS) and DCI formats to monitor
+ *      ue-Specific:     Configures this search space as UE specific search space (USS)
+ *                       The UE monitors the DCI format with CRC scrambled by
+ *                       C-RNTI, CS-RNTI (if configured), TC-RNTI (if a certain condition is met),
+ *                       and SP-CSI-RNTI (if configured)
+ */
+
+  NR_SEARCHSPACE_TYPE_t type;
+  NR_UE_SEARCHSPACE_CSS_DCI_FORMAT_t  common_dci_formats;
+  //NR_UE_SEARCHSPACE_nbrCAND_t nrofCandidates_SFI_aggr_level[5]; // FIXME! A table of five enum elements
+  NR_UE_SEARCHSPACE_nbrCAND_SFI_t sfi_nrofCandidates_aggrlevel1;
+  NR_UE_SEARCHSPACE_nbrCAND_SFI_t sfi_nrofCandidates_aggrlevel2;
+  NR_UE_SEARCHSPACE_nbrCAND_SFI_t sfi_nrofCandidates_aggrlevel4;
+  NR_UE_SEARCHSPACE_nbrCAND_SFI_t sfi_nrofCandidates_aggrlevel8;
+  NR_UE_SEARCHSPACE_nbrCAND_SFI_t sfi_nrofCandidates_aggrlevel16;
+  NR_UE_SEARCHSPACE_MON_PERIOD_t  srs_monitoringPeriodicity2_3;
+  NR_UE_SEARCHSPACE_nbrCAND_2_3_t srs_nrofCandidates;
+  NR_UE_SEARCHSPACE_USS_DCI_FORMAT_t  ue_specific_dci_formats;
+
+} NR_UE_PDCCH_SEARCHSPACE_TYPE;
+
+typedef struct {
+/*
+ * define SearchSpace structure according to 38.331
+ *
+ * searchSpaceId:        Identity of the search space. SearchSpaceId = 0 identifies the SearchSpace configured via PBCH (MIB)
+ *                       The searchSpaceId is unique among the BWPs of a Serving Cell
+ * controlResourceSetId: CORESET applicable for this SearchSpace
+ *                       0 identifies the common CORESET configured in MIB
+ *                       1..maxNrofControlResourceSets-1 identify CORESETs configured by dedicated signalling
+ * monitoringSlotPeriodicityAndOffset:
+ *                       Slots for PDCCH Monitoring configured as periodicity and offset.
+ *                       Corresponds to L1 parameters 'Montoring-periodicity-PDCCH-slot' and
+ *                       'Montoring-offset-PDCCH-slot' (see 38.213, section 10)
+ * monitoringSymbolsWithinSlot:
+ *                       Symbols for PDCCH monitoring in the slots configured for PDCCH monitoring
+ *                       The most significant (left) bit represents the first OFDM in a slot
+ *
+ * nrofCandidates:       Number of PDCCH candidates per aggregation level
+ *
+ * searchSpaceType:      Indicates whether this is a common search space (present) or a UE specific search space
+ *                       as well as DCI formats to monitor for (description in struct NR_UE_PDCCH_SEARCHSPACE_TYPE
+ *      common:          Configures this search space as common search space (CSS) and DCI formats to monitor
+ *      ue-Specific:     Configures this search space as UE specific search space (USS)
+ *                       The UE monitors the DCI format with CRC scrambled by
+ *                       C-RNTI, CS-RNTI (if configured), TC-RNTI (if a certain condition is met),
+ *                       and SP-CSI-RNTI (if configured)
+ */
+  // INTEGER (0..maxNrofSearchSpaces-1) (0..40-1)
+  int searchSpaceId;
+  int controlResourceSetId;
+  // FIXME! Verify type to be used for this parameter (sl1, sl2, sl4, sl5, sl8, sl10, sl16, sl20). Maybe enum.
+  NR_UE_SLOT_PERIOD_OFFSET_t monitoringSlotPeriodicityAndOffset;
+  int monitoringSlotPeriodicityAndOffset_offset;
+  // bit string size 14. Bitmap to indicate symbols within slot where PDCCH has to be monitored
+  // the MSB (left) bit represents first OFDM in slot
+  uint16_t monitoringSymbolWithinSlot;
+  NR_UE_SEARCHSPACE_nbrCAND_t nrofCandidates_aggrlevel1;
+  NR_UE_SEARCHSPACE_nbrCAND_t nrofCandidates_aggrlevel2;
+  NR_UE_SEARCHSPACE_nbrCAND_t nrofCandidates_aggrlevel4;
+  NR_UE_SEARCHSPACE_nbrCAND_t nrofCandidates_aggrlevel8;
+  NR_UE_SEARCHSPACE_nbrCAND_t nrofCandidates_aggrlevel16;
+  NR_UE_PDCCH_SEARCHSPACE_TYPE searchSpaceType;
+
+} NR_UE_PDCCH_SEARCHSPACE;
+#endif
 typedef struct {
   /// \brief Pointers to extracted PDCCH symbols in frequency-domain.
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
@@ -621,6 +824,13 @@ typedef struct {
   //Check for specific DCIFormat and AgregationLevel
   uint8_t dciFormat;
   uint8_t agregationLevel;
+  #ifdef NR_PDCCH_DEFS_NR_UE
+  // CORESET structure, where maximum number of CORESETs to be handled is 3 (according to 38.331 V15.1.0)
+  NR_UE_PDCCH_CORESET coreset[NR_NBR_CORESET_ACT_BWP];
+  // SEARCHSPACE structure, where maximum number of SEARCHSPACEs to be handled is 10 (according to 38.331 V15.1.0)
+  // Each SearchSpace is associated with one ControlResourceSet 
+  NR_UE_PDCCH_SEARCHSPACE searchSpace[NR_NBR_SEARCHSPACE_ACT_BWP];
+  #endif
 } NR_UE_PDCCH;
 
 #define PBCH_A 24
diff --git a/openair1/PHY/phy_vars_nr_ue.h b/openair1/PHY/phy_vars_nr_ue.h
index a179f509c61ad2169f1173b5fc862eb968585d19..476d64f104897b2f92e25003564d1f19aa90c4d1 100644
--- a/openair1/PHY/phy_vars_nr_ue.h
+++ b/openair1/PHY/phy_vars_nr_ue.h
@@ -44,6 +44,7 @@ int16_t *primary_synch2_time;
 //PHY_VARS *PHY_vars;
 #ifndef OCP_FRAMEWORK
 PHY_VARS_NR_UE ***PHY_vars_UE_g;
+PHY_VARS_eNB ***PHY_vars_eNB_g;
 LTE_DL_FRAME_PARMS *lte_frame_parms_g;
 #else
 PHY_VARS_NR_UE * PHY_vars_UE_g[MAX_UE][MAX_NUM_CCs]={NULL};
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6f2beb131278227e20dceb991920ea110238af4
--- /dev/null
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -0,0 +1,373 @@
+/*
+ * 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.1  (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
+ */
+
+/*
+  \author R. Knopp, F. Kaltenberger
+  \company EURECOM
+  \email knopp@eurecom.fr
+*/
+
+#ifndef __openair_SCHED_H__
+#define __openair_SCHED_H__
+
+#include "PHY/defs_nr_UE.h"
+
+
+/*enum THREAD_INDEX { OPENAIR_THREAD_INDEX = 0,
+                    TOP_LEVEL_SCHEDULER_THREAD_INDEX,
+                    DLC_SCHED_THREAD_INDEX,
+                    openair_SCHED_NB_THREADS
+                  };*/ // do not modify this line
+
+
+#define OPENAIR_THREAD_PRIORITY        255
+
+
+#define OPENAIR_THREAD_STACK_SIZE     PTHREAD_STACK_MIN //4096 //RTL_PTHREAD_STACK_MIN*6
+//#define DLC_THREAD_STACK_SIZE        4096 //DLC stack size
+//#define UE_SLOT_PARALLELISATION
+//#define UE_DLSCH_PARALLELISATION
+
+/*enum openair_SCHED_STATUS {
+  openair_SCHED_STOPPED=1,
+  openair_SCHED_STARTING,
+  openair_SCHED_STARTED,
+  openair_SCHED_STOPPING
+};*/
+
+/*enum openair_ERROR {
+  // HARDWARE CAUSES
+  openair_ERROR_HARDWARE_CLOCK_STOPPED= 1,
+
+  // SCHEDULER CAUSE
+  openair_ERROR_OPENAIR_RUNNING_LATE,
+  openair_ERROR_OPENAIR_SCHEDULING_FAILED,
+
+  // OTHERS
+  openair_ERROR_OPENAIR_TIMING_OFFSET_OUT_OF_BOUNDS,
+};*/
+
+/*enum openair_SYNCH_STATUS {
+  openair_NOT_SYNCHED=1,
+  openair_SYNCHED,
+  openair_SCHED_EXIT
+};*/
+
+/*enum openair_HARQ_TYPE {
+  openair_harq_DL = 0,
+  openair_harq_UL,
+  openair_harq_RA
+};*/
+
+#define DAQ_AGC_ON 1
+#define DAQ_AGC_OFF 0
+
+
+/** @addtogroup _PHY_PROCEDURES_
+ * @{
+ */
+
+
+/*! \brief Top-level entry routine for UE procedures.  Called every slot by process scheduler. In even slots, it performs RX functions from previous subframe (if required).  On odd slots, it generate TX waveform for the following subframe.
+  @param phy_vars_ue Pointer to UE variables on which to act
+  @param eNB_id ID of eNB on which to act
+  @param abstraction_flag Indicator of PHY abstraction
+  @param mode calibration/debug mode
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
+  @param *phy_vars_rn pointer to RN variables
+*/
+void phy_procedures_UE_lte(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type);
+#if defined(Rel10) || defined(Rel14)
+/*! \brief Top-level entry routine for relay node procedures actinf as UE. This proc will make us of the existing UE procs.
+  @param last_slot Index of last slot (0-19)
+  @param next_slot Index of next_slot (0-19)
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
+*/
+int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type);
+#endif
+
+/*! \brief Scheduling for UE TX procedures in normal subframes.
+  @param phy_vars_ue Pointer to UE variables on which to act
+  @param proc Pointer to RXn-TXnp4 proc information
+  @param eNB_id Local id of eNB on which to act
+  @param abstraction_flag Indicator of PHY abstraction
+  @param mode calib/normal mode
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
+*/
+void phy_procedures_UE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type);
+/*! \brief Scheduling for UE RX procedures in normal subframes.
+  @param last_slot Index of last slot (0-19)
+  @param phy_vars_ue Pointer to UE variables on which to act
+  @param proc Pointer to RXn_TXnp4 proc information
+  @param eNB_id Local id of eNB on which to act
+  @param abstraction_flag Indicator of PHY abstraction
+  @param mode calibration/debug mode
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
+  @param phy_vars_rn pointer to RN variables
+*/
+int phy_procedures_UE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type);
+int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type);
+
+#ifdef UE_SLOT_PARALLELISATION
+void *UE_thread_slot1_dl_processing(void *arg);
+#endif
+
+/*! \brief Scheduling for UE TX procedures in TDD S-subframes.
+  @param phy_vars_ue Pointer to UE variables on which to act
+  @param eNB_id Local id of eNB on which to act
+  @param abstraction_flag Indicator of PHY abstraction
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
+*/
+void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type);
+
+/*! \brief Scheduling for UE RX procedures in TDD S-subframes.
+  @param phy_vars_ue Pointer to UE variables on which to act
+  @param eNB_id Local id of eNB on which to act
+  @param abstraction_flag Indicator of PHY abstraction
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
+*/
+void phy_procedures_UE_S_RX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag, relaying_type_t r_type);
+
+
+/*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index.
+  @param frame_parms Pointer to DL frame parameter descriptor
+  @param subframe Subframe index
+  @returns Subframe type (DL,UL,S)
+*/
+
+
+nr_subframe_t nr_subframe_select(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
+
+
+/*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index.  Same as nr_subframe_select, except that it uses the Mod_id and is provided as a service to the MAC scheduler.
+  @param Mod_id Index of eNB
+  @param CC_id Component Carrier Index
+  @param subframe Subframe index
+  @returns Subframe type (DL,UL,S)
+*/
+nr_subframe_t nr_get_subframe_direction(uint8_t Mod_id, uint8_t CC_id,uint8_t subframe);
+
+/*! \brief Function to compute timing of Msg3 transmission on UL-SCH (first UE transmission in RA procedure). This implements the timing in paragraph a) from Section 6.1.1 in 36.213 (p. 17 in version 8.6).  Used by eNB upon transmission of random-access response (RA_RNTI) to program corresponding ULSCH reception procedure.  Used by UE upon reception of random-access response (RA_RNTI) to program corresponding ULSCH transmission procedure.  This does not support the UL_delay field in RAR (always assumed to be 0).
+  @param frame_parms Pointer to DL frame parameter descriptor
+  @param current_subframe Index of subframe where RA_RNTI was received
+  @param current_frame Index of frame where RA_RNTI was received
+  @param frame Frame index where Msg3 is to be transmitted (n+6 mod 10 for FDD, different for TDD)
+  @param subframe subframe index where Msg3 is to be transmitted (n, n+1 or n+2)
+*/
+void nr_get_Msg3_alloc(NR_DL_FRAME_PARMS *frame_parms,
+                    uint8_t current_subframe,
+                    uint32_t current_frame,
+                    uint32_t *frame,
+                    uint8_t *subframe);
+
+/*! \brief Function to compute timing of Msg3 retransmission on UL-SCH (first UE transmission in RA procedure).
+  @param frame_parms Pointer to DL frame parameter descriptor
+  @param current_subframe Index of subframe where RA_RNTI was received
+  @param current_frame Index of frame where RA_RNTI was received
+  @param frame Frame index where Msg3 is to be transmitted (n+6 mod 10 for FDD, different for TDD)
+  @param subframe subframe index where Msg3 is to be transmitted (n, n+1 or n+2)
+*/
+void nr_get_Msg3_alloc_ret(NR_DL_FRAME_PARMS *frame_parms,
+                        uint8_t current_subframe,
+                        uint32_t current_frame,
+                        uint32_t *frame,
+                        uint8_t *subframe);
+
+/*! \brief Get ULSCH harq_pid for Msg3 from RAR subframe.  This returns n+k mod 10 (k>6) and corresponds to the rule in Section 6.1.1 from 36.213
+   @param frame_parms Pointer to DL Frame Parameters
+   @param frame Frame index
+   @param current_subframe subframe of RAR transmission
+   @returns harq_pid (0 ... 7)
+ */
+uint8_t nr_get_Msg3_harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t current_subframe);
+
+/*! \brief Get ULSCH harq_pid from PHICH subframe
+   @param frame_parms Pointer to DL Frame Parameters
+   @param subframe subframe of PHICH
+   @returns harq_pid (0 ... 7)
+ */
+
+/*! \brief Function to indicate failure of contention resolution or RA procedure.  It places the UE back in PRACH mode.
+    @param Mod_id Instance index of UE
+    @param CC_id Component Carrier Index
+    @param eNB_index Index of eNB
+ */
+void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+
+/*! \brief Function to indicate success of contention resolution or RA procedure.
+    @param Mod_id Instance index of UE
+    @param CC_id Component Carrier Index
+    @param eNB_index Index of eNB
+ */
+void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+
+/*! \brief Compute ACK/NACK information for PUSCH/PUCCH for UE transmission in subframe n. This function implements table 10.1-1 of 36.213, p. 69.
+  @param frame_parms Pointer to DL frame parameter descriptor
+  @param harq_ack Pointer to dlsch_ue harq_ack status descriptor
+  @param subframe Subframe for UE transmission (n in 36.213)
+  @param o_ACK Pointer to ACK/NAK payload for PUCCH/PUSCH
+  @returns status indicator for PUCCH/PUSCH transmission
+*/
+uint8_t nr_get_ack(NR_DL_FRAME_PARMS *frame_parms,nr_harq_status_t *harq_ack,uint8_t subframe_tx,uint8_t subframe_rx,uint8_t *o_ACK, uint8_t cw_idx);
+
+/*! \brief Reset ACK/NACK information
+  @param frame_parms Pointer to DL frame parameter descriptor
+  @param harq_ack Pointer to dlsch_ue harq_ack status descriptor
+  @param subframe Subframe for UE transmission (n in 36.213)
+  @param o_ACK Pointer to ACK/NAK payload for PUCCH/PUSCH
+  @returns status indicator for PUCCH/PUSCH transmission
+*/
+uint8_t nr_reset_ack(NR_DL_FRAME_PARMS *frame_parms,
+                nr_harq_status_t *harq_ack,
+                unsigned char subframe_tx,
+                unsigned char subframe_rx,
+                unsigned char *o_ACK,
+                uint8_t *pN_bundled,
+                uint8_t cw_idx);
+
+/*! \brief Compute UL ACK subframe from DL subframe. This is used to retrieve corresponding DLSCH HARQ pid at eNB upon reception of ACK/NAK information on PUCCH/PUSCH.  Derived from Table 10.1-1 in 36.213 (p. 69 in version 8.6)
+  @param frame_parms Pointer to DL frame parameter descriptor
+  @param subframe Subframe for UE transmission (n in 36.213)
+  @param ACK_index TTI bundling index (0,1)
+  @returns Subframe index for corresponding DL transmission
+*/
+uint8_t nr_ul_ACK_subframe2_dl_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe,uint8_t ACK_index);
+
+/*! \brief Computes number of DL subframes represented by a particular ACK received on UL (M from Table 10.1-1 in 36.213, p. 69 in version 8.6)
+  @param frame_parms Pointer to DL frame parameter descriptor
+  @param subframe Subframe for UE transmission (n in 36.213)
+  @returns Number of DL subframes (M)
+*/
+uint8_t nr_ul_ACK_subframe2_M(NR_DL_FRAME_PARMS *frame_parms,unsigned char subframe);
+
+/*! \brief Indicates the SR TXOp in current subframe.  Implements Table 10.1-5 from 36.213.
+  @param phy_vars_ue Pointer to UE variables
+  @param proc Pointer to RXn_TXnp4 thread context
+  @param eNB_id ID of eNB which is to receive the SR
+  @returns 1 if TXOp is active.
+*/
+uint8_t nr_is_SR_TXOp(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id);
+
+/*! \brief Gives the UL subframe corresponding to a PDDCH order in subframe n
+  @param frame_parms Pointer to DL frame parameters
+  @param proc Pointer to RXn-TXnp4 proc information
+  @param n subframe of PDCCH
+  @returns UL subframe corresponding to pdcch order
+*/
+uint8_t nr_pdcch_alloc2ul_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t n);
+
+/*! \brief Gives the UL frame corresponding to a PDDCH order in subframe n
+  @param frame_parms Pointer to DL frame parameters
+  @param frame Frame of received PDCCH
+  @param n subframe of PDCCH
+  @returns UL frame corresponding to pdcch order
+*/
+uint32_t nr_pdcch_alloc2ul_frame(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n);
+
+
+uint16_t nr_get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1);
+
+
+int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
+
+void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance);
+void nr_process_timing_advance_rar(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance);
+
+unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb);
+
+void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+
+/*! \brief This function retrives the resource (n1_pucch) corresponding to a PDSCH transmission in
+subframe n-4 which is acknowledged in subframe n (for FDD) according to n1_pucch = Ncce + N1_pucch.  For
+TDD, this routine computes the complex procedure described in Section 10.1 of 36.213 (through tables 10.1-1,10.1-2)
+@param phy_vars_ue Pointer to UE variables
+@param proc Pointer to RXn-TXnp4 proc information
+@param harq_ack Pointer to dlsch_ue harq_ack status descriptor
+@param eNB_id Index of eNB
+@param b Pointer to PUCCH payload (b[0],b[1])
+@param SR 1 means there's a positive SR in parallel to ACK/NAK
+@returns n1_pucch
+*/
+uint16_t nr_get_n1_pucch(PHY_VARS_NR_UE *phy_vars_ue,
+		      UE_nr_rxtx_proc_t *proc,
+                      nr_harq_status_t *harq_ack,
+                      uint8_t eNB_id,
+                      uint8_t *b,
+                      uint8_t SR);
+
+
+/*! \brief This function retrieves the PHY UE mode. It is used as a helper function for the UE MAC.
+  @param Mod_id Local UE index on which to act
+  @param CC_id Component Carrier Index
+  @param eNB_index ID of eNB
+  @returns UE mode
+*/
+UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+
+/*! \brief This function implements the power control mechanism for PUCCH from 36.213.
+    @param phy_vars_ue PHY variables
+    @param proc Pointer to proc descriptor
+    @param eNB_id Index of eNB
+    @param pucch_fmt Format of PUCCH that is being transmitted
+    @returns Transmit power
+ */
+int16_t nr_pucch_power_cntl(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t subframe,uint8_t eNB_id,PUCCH_FMT_t pucch_fmt);
+
+/*! \brief This function implements the power control mechanism for PUCCH from 36.213.
+    @param phy_vars_ue PHY variables
+    @param proc Pointer to proc descriptor
+    @param eNB_id Index of eNB
+    @param j index of type of PUSCH (SPS, Normal, Msg3)
+    @returns Transmit power
+ */
+void nr_pusch_power_cntl(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag);
+
+/*! \brief This function implements the power control mechanism for SRS from 36.213.
+    @param phy_vars_ue PHY variables
+    @param proc Pointer to proc descriptor
+    @param eNB_id Index of eNB
+    @param j index of type of PUSCH (SPS, Normal, Msg3)
+    @returns Transmit power
+ */
+void nr_srs_power_cntl(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t *pnb_rb_srs, uint8_t abstraction_flag);
+
+void nr_get_cqipmiri_params(PHY_VARS_NR_UE *ue,uint8_t eNB_id);
+
+
+
+
+
+
+void nr_dump_dlsch(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid);
+void nr_dump_dlsch_SI(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe);
+void nr_dump_dlsch_ra(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe);
+
+
+int nr_is_srs_occasion_common(NR_DL_FRAME_PARMS *frame_parms,int frame_tx,int subframe_tx);
+
+void nr_compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
+
+/*@}*/
+
+
+#endif
+
+
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
new file mode 100644
index 0000000000000000000000000000000000000000..58aef566023e01e420991b35499e4bfed581f237
--- /dev/null
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -0,0 +1,6529 @@
+/*
+ * 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.1  (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_procedures_nr_ue.c
+ * \brief Implementation of UE procedures from 36.213 LTE specifications
+ * \author R. Knopp, F. Kaltenberger, N. Nikaein, A. Mico Pereperez
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#define _GNU_SOURCE
+
+#include "assertions.h"
+#include "defs.h"
+//#include "PHY/defs.h"
+#include "PHY/defs_nr_UE.h"
+#include "PHY/phy_vars_nr_ue.h"
+//#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
+//#include "PHY/extern.h"
+#include "SCHED_NR_UE/defs.h"
+#include "SCHED_NR/extern.h"
+#include <sched.h>
+#include "targets/RT/USER/nr-softmodem.h"
+
+#ifdef EMOS
+#include "SCHED/phy_procedures_emos.h"
+#endif
+
+#define DEBUG_PHY_PROC
+
+#define NR_PDCCH_SCHED
+#define NR_PDCCH_SCHED_DEBUG
+#define NR_PUCCH_SCHED
+#define NR_PUCCH_SCHED_DEBUG
+
+#ifndef PUCCH
+#define PUCCH
+#endif
+
+#include "LAYER2/NR_MAC_UE/extern.h"
+#include "LAYER2/NR_MAC_UE/defs.h"
+#include "UTIL/LOG/log.h"
+
+#ifdef EMOS
+fifo_dump_emos_UE emos_dump_UE;
+#endif
+
+#include "UTIL/LOG/vcd_signal_dumper.h"
+#include "UTIL/OPT/opt.h"
+
+#if defined(ENABLE_ITTI)
+# include "intertask_interface.h"
+#endif
+
+//#include "PHY/defs.h"
+
+//#include "PHY/CODING/extern.h"
+
+#include "T.h"
+
+#define DLSCH_RB_ALLOC 0x1fbf  // skip DC RB (total 23/25 RBs)
+#define DLSCH_RB_ALLOC_12 0x0aaa  // skip DC RB (total 23/25 RBs)
+
+#define NS_PER_SLOT 500000
+
+extern double cpuf;
+
+
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
+#endif
+
+
+#if 0
+void nr_dump_dlsch(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t nr_tti_rx,uint8_t harq_pid)
+{
+  unsigned int coded_bits_per_codeword;
+  uint8_t nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;
+
+  coded_bits_per_codeword = get_G(&ue->frame_parms,
+                                  ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
+                                  ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+                                  ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[harq_pid]->Qm,
+                                  ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[harq_pid]->Nl,
+                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+                                  proc->frame_rx,
+          nr_tti_rx,
+          ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
+
+  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
+  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
+  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
+  /*
+    write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
+    write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
+    write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
+    write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
+  */
+  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->rxdataF_comp0[0],300*12,1,1);
+  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->llr[0],coded_bits_per_codeword,1,0);
+
+  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_mag0,300*12,1,1);
+  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_magb0,300*12,1,1);
+}
+
+void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t nr_tti_rx)
+{
+  unsigned int coded_bits_per_codeword;
+  uint8_t nsymb = ((ue->frame_parms.Ncp == 0) ? 14 : 12);
+
+  coded_bits_per_codeword = get_G(&ue->frame_parms,
+                                  ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
+                                  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even,
+                                  2,
+                                  1,
+                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+                                  proc->frame_rx,
+          nr_tti_rx,
+          0);
+  LOG_D(PHY,"[UE %d] Dumping dlsch_SI : ofdm_symbol_size %d, nsymb %d, nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
+        ue->Mod_id,
+  ue->frame_parms.ofdm_symbol_size,
+  nsymb,
+        ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
+        ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs,
+        ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
+        ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+        coded_bits_per_codeword);
+
+  write_output("rxsig0.m","rxs0", &ue->common_vars.rxdata[0][nr_tti_rx*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1);
+
+  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
+  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_SI[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
+  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_SI[0]->dl_ch_estimates_ext[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1);
+  /*
+    write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
+    write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
+    write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
+    write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
+  */
+  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_SI[0]->rxdataF_comp0[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1);
+  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_SI[0]->llr[0],coded_bits_per_codeword,1,0);
+
+  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_SI[0]->dl_ch_mag0,300*nsymb,1,1);
+  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_SI[0]->dl_ch_magb0,300*nsymb,1,1);
+  sleep(1);
+  exit(-1);
+}
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+//unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
+/*
+  unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL)
+  {
+
+  int gain_dB = power_dBm - power_max_dBm;
+  int amp_x_100;
+
+  switch (N_RB_UL) {
+  case 6:
+  amp_x_100 = AMP;      // PRACH is 6 PRBS so no scale
+  break;
+  case 15:
+  amp_x_100 = 158*AMP;  // 158 = 100*sqrt(15/6)
+  break;
+  case 25:
+  amp_x_100 = 204*AMP;  // 204 = 100*sqrt(25/6)
+  break;
+  case 50:
+  amp_x_100 = 286*AMP;  // 286 = 100*sqrt(50/6)
+  break;
+  case 75:
+  amp_x_100 = 354*AMP;  // 354 = 100*sqrt(75/6)
+  break;
+  case 100:
+  amp_x_100 = 408*AMP;  // 408 = 100*sqrt(100/6)
+  break;
+  default:
+  LOG_E(PHY,"Unknown PRB size %d\n",N_RB_UL);
+  //mac_xface->macphy_exit("");
+  break;
+  }
+  if (gain_dB < -30) {
+  return(amp_x_100/3162);
+  } else if (gain_dB>0)
+  return(amp_x_100);
+  else
+  return(amp_x_100/gain_table[-gain_dB]);  // 245 corresponds to the factor sqrt(25/6)
+  }
+*/
+
+unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
+{
+
+  int gain_dB = power_dBm - power_max_dBm;
+  double gain_lin;
+
+  gain_lin = pow(10,.1*gain_dB);
+  if ((nb_rb >0) && (nb_rb <= N_RB_UL)) {
+    return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)));
+  }
+  else {
+    LOG_E(PHY,"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL);
+    //mac_xface->macphy_exit("");
+  }
+  return(0);
+}
+
+#endif
+
+void nr_dump_dlsch_ra(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t nr_tti_rx)
+{
+  unsigned int coded_bits_per_codeword;
+  uint8_t nsymb = ((ue->frame_parms.Ncp == 0) ? 14 : 12);
+
+  coded_bits_per_codeword = get_G(&ue->frame_parms,
+                                  ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
+                                  ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even,
+                                  2,
+                                  1,
+                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+                                  proc->frame_rx,
+          nr_tti_rx,
+          0);
+  LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
+        ue->Mod_id,
+        ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
+        ue->dlsch_ra[eNB_id]->harq_processes[0]->mcs,
+        ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
+        ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+        coded_bits_per_codeword);
+
+  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1);
+  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_ra[0]->rxdataF_ext[0],2*12*ue->frame_parms.ofdm_symbol_size,1,1);
+  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_ra[0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
+  /*
+    write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
+    write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
+    write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
+    write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
+  */
+  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_ra[0]->rxdataF_comp0[0],300*nsymb,1,1);
+  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_ra[0]->llr[0],coded_bits_per_codeword,1,0);
+
+  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_ra[0]->dl_ch_mag0,300*nsymb,1,1);
+  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1);
+}
+
+void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
+{
+
+  // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later
+  // for more flexibility
+
+  uint8_t i,j,k,s;
+  PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
+
+  //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2];
+  for(int l=0; l<RX_NB_TH; l++) {
+      for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
+          for(j=0; j<2; j++) {
+              //DL HARQ
+              if(ue->dlsch[l][i][j]) {
+                  for(k=0; k<NUMBER_OF_HARQ_PID_MAX && ue->dlsch[l][i][j]->harq_processes[k]; k++) {
+                      ue->dlsch[l][i][j]->harq_processes[k]->status = SCH_IDLE;
+                      for (s=0; s<10; s++) {
+                          // reset ACK/NACK bit to DTX for all nr_tti_rxs s = 0..9
+                          ue->dlsch[l][i][j]->harq_ack[s].ack = 2;
+                          ue->dlsch[l][i][j]->harq_ack[s].send_harq_status = 0;
+                          ue->dlsch[l][i][j]->harq_ack[s].vDAI_UL = 0xff;
+                          ue->dlsch[l][i][j]->harq_ack[s].vDAI_DL = 0xff;
+                      }
+                  }
+              }
+          }
+
+          //UL HARQ
+          if(ue->ulsch[i]) {
+              for(k=0; k<NUMBER_OF_HARQ_PID_MAX && ue->ulsch[i]->harq_processes[k]; k++) {
+                  ue->ulsch[i]->harq_processes[k]->status = SCH_IDLE;
+                  //Set NDIs for all UL HARQs to 0
+                  //  ue->ulsch[i]->harq_processes[k]->Ndi = 0;
+
+              }
+          }
+
+          // flush Msg3 buffer
+          ue->ulsch_Msg3_active[i] = 0;
+
+      }
+  }
+}
+
+void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
+{
+
+  // if contention resolution fails, go back to PRACH
+  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH;
+  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0;
+  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti = 0;
+  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0;
+  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti = 0;
+  LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0, discard temporary C-RNTI and State RRC_IDLE\n",Mod_id);
+  //mac_xface->macphy_exit("");
+}
+
+void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
+{
+
+  int i;
+
+  LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded. Set C-RNTI = Temporary C-RNTI\n",Mod_id);
+
+  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0;
+  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0;
+  PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0;
+  PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH;
+
+  for (i=0; i<8; i++) {
+    if (PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]) {
+      PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=IDLE;
+      PHY_vars_UE_g[Mod_id][CC_id]->dlsch[0][eNB_index][0]->harq_processes[i]->round=0;
+      PHY_vars_UE_g[Mod_id][CC_id]->dlsch[1][eNB_index][0]->harq_processes[i]->round=0;
+      PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->subframe_scheduling_flag=0;
+    }
+  }
+
+
+}
+
+UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
+{
+
+  return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
+
+}
+void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance) {
+
+  ue->timing_advance = timing_advance*4;
+
+
+#ifdef DEBUG_PHY_PROC
+  /* TODO: fix this log, what is 'HW timing advance'? */
+  /*LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx_rx, ue->timing_advance);*/
+  LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx, ue->timing_advance);
+#endif
+
+}
+
+void nr_process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance)
+{
+
+  //  uint32_t frame = PHY_vars_UE_g[Mod_id]->frame;
+
+  // timing advance has Q1.5 format
+  timing_advance = timing_advance - 31;
+
+  PHY_vars_UE_g[Mod_id][CC_id]->timing_advance = PHY_vars_UE_g[Mod_id][CC_id]->timing_advance+timing_advance*4; //this is for 25RB only!!!
+
+
+  LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
+
+
+}
+
+uint8_t nr_is_SR_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id)
+{
+
+  int nr_tti_tx=proc->nr_tti_tx;
+
+  LOG_D(PHY,"[UE %d][SR %x] Frame %d nr_tti_tx %d Checking for SR TXOp (sr_ConfigIndex %d)\n",
+        ue->Mod_id,ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->crnti,proc->frame_tx,nr_tti_tx,
+        ue->scheduling_request_config[eNB_id].sr_ConfigIndex);
+
+  if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
+    if ((nr_tti_tx%5) == ue->scheduling_request_config[eNB_id].sr_ConfigIndex)
+      return(1);
+  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 14) { // 10 ms SR period
+    if (nr_tti_tx==(ue->scheduling_request_config[eNB_id].sr_ConfigIndex-5))
+      return(1);
+  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 34) { // 20 ms SR period
+    if ((10*(proc->frame_tx&1)+nr_tti_tx) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-15))
+      return(1);
+  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 74) { // 40 ms SR period
+    if ((10*(proc->frame_tx&3)+nr_tti_tx) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-35))
+      return(1);
+  } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 154) { // 80 ms SR period
+    if ((10*(proc->frame_tx&7)+nr_tti_tx) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-75))
+      return(1);
+  }
+
+  return(0);
+}
+
+uint8_t is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id)
+{
+  int nr_tti_tx = proc->nr_tti_tx;
+  int frame    = proc->frame_tx;
+  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;
+
+  //LOG_I(PHY,"[UE %d][CRNTI %x] AbsSubFrame %d.%d Checking for CQI TXOp (cqi_ConfigIndex %d) isCQIOp %d\n",
+  //      ue->Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame,nr_tti_rx,
+  //      cqirep->cqi_PMI_ConfigIndex,
+  //      (((10*frame + nr_tti_tx) % cqirep->Npd) == cqirep->N_OFFSET_CQI));
+
+  if (cqirep->cqi_PMI_ConfigIndex==-1)
+    return(0);
+  else if (((10*frame + nr_tti_tx) % cqirep->Npd) == cqirep->N_OFFSET_CQI)
+    return(1);
+  else
+    return(0);
+}
+uint8_t is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id)
+{
+
+
+  int nr_tti_tx = proc->nr_tti_tx;
+  int frame    = proc->frame_tx;
+  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;
+  int log2Mri = cqirep->ri_ConfigIndex/161;
+  int N_OFFSET_RI = cqirep->ri_ConfigIndex % 161;
+
+  //LOG_I(PHY,"[UE %d][CRNTI %x] AbsSubFrame %d.%d Checking for RI TXOp (ri_ConfigIndex %d) isRIOp %d\n",
+  //      ue->Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame,nr_tti_tx,
+  //      cqirep->ri_ConfigIndex,
+  //      (((10*frame + nr_tti_tx + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0));
+  if (cqirep->ri_ConfigIndex==-1)
+    return(0);
+  else if (((10*frame + nr_tti_tx + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0)
+    return(1);
+  else
+    return(0);
+}
+
+void compute_cqi_ri_resources(PHY_VARS_NR_UE *ue,
+                              NR_UE_ULSCH_t *ulsch,
+                              uint8_t eNB_id,
+                              uint16_t rnti,
+                              uint16_t p_rnti,
+                              uint16_t cba_rnti,
+                              uint8_t cqi_status,
+                              uint8_t ri_status)
+{
+    //PHY_MEASUREMENTS *meas = &ue->measurements;
+    //uint8_t transmission_mode = ue->transmission_mode[eNB_id];
+
+
+    //LOG_I(PHY,"compute_cqi_ri_resources O_RI %d O %d uci format %d \n",ulsch->O_RI,ulsch->O,ulsch->uci_format);
+    if (cqi_status == 1 || ri_status == 1)
+    {
+        ulsch->O = 4;
+    }
+}
+
+void ue_compute_srs_occasion(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS)
+{
+
+  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  int frame_tx    = proc->frame_tx;
+  int nr_tti_tx = proc->nr_tti_tx;
+  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
+  uint16_t srsPeriodicity;
+  uint16_t srsOffset;
+  uint8_t is_pucch2_subframe = 0;
+  uint8_t is_sr_an_subframe  = 0;
+
+  // check for SRS opportunity
+  pSoundingrs_ul_config_dedicated->srsUeSubframe   = 0;
+  pSoundingrs_ul_config_dedicated->srsCellSubframe = isSubframeSRS;
+
+  if (isSubframeSRS) {
+    LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup);
+      if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup)
+      {
+          nr_compute_srs_pos(frame_parms->frame_type, pSoundingrs_ul_config_dedicated->srs_ConfigIndex, &srsPeriodicity, &srsOffset);
+
+          LOG_D(PHY," srsPeriodicity: %d srsOffset: %d isSubframeSRS %d \n",srsPeriodicity,srsOffset,isSubframeSRS);
+
+          // transmit SRS if the four following constraints are respected:
+          // - UE is configured to transmit SRS
+          // - SRS are configured in current nr_tti_rx
+          // - UE is configured to send SRS in this nr_tti_tx
+
+          // 36.213 8.2
+          // 1- A UE shall not transmit SRS whenever SRS and PUCCH format 2/2a/2b transmissions happen to coincide in the same nr_tti_rx
+          // 2- A UE shall not transmit SRS whenever SRS transmit
+          //    on and PUCCH transmission carrying ACK/NACK and/or
+          //    positive SR happen to coincide in the same nr_tti_rx if the parameter
+          //    Simultaneous-AN-and-SRS is FALSE
+
+          // check PUCCH format 2/2a/2b transmissions
+          is_pucch2_subframe = is_cqi_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0);
+          is_pucch2_subframe = (is_ri_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0)) || is_pucch2_subframe;
+
+          // check ACK/SR transmission
+          if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == FALSE)
+          {
+              if(nr_is_SR_TXOp(ue,proc,eNB_id))
+              {
+                  uint32_t SR_payload = 0;
+                  if (ue->mac_enabled==1)
+                  {
+                      int Mod_id = ue->Mod_id;
+                      int CC_id = ue->CC_id;
+                      SR_payload = mac_xface->ue_get_SR(Mod_id,
+                              CC_id,
+                              frame_tx,
+                              eNB_id,
+                              ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->crnti,
+                              nr_tti_tx); // nr_tti_tx used for meas gap
+
+                      if (SR_payload > 0)
+                          is_sr_an_subframe = 1;
+                  }
+              }
+
+              uint8_t pucch_ack_payload[2];
+              if (nr_get_ack(&ue->frame_parms,
+                      ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack,
+                      nr_tti_tx,proc->nr_tti_rx,pucch_ack_payload,0) > 0)
+              {
+                  is_sr_an_subframe = 1;
+              }
+          }
+
+          // check SRS UE opportunity
+          if( isSubframeSRS  &&
+                  (((10*frame_tx+nr_tti_tx) % srsPeriodicity) == srsOffset)
+          )
+          {
+              if ((is_pucch2_subframe == 0) && (is_sr_an_subframe == 0))
+              {
+                  pSoundingrs_ul_config_dedicated->srsUeSubframe = 1;
+                  ue->ulsch[eNB_id]->srs_active   = 1;
+                  ue->ulsch[eNB_id]->Nsymb_pusch  = 12-(frame_parms->Ncp<<1)- ue->ulsch[eNB_id]->srs_active;
+              }
+              else
+              {
+                  LOG_I(PHY,"DROP UE-SRS-TX for this nr_tti_tx %d.%d: collision with PUCCH2 or SR/AN: PUCCH2-occasion: %d, SR-AN-occasion[simSRS-SR-AN %d]: %d  \n", frame_tx, nr_tti_tx, is_pucch2_subframe, frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, is_sr_an_subframe);
+              }
+          }
+      }
+      LOG_D(PHY," srsCellSubframe: %d, srsUeSubframe: %d, Nsymb-pusch: %d \n", pSoundingrs_ul_config_dedicated->srsCellSubframe, pSoundingrs_ul_config_dedicated->srsUeSubframe, ue->ulsch[eNB_id]->Nsymb_pusch);
+  }
+}
+
+
+void nr_get_cqipmiri_params(PHY_VARS_NR_UE *ue,uint8_t eNB_id)
+{
+
+  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;
+  int cqi_PMI_ConfigIndex = cqirep->cqi_PMI_ConfigIndex;
+
+  if (ue->frame_parms.frame_type == FDD) {
+    if (cqi_PMI_ConfigIndex <= 1) {        // 2 ms CQI_PMI period
+      cqirep->Npd = 2;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex;
+    } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period
+      cqirep->Npd = 5;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-2;
+    } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
+      cqirep->Npd = 10;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-7;
+    } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
+      cqirep->Npd = 20;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-17;
+    } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
+      cqirep->Npd = 40;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-37;
+    } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
+      cqirep->Npd = 80;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-77;
+    } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
+      cqirep->Npd = 160;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-157;
+    }
+    else if (cqi_PMI_ConfigIndex > 317) {
+
+      if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period
+  cqirep->Npd = 32;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-318;
+      }
+      else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period
+  cqirep->Npd = 64;
+  cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
+      }
+      else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period
+  cqirep->Npd = 128;
+  cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
+      }
+    }
+  }
+  else { // TDD
+   if (cqi_PMI_ConfigIndex == 0) {        // all UL subframes
+     cqirep->Npd = 1;
+     cqirep->N_OFFSET_CQI = 0;
+   } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period
+     cqirep->Npd = 5;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-1;
+   } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
+     cqirep->Npd = 10;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-6;
+   } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
+     cqirep->Npd = 20;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-16;
+   } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
+     cqirep->Npd = 40;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-36;
+   } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
+     cqirep->Npd = 80;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-76;
+   } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
+     cqirep->Npd = 160;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-156;
+   }
+  }
+}
+
+PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
+                             lte_prefix_type_t cyclic_prefix_type,
+                             uint8_t SR_payload,
+                             uint8_t nb_cw,
+                             uint8_t cqi_status,
+                             uint8_t ri_status,
+                             uint8_t bundling_flag)
+{
+  if((cqi_status == 0) && (ri_status==0))
+  {
+      // PUCCH Format 1 1a 1b
+      // 1- SR only ==> PUCCH format 1
+      // 2- 1bit Ack/Nack with/without SR  ==> PUCCH format 1a
+      // 3- 2bits Ack/Nack with/without SR ==> PUCCH format 1b
+      if((nb_cw == 1)&&(bundling_flag==bundling))
+      {
+          return pucch_format1a;
+      }
+      if((nb_cw == 1)&&(bundling_flag==multiplexing))
+      {
+          return pucch_format1b;
+      }
+      if(nb_cw == 2)
+      {
+          return pucch_format1b;
+      }
+      if(SR_payload == 1)
+      {
+          return pucch_format1;
+          /*
+          if (frame_type == FDD) {
+              return pucch_format1;
+          } else if (frame_type == TDD) {
+              return pucch_format1b;
+          } else {
+              AssertFatal(1==0,"Unknown frame_type");
+          }*/
+      }
+  }
+  else
+  {
+      // PUCCH Format 2 2a 2b
+      // 1- CQI only or RI only  ==> PUCCH format 2
+      // 2- CQI or RI + 1bit Ack/Nack for normal CP  ==> PUCCH format 2a
+      // 3- CQI or RI + 2bits Ack/Nack for normal CP ==> PUCCH format 2b
+      // 4- CQI or RI + Ack/Nack for extended CP ==> PUCCH format 2
+      if(nb_cw == 0)
+      {
+          return pucch_format2;
+      }
+      if(cyclic_prefix_type == NORMAL)
+      {
+          if(nb_cw == 1)
+          {
+              return pucch_format2a;
+          }
+          if(nb_cw == 2)
+          {
+              return pucch_format2b;
+          }
+      }
+      else
+      {
+          return pucch_format2;
+      }
+  }
+  return pucch_format1a;
+}
+
+uint16_t nr_get_n1_pucch(PHY_VARS_NR_UE *ue,
+          UE_nr_rxtx_proc_t *proc,
+                      nr_harq_status_t *harq_ack,
+                      uint8_t eNB_id,
+                      uint8_t *b,
+                      uint8_t SR)
+{
+
+  NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
+  uint8_t nCCE0,nCCE1,nCCE2,nCCE3,harq_ack1,harq_ack0,harq_ack3,harq_ack2;
+  ANFBmode_t bundling_flag;
+  uint16_t n1_pucch0=0,n1_pucch1=0,n1_pucch2=0,n1_pucch3=0,n1_pucch_inter;
+  static uint8_t candidate_dl[9]; // which downlink(s) the current ACK/NACK is associating to
+  uint8_t last_dl=0xff; // the last downlink with valid DL-DCI. for calculating the PUCCH resource index
+  int sf;
+  int M;
+  uint8_t ack_counter=0;
+  // clear this, important for case where n1_pucch selection is not used
+  int nr_tti_tx=proc->nr_tti_tx;
+
+  ue->pucch_sel[nr_tti_tx] = 0;
+
+  if (frame_parms->frame_type == FDD ) { // FDD
+    sf = (nr_tti_tx<4)? nr_tti_tx+6 : nr_tti_tx-4;
+    LOG_D(PHY,"n1_pucch_UE: nr_tti_tx %d, nCCE %d\n",sf,ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[sf]);
+
+    if (SR == 0)
+      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[sf]);
+    else
+      return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
+  } else {
+
+    bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
+#ifdef DEBUG_PHY_PROC
+
+    if (bundling_flag==bundling) {
+      LOG_D(PHY,"[UE%d] Frame %d nr_tti_tx %d : nr_get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->frame_tx,nr_tti_tx,SR,
+            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
+    } else {
+      LOG_D(PHY,"[UE%d] Frame %d nr_tti_tx %d : nr_get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,proc->frame_tx,nr_tti_tx,SR,
+            ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
+    }
+
+#endif
+
+    switch (frame_parms->tdd_config) {
+    case 1:  // DL:S:UL:UL:DL:DL:S:UL:UL:DL
+
+      harq_ack0 = 2; // DTX
+      M=1;
+
+      // This is the offset for a particular nr_tti_tx (2,3,4) => (0,2,4)
+      if (nr_tti_tx == 2) {  // ACK nr_tti_txs 5,6
+        candidate_dl[0] = 6;
+        candidate_dl[1] = 5;
+        M=2;
+      } else if (nr_tti_tx == 3) { // ACK nr_tti_tx 9
+        candidate_dl[0] = 9;
+      } else if (nr_tti_tx == 7) { // ACK nr_tti_txs 0,1
+        candidate_dl[0] = 1;
+        candidate_dl[1] = 0;
+        M=2;
+      } else if (nr_tti_tx == 8) { // ACK nr_tti_txs 4
+        candidate_dl[0] = 4;
+      } else {
+        LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal tx-nr_tti_tx %d for tdd_config %d\n",
+              ue->Mod_id,proc->frame_tx,nr_tti_tx,frame_parms->tdd_config);
+        return(0);
+      }
+
+      // checking which downlink candidate is the last downlink with valid DL-DCI
+      int k;
+      for (k=0;k<M;k++) {
+        if (harq_ack[candidate_dl[k]].send_harq_status>0) {
+          last_dl = candidate_dl[k];
+          break;
+        }
+      }
+      if (last_dl >= 10) {
+        LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal rx-nr_tti_tx %d (tx-nr_tti_tx %d) for tdd_config %d\n",
+              ue->Mod_id,proc->frame_tx,last_dl,nr_tti_tx,frame_parms->tdd_config);
+        return (0);
+      }
+
+      LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch0 from last_dl=%d\n",
+          proc->frame_tx%1024,
+          proc->nr_tti_tx,
+          last_dl);
+
+      // i=0
+      nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[last_dl];
+      n1_pucch0 = nr_get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
+
+      harq_ack0 = b[0];
+
+      if (harq_ack0!=2) {  // DTX
+        if (frame_parms->frame_type == FDD ) {
+          if (SR == 0) {  // last paragraph pg 68 from 36.213 (v8.6), m=0
+            b[0]=(M==2) ? 1-harq_ack0 : harq_ack0;
+            b[1]=harq_ack0;   // in case we use pucch format 1b (subframes 2,7)
+          ue->pucch_sel[nr_tti_tx] = 0;
+            return(n1_pucch0);
+          } else { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213)
+            b[0]=harq_ack0;
+          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
+          }
+        } else {
+          if (SR == 0) {
+            b[0] = harq_ack0;
+            b[1] = harq_ack0;
+            ue->pucch_sel[nr_tti_tx] = 0;
+            return(n1_pucch0);
+          } else {
+            b[0] = harq_ack0;
+            b[1] = harq_ack0;
+            return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
+          }
+        }
+      }
+
+
+      break;
+
+    case 3:  // DL:S:UL:UL:UL:DL:DL:DL:DL:DL
+      // in this configuration we have M=2 from pg 68 of 36.213 (v8.6)
+      // Note: this doesn't allow using nr_tti_tx 1 for PDSCH transmission!!! (i.e. SF 1 cannot be acked in SF 2)
+      // set ACK/NAKs to DTX
+      harq_ack1 = 2; // DTX
+      harq_ack0 = 2; // DTX
+      // This is the offset for a particular nr_tti_rx (2,3,4) => (0,2,4)
+      last_dl = (nr_tti_tx-2)<<1;
+      // i=0
+      nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[5+last_dl];
+      n1_pucch0 = nr_get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
+      // i=1
+      nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[(6+last_dl)%10];
+      n1_pucch1 = nr_get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
+
+      // set ACK/NAK to values if not DTX
+      if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0)  // n-6 // nr_tti_tx 6 is to be ACK/NAKed
+        harq_ack1 = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].ack;
+
+      if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0)  // n-6 // nr_tti_tx 5 is to be ACK/NAKed
+        harq_ack0 = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[5+last_dl].ack;
+
+      LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d\n",
+                                      proc->frame_tx%1024,
+                                      proc->nr_tti_tx,
+                                      nCCE0,n1_pucch0,
+                                      nCCE1,n1_pucch1);
+
+      if (harq_ack1!=2) { // n-6 // nr_tti_tx 6,8,0 and maybe 5,7,9 is to be ACK/NAKed
+
+        if ((bundling_flag==bundling)&&(SR == 0)) {  // This is for bundling without SR,
+          // n1_pucch index takes value of smallest element in set {0,1}
+          // i.e. 0 if harq_ack0 is not DTX, otherwise 1
+          b[0] = harq_ack1;
+
+          if (harq_ack0!=2)
+            b[0]=b[0]&harq_ack0;
+
+          ue->pucch_sel[nr_tti_tx] = 1;
+          return(n1_pucch1);
+
+        } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1
+          if (harq_ack0 == 2)
+            harq_ack0 = 0;
+
+          b[1] = harq_ack0;
+          b[0] = (harq_ack0!=harq_ack1)?0:1;
+
+          if ((harq_ack0 == 1) && (harq_ack1 == 0)) {
+            ue->pucch_sel[nr_tti_tx] = 0;
+            return(n1_pucch0);
+          } else {
+            ue->pucch_sel[nr_tti_tx] = 1;
+            return(n1_pucch1);
+          }
+        } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213)
+          // this should be number of ACKs (including
+          if (harq_ack0 == 2)
+            harq_ack0 = 0;
+
+          b[0]= harq_ack1 | harq_ack0;
+          b[1]= harq_ack1 ^ harq_ack0;
+          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
+        }
+      } else if (harq_ack0!=2) { // n-7  // nr_tti_tx 5,7,9 only is to be ACK/NAKed
+        if ((bundling_flag==bundling)&&(SR == 0)) {  // last paragraph pg 68 from 36.213 (v8.6), m=0
+          b[0]=harq_ack0;
+          ue->pucch_sel[nr_tti_tx] = 0;
+          return(n1_pucch0);
+        } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1 with i=1 set to DTX
+          b[0] = harq_ack0;
+          b[1] = 1-b[0];
+          ue->pucch_sel[nr_tti_tx] = 0;
+          return(n1_pucch0);
+        } else if (SR==1) { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213)
+          b[0]=harq_ack0;
+          b[1]=b[0];
+          return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
+        }
+      }
+
+      break;
+
+    case 4:  // DL:S:UL:UL:DL:DL:DL:DL:DL:DL
+          // in this configuration we have M=4 from pg 68 of 36.213 (v8.6)
+          // Note: this doesn't allow using nr_tti_tx 1 for PDSCH transmission!!! (i.e. SF 1 cannot be acked in SF 2)
+          // set ACK/NAKs to DTX
+          harq_ack3 = 2; // DTX
+          harq_ack2 = 2; // DTX
+          harq_ack1 = 2; // DTX
+          harq_ack0 = 2; // DTX
+          // This is the offset for a particular nr_tti_tx (2,3,4) => (0,2,4)
+          //last_dl = (nr_tti_tx-2)<<1;
+          if (nr_tti_tx == 2) {
+          // i=0
+          //nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[2+nr_tti_tx];
+          nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[(8+nr_tti_tx)%10];
+          n1_pucch0 = 2*nr_get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=1
+          nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[2+nr_tti_tx];
+          n1_pucch1 = nr_get_Np(frame_parms->N_RB_DL,nCCE1,0) + nr_get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=2
+          nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[(8+nr_tti_tx)%10];
+
+          n1_pucch2 = 2*nr_get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=3
+          //nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[(9+nr_tti_tx)%10];
+          //n1_pucch3 = nr_get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN;
+
+          // set ACK/NAK to values if not DTX
+          if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[(8+nr_tti_tx)%10].send_harq_status>0)  // n-6 // nr_tti_tx 6 is to be ACK/NAKed
+            harq_ack0 = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[(8+nr_tti_tx)%10].ack;
+
+          if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[2+nr_tti_tx].send_harq_status>0)  // n-6 // nr_tti_tx 5 is to be ACK/NAKed
+            harq_ack1 = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[2+nr_tti_tx].ack;
+
+          if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[3+nr_tti_tx].send_harq_status>0)  // n-6 // nr_tti_tx 6 is to be ACK/NAKed
+            harq_ack2 = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[3+nr_tti_tx].ack;
+
+          //if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[(9+nr_tti_tx)%10].send_harq_status>0)  // n-6 // nr_tti_tx 5 is to be ACK/NAKed
+            //harq_ack3 = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[(9+nr_tti_tx)%10].ack;
+          //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d cce2=%d n1_pucch2=%d\n",
+          //                      proc->frame_tx%1024,
+          //                      proc->nr_tti_tx_tx,
+          //                      nCCE0,n1_pucch0,
+          //                      nCCE1,n1_pucch1, nCCE2, n1_pucch2);
+          }else if (nr_tti_tx == 3) {
+          // i=0
+
+          nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[4+nr_tti_tx];
+          n1_pucch0 = 3*nr_get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=1
+          nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[5+nr_tti_tx];
+          n1_pucch1 = 2*nr_get_Np(frame_parms->N_RB_DL,nCCE1,0) + nr_get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=2
+          nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[(6+nr_tti_tx)];
+          n1_pucch2 = nr_get_Np(frame_parms->N_RB_DL,nCCE2,0) + 2*nr_get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
+          // i=3
+          nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->nCCE[(3+nr_tti_tx)];
+          n1_pucch3 = 3*nr_get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN;
+
+          // set ACK/NAK to values if not DTX
+          if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[4+nr_tti_tx].send_harq_status>0)  // n-6 // nr_tti_tx 6 is to be ACK/NAKed
+          harq_ack0 = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[4+nr_tti_tx].ack;
+
+          if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[5+nr_tti_tx].send_harq_status>0)  // n-6 // nr_tti_tx 5 is to be ACK/NAKed
+          harq_ack1 = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[5+nr_tti_tx].ack;
+
+          if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[(6+nr_tti_tx)].send_harq_status>0)  // n-6 // nr_tti_tx 6 is to be ACK/NAKed
+          harq_ack2 = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[(6+nr_tti_tx)].ack;
+
+          if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[(3+nr_tti_tx)].send_harq_status>0)  // n-6 // nr_tti_tx 5 is to be ACK/NAKed
+          harq_ack3 = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack[(3+nr_tti_tx)].ack;
+          }
+
+          //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d harq_ack0=%d cce1=%d n1_pucch1=%d harq_ack1=%d cce2=%d n1_pucch2=%d harq_ack2=%d cce3=%d n1_pucch3=%d harq_ack3=%d bundling_flag=%d\n",
+          //                                proc->frame_tx%1024,
+          //                                proc->nr_tti_tx,
+          //                                nCCE0,n1_pucch0,harq_ack0,
+          //                                nCCE1,n1_pucch1,harq_ack1, nCCE2, n1_pucch2, harq_ack2,
+          //                                nCCE3, n1_pucch3, harq_ack3, bundling_flag);
+
+          if ((bundling_flag==bundling)&&(SR == 0)) {  // This is for bundling without SR,
+             b[0] = 1;
+             ack_counter = 0;
+
+             if ((harq_ack3!=2) ) {
+                b[0] = b[0]&harq_ack3;
+                n1_pucch_inter = n1_pucch3;
+                ack_counter ++;
+             }
+             if ((harq_ack0!=2) ) {
+                b[0] = b[0]&harq_ack0;
+                n1_pucch_inter = n1_pucch0;
+                ack_counter ++;
+             }
+             if ((harq_ack1!=2) ) {
+                b[0] = b[0]&harq_ack1;
+                n1_pucch_inter = n1_pucch1;
+                ack_counter ++;
+             }
+             if ((harq_ack2!=2) ) {
+                b[0] = b[0]&harq_ack2;
+                n1_pucch_inter = n1_pucch2;
+                ack_counter ++;
+             }
+
+             if (ack_counter == 0)
+                 b[0] = 0;
+
+             /*if (nr_tti_tx == 3) {
+                n1_pucch_inter = n1_pucch2;
+             } else if (nr_tti_tx == 2) {
+                n1_pucch_inter = n1_pucch1;
+             }*/
+
+             //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch n1_pucch_inter=%d  b[0]=%d b[1]=%d \n",
+             //                                           proc->frame_tx%1024,
+             //                                           proc->nr_tti_tx,n1_pucch_inter,
+             //                                           b[0],b[1]);
+
+              return(n1_pucch_inter);
+
+            } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1
+
+             if (nr_tti_tx == 3) {
+                 LOG_I(PHY, "sbuframe=%d \n",nr_tti_tx);
+              if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
+                b[0] = 1;
+                b[1] = 1;
+                return(n1_pucch1);
+              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 1;
+                b[1] = 0;
+                return(n1_pucch1);
+              } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 0) && (harq_ack3 == 2)) {
+                b[0] = 1;
+                b[1] = 1;
+                return(n1_pucch2);
+              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
+                b[0] = 1;
+                b[1] = 0;
+                return(n1_pucch1);
+              } else if ((harq_ack0 == 0) && (harq_ack1 == 2) && (harq_ack2 == 2) && (harq_ack3 == 2)) {
+                b[0] = 1;
+                b[1] = 0;
+                return(n1_pucch0);
+              } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 1;
+                b[1] = 0;
+                return(n1_pucch1);
+              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch3);
+              } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 0)) {
+                b[0] = 1;
+                b[1] = 1;
+                return(n1_pucch3);
+              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch2);
+              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch0);
+              } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch0);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch3);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 0) && (harq_ack2 == 2) && (harq_ack3 == 2)) {
+                b[0] = 0;
+                b[1] = 0;
+                return(n1_pucch1);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 1;
+                b[1] = 0;
+                return(n1_pucch2);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
+                b[0] = 1;
+                b[1] = 0;
+                return(n1_pucch3);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch1);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
+                b[0] = 0;
+                b[1] = 1;
+                return(n1_pucch3);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
+                b[0] = 0;
+                b[1] = 0;
+                return(n1_pucch2);
+              } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack3 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                b[0] = 0;
+                b[1] = 0;
+                return(n1_pucch3);
+                }
+             } else if (nr_tti_tx == 2) {
+                if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1)) {
+                 b[0] = 1;
+                 b[1] = 1;
+                 return(n1_pucch2);
+               } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                 b[0] = 1;
+                 b[1] = 1;
+                 return(n1_pucch1);
+               } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) {
+                 b[0] = 1;
+                 b[1] = 1;
+                 return(n1_pucch0);
+               } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                 b[0] = 0;
+                 b[1] = 1;
+                 return(n1_pucch0);
+               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1)) {
+                 b[0] = 1;
+                 b[1] = 0;
+                 return(n1_pucch2);
+               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                 b[1] = 0;
+                 b[0] = 0;
+                 return(n1_pucch1);
+               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) {
+                 b[0] = 0;
+                 b[1] = 0;
+                 return(n1_pucch2);
+               } else if ((harq_ack0 == 2) && (harq_ack1 == 2) && (harq_ack2 == 0)) {
+                 b[0] = 0;
+                 b[1] = 1;
+                 return(n1_pucch2);
+               } else if ((harq_ack0 == 2) && (harq_ack1 == 0) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                 b[0] = 1;
+                 b[1] = 0;
+                 return(n1_pucch1);
+               } else if ((harq_ack0 == 0) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                 b[0] = 1;
+                 b[1] = 0;
+                 return(n1_pucch0);
+               }
+
+             }
+            } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213)
+              // this should be number of ACKs (including
+              ack_counter = 0;
+              if (harq_ack0==1)
+                 ack_counter ++;
+              if (harq_ack1==1)
+                 ack_counter ++;
+              if (harq_ack2==1)
+                 ack_counter ++;
+              if (harq_ack3==1)
+                 ack_counter ++;
+
+            switch (ack_counter) {
+               case 0:
+                 b[0] = 0;
+                 b[1] = 0;
+               break;
+
+               case 1:
+                 b[0] = 1;
+                 b[1] = 1;
+               break;
+
+               case 2:
+                 b[0] = 1;
+                 b[1] = 0;
+               break;
+
+               case 3:
+                 b[0] = 0;
+                 b[1] = 1;
+               break;
+
+               case 4:
+                 b[0] = 1;
+                 b[1] = 1;
+               break;
+            }
+
+            ack_counter = 0;
+            return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
+          }
+
+          break;
+
+    }  // switch tdd_config
+  }
+
+  LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, exit without proper return\n", ue->Mod_id, proc->frame_tx);
+  return(-1);
+}
+
+
+#ifdef EMOS
+
+  void phy_procedures_emos_UE_TX(uint8_t next_slot,uint8_t eNB_id) {
+  uint8_t harq_pid;
+
+
+  if (next_slot%2==0) {
+  // get harq_pid from nr_tti_tx relationship
+  harq_pid = nr_subframe2harq_pid(&ue->frame_parms,ue->frame,(next_slot>>1));
+  if (harq_pid==255) {
+  LOG_E(PHY,"[UE%d] Frame %d : FATAL ERROR: illegal harq_pid, returning\n",
+  0,ue->frame);
+  return;
+  }
+
+  if (ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
+  emos_dump_UE.uci_cnt[next_slot>>1] = 1;
+  memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o,ulsch[eNB_id]->o,MAX_CQI_BITS*sizeof(char));
+  emos_dump_UE.UCI_data[0][next_slot>>1].O = ulsch[eNB_id]->O;
+  memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o_RI,ulsch[eNB_id]->o_RI,2*sizeof(char));
+  emos_dump_UE.UCI_data[0][next_slot>>1].O_RI = ulsch[eNB_id]->O_RI;
+  memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o_ACK,ulsch[eNB_id]->o_ACK,4*sizeof(char));
+  emos_dump_UE.UCI_data[0][next_slot>>1].O_ACK = ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK;
+  }
+  else {
+  emos_dump_UE.uci_cnt[next_slot>>1] = 0;
+  }
+  }
+  }
+
+#endif
+
+void ulsch_common_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t empty_subframe) {
+
+  int aa;
+  NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
+
+  int nsymb;
+  int nr_tti_tx = proc->nr_tti_tx;
+  int frame_tx = proc->frame_tx;
+  int ulsch_start;
+  int overflow=0;
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+  int k,l;
+  int dummy_tx_buffer[frame_parms->samples_per_subframe] __attribute__((aligned(16)));
+#endif
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN);
+#if UE_TIMING_TRACE
+  start_meas(&ue->ofdm_mod_stats);
+#endif
+  nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)//this is the EXPRESS MIMO case
+  ulsch_start = (ue->rx_offset+nr_tti_tx*frame_parms->samples_per_subframe-
+         ue->hw_timing_advance-
+         ue->timing_advance-
+         ue->N_TA_offset+5);
+  //LOG_E(PHY,"ul-signal [nr_tti_rx: %d, ulsch_start %d]\n",nr_tti_tx, ulsch_start);
+
+  if(ulsch_start < 0)
+      ulsch_start = ulsch_start + (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe);
+
+  if (ulsch_start > (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe))
+      ulsch_start = ulsch_start % (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe);
+
+  //LOG_E(PHY,"ul-signal [nr_tti_rx: %d, ulsch_start %d]\n",nr_tti_tx, ulsch_start);
+#else //this is the normal case
+  ulsch_start = (frame_parms->samples_per_subframe*nr_tti_tx)-ue->N_TA_offset; //-ue->timing_advance;
+#endif //else EXMIMO
+
+//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+  if (empty_subframe)
+  {
+//#if 1
+      overflow = ulsch_start - 9*frame_parms->samples_per_subframe;
+      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+
+          if (overflow > 0)
+     {
+       memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_subframe-overflow));
+       memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
+     }
+     else
+     {
+       memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_subframe);
+     }
+      }
+/*#else
+      overflow = ulsch_start - 9*frame_parms->samples_per_subframe;
+      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+          for (k=ulsch_start; k<cmin(frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_subframe); k++) {
+              ((short*)ue->common_vars.txdata[aa])[2*k] = 0;
+              ((short*)ue->common_vars.txdata[aa])[2*k+1] = 0;
+          }
+
+          for (k=0; k<overflow; k++) {
+              ((short*)ue->common_vars.txdata[aa])[2*k] = 0;
+              ((short*)ue->common_vars.txdata[aa])[2*k+1] = 0;
+          }
+      }
+endif*/
+      return;
+  }
+
+
+  if ((frame_tx%100) == 0)
+    LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n",
+    ue->Mod_id,frame_tx,nr_tti_tx,
+    ulsch_start,
+    ue->rx_offset,
+    ue->hw_timing_advance,
+    ue->timing_advance,
+    ue->N_TA_offset);
+
+
+  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+    if (frame_parms->Ncp == 1)
+      PHY_ofdm_mod(&ue->common_vars.txdataF[aa][nr_tti_tx*nsymb*frame_parms->ofdm_symbol_size],
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+       dummy_tx_buffer,
+#else
+       &ue->common_vars.txdata[aa][ulsch_start],
+#endif
+       frame_parms->ofdm_symbol_size,
+       nsymb,
+       frame_parms->nb_prefix_samples,
+       CYCLIC_PREFIX);
+    else
+      normal_prefix_mod(&ue->common_vars.txdataF[aa][nr_tti_tx*nsymb*frame_parms->ofdm_symbol_size],
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+      dummy_tx_buffer,
+#else
+      &ue->common_vars.txdata[aa][ulsch_start],
+#endif
+      nsymb,
+      &ue->frame_parms);
+
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+    apply_7_5_kHz(ue,dummy_tx_buffer,0);
+    apply_7_5_kHz(ue,dummy_tx_buffer,1);
+#else
+    apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],0);
+    apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],1);
+#endif
+
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+    overflow = ulsch_start - 9*frame_parms->samples_per_subframe;
+
+
+    for (k=ulsch_start,l=0; k<cmin(frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_subframe); k++,l++) {
+      ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
+      ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
+    }
+
+    for (k=0; k<overflow; k++,l++) {
+      ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
+      ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
+    }
+#if defined(EXMIMO)
+    // handle switch before 1st TX nr_tti_rx, guarantee that the slot prior to transmission is switch on
+    for (k=ulsch_start - (frame_parms->samples_per_subframe>>1) ; k<ulsch_start ; k++) {
+      if (k<0)
+  ue->common_vars.txdata[aa][k+frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
+      else if (k>(frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
+  ue->common_vars.txdata[aa][k-frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
+      else
+  ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE;
+    }
+#endif
+#endif
+    /*
+    only for debug
+    LOG_I(PHY,"ul-signal [nr_tti_rx: %d, ulsch_start %d, TA: %d, rxOffset: %d, timing_advance: %d, hw_timing_advance: %d]\n",nr_tti_tx, ulsch_start, ue->N_TA_offset, ue->rx_offset, ue->timing_advance, ue->hw_timing_advance);
+    if( (crash == 1) && (nr_tti_tx == 0) )
+    {
+      LOG_E(PHY,"***** DUMP TX Signal [ulsch_start %d] *****\n",ulsch_start);
+      write_output("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_subframe,1,1);
+    }
+    */
+
+  } //nb_antennas_tx
+
+#if UE_TIMING_TRACE
+      stop_meas(&ue->ofdm_mod_stats);
+#endif
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT);
+
+}
+
+void ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) {
+
+  int frame_tx = proc->frame_tx;
+  int nr_tti_tx = proc->nr_tti_tx;
+  int prach_power;
+  PRACH_RESOURCES_t prach_resources_local;
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
+
+  ue->generate_prach=0;
+
+  if (ue->mac_enabled==0){
+    ue->prach_resources[eNB_id] = &prach_resources_local;
+    prach_resources_local.ra_RNTI = 0xbeef;
+    prach_resources_local.ra_PreambleIndex = 0;
+  }
+
+  if (ue->mac_enabled==1){
+    // ask L2 for RACH transport
+    if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
+      LOG_D(PHY,"Getting PRACH resources\n");
+      //ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,
+                 ue->CC_id,
+                 frame_tx,
+                 eNB_id,
+                 nr_tti_tx);
+      LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon);
+      LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
+    }
+  }
+
+  if (ue->prach_resources[eNB_id]!=NULL) {
+
+    ue->generate_prach=1;
+    ue->prach_cnt=0;
+#ifdef SMBV
+    ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
+#endif
+#ifdef OAI_EMU
+    ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex;
+#endif
+
+    if (abstraction_flag == 0) {
+
+      LOG_I(PHY,"mode %d\n",mode);
+
+      if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
+  ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id);
+      }
+      else {
+  ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm;
+  ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
+      }
+
+      LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d,  P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
+      ue->Mod_id,
+      frame_tx,
+      nr_tti_tx,
+      ue->prach_resources[eNB_id]->ra_PreambleIndex,
+    get_PL(ue->Mod_id,ue->CC_id,eNB_id),
+    ue->tx_power_dBm[nr_tti_tx],
+      ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
+      ue->prach_resources[eNB_id]->ra_TDD_map_index,
+      ue->prach_resources[eNB_id]->ra_RNTI);
+
+      ue->tx_total_RE[nr_tti_tx] = 96;
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+      ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx],
+                 ue->tx_power_max_dBm,
+                 ue->frame_parms.N_RB_UL,
+                 6);
+#else
+      ue->prach_vars[eNB_id]->amp = AMP;
+#endif
+      if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
+  LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n",
+        ue->Mod_id,
+        proc->frame_rx,
+        proc->nr_tti_tx,
+        ue->tx_power_dBm[nr_tti_tx],
+        ue->prach_vars[eNB_id]->amp);
+
+
+      //      start_meas(&ue->tx_prach);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
+      prach_power = generate_prach(ue,eNB_id,nr_tti_tx,frame_tx);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
+      //      stop_meas(&ue->tx_prach);
+      LOG_D(PHY,"[UE  %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
+      ue->Mod_id,
+      get_PL(ue->Mod_id,ue->CC_id,eNB_id),
+      ue->tx_power_dBm[nr_tti_tx],
+      dB_fixed(prach_power),
+      ue->prach_vars[eNB_id]->amp);
+    } else {
+      UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
+      UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
+    }
+
+    if (ue->mac_enabled==1){
+      //mac_xface->Msg1_transmitted(ue->Mod_id,
+          ue->CC_id,
+          frame_tx,
+          eNB_id);
+    }
+
+    LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
+    ue->Mod_id,frame_tx,nr_tti_tx,eNB_id,
+    ue->prach_resources[eNB_id]->ra_PreambleIndex,
+    ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id),
+    get_PL(ue->Mod_id,ue->CC_id,eNB_id));
+
+  }
+
+
+  // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
+  if (mode == calib_prach_tx)
+    ue->prach_resources[eNB_id]=NULL;
+
+  LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_prach %d, prach_cnt %d\n",
+  ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_prach,ue->prach_cnt);
+
+  ue->prach_cnt++;
+
+  if (ue->prach_cnt==3)
+    ue->generate_prach=0;
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
+}
+
+void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
+
+  int harq_pid;
+  int frame_tx=proc->frame_tx;
+  int nr_tti_tx=proc->nr_tti_tx;
+  int Mod_id = ue->Mod_id;
+  int CC_id = ue->CC_id;
+  uint8_t Msg3_flag=0;
+  uint16_t first_rb, nb_rb;
+  unsigned int input_buffer_length;
+  int i;
+  int aa;
+  int tx_amp;
+  uint8_t ulsch_input_buffer[5477] __attribute__ ((aligned(32)));
+  uint8_t access_mode;
+  uint8_t Nbundled=0;
+  uint8_t NbundledCw1=0;
+  uint8_t ack_status_cw0=0;
+  uint8_t ack_status_cw1=0;
+  uint8_t cqi_status = 0;
+  uint8_t ri_status  = 0;
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_IN);
+
+  // get harq_pid from nr_tti_rx relationship
+  harq_pid = nr_subframe2harq_pid(&ue->frame_parms,
+             frame_tx,
+             nr_tti_tx);
+
+
+  if (ue->mac_enabled == 1) {
+    if ((ue->ulsch_Msg3_active[eNB_id] == 1) &&
+  (ue->ulsch_Msg3_frame[eNB_id] == frame_tx) &&
+  (ue->ulsch_Msg3_subframe[eNB_id] == nr_tti_tx)) { // Initial Transmission of Msg3
+
+      ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+
+      if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0)
+  generate_ue_ulsch_params_from_rar(ue,
+            proc,
+            eNB_id);
+
+      ue->ulsch[eNB_id]->power_offset = 14;
+      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d: Setting Msg3_flag in nr_tti_rx %d, for harq_pid %d\n",
+      Mod_id,
+      frame_tx,
+      nr_tti_tx,
+      harq_pid);
+      Msg3_flag = 1;
+    } else {
+
+      if (harq_pid==255) {
+	LOG_E(PHY,"[UE%d] Frame %d nr_tti_rx %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, returning\n",
+	      Mod_id,frame_tx, nr_tti_tx);
+	//mac_xface->macphy_exit("Error in ulsch_decoding");
+	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->phy_proc_tx);
+#endif
+	return;
+      }
+
+      Msg3_flag=0;
+    }
+  }
+
+  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
+
+    uint8_t isBad = 0;
+    if (ue->frame_parms.N_RB_UL <= ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb) {
+      LOG_D(PHY,"Invalid PUSCH first_RB=%d for N_RB_UL=%d\n",
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
+          ue->frame_parms.N_RB_UL);
+      isBad = 1;
+    }
+    if (ue->frame_parms.N_RB_UL < ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb) {
+      LOG_D(PHY,"Invalid PUSCH num_RB=%d for N_RB_UL=%d\n",
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
+          ue->frame_parms.N_RB_UL);
+      isBad = 1;
+    }
+    if (0 > ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb) {
+      LOG_D(PHY,"Invalid PUSCH first_RB=%d\n",
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb);
+      isBad = 1;
+    }
+    if (0 >= ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb) {
+      LOG_D(PHY,"Invalid PUSCH num_RB=%d\n",
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb);
+      isBad = 1;
+    }
+    if (ue->frame_parms.N_RB_UL < (ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb)) {
+      LOG_D(PHY,"Invalid PUSCH num_RB=%d + first_RB=%d for N_RB_UL=%d\n",
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
+          ue->frame_parms.N_RB_UL);
+      isBad = 1;
+    }
+    if ((0 > ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx) ||
+        (3 < ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx)) {
+      LOG_D(PHY,"Invalid PUSCH RV index=%d\n", ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx);
+      isBad = 1;
+    }
+
+    if (20 < ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs) {
+       LOG_D(PHY,"Not supported MCS in OAI mcs=%d\n", ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs);
+       isBad = 1;
+    }
+
+    if (isBad) {
+      LOG_I(PHY,"Skip PUSCH generation!\n");
+      ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+    }
+  }
+  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
+
+    ue->generate_ul_signal[eNB_id] = 1;
+
+    // deactivate service request
+    // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+    LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,nr_tti_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit);
+    if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1))
+    {
+        LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n");
+        ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+        ue->ulsch[eNB_id]->harq_processes[harq_pid]->round  = 0;
+    }
+
+    ack_status_cw0 = nr_reset_ack(&ue->frame_parms,
+            ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack,
+            nr_tti_tx,
+            proc->nr_tti_rx,
+            ue->ulsch[eNB_id]->o_ACK,
+            &Nbundled,
+            0);
+    ack_status_cw1 = nr_reset_ack(&ue->frame_parms,
+            ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][1]->harq_ack,
+            nr_tti_tx,
+            proc->nr_tti_rx,
+            ue->ulsch[eNB_id]->o_ACK,
+            &NbundledCw1,
+            1);
+
+    //Nbundled = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack;
+    //ue->ulsch[eNB_id]->bundling = Nbundled;
+
+    first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
+    nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
+
+
+    // check Periodic CQI/RI reporting
+    cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
+        (is_cqi_TXOp(ue,proc,eNB_id)==1));
+
+    ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
+             (is_ri_TXOp(ue,proc,eNB_id)==1));
+
+    // compute CQI/RI resources
+    compute_cqi_ri_resources(ue, ue->ulsch[eNB_id], eNB_id, ue->ulsch[eNB_id]->rnti, P_RNTI, CBA_RNTI, cqi_status, ri_status);
+
+    if (ack_status_cw0 > 0) {
+
+      // check if we received a PDSCH at nr_tti_tx - 4
+      // ==> send ACK/NACK on PUSCH
+      if (ue->frame_parms.frame_type == FDD)
+      {
+        ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1;
+      }
+
+
+#if T_TRACER
+    if(ue->ulsch[eNB_id]->o_ACK[0])
+    {
+    	LOG_I(PHY,"PUSCH ACK\n");
+        T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->rnti),
+                      T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->current_harq_pid));
+    }
+    else
+    {
+    	LOG_I(PHY,"PUSCH NACK\n");
+        T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->rnti),
+                      T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->current_harq_pid));
+    }
+#endif
+#ifdef UE_DEBUG_TRACE
+      LOG_I(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n",
+        Mod_id,
+        ue->ulsch[eNB_id]->rnti,
+        frame_tx%1024,nr_tti_tx,
+        ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
+        ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
+#endif
+    }
+
+    //#ifdef UE_DEBUG_TRACE
+        LOG_I(PHY,
+              "[UE  %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, tbs %d, rv %d, "
+              "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, ack_status_cw0 %d ack_status_cw1 %d bundling %d, Nbundled %d, CQI %d, RI %d\n",
+          Mod_id,harq_pid,frame_tx%1024,nr_tti_tx,
+          first_rb,nb_rb,
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs,
+	      ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS,
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
+          (ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift+
+           ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2+
+           ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[nr_tti_tx<<1])%12,
+          ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2,
+          ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[nr_tti_tx<<1],
+          ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK,
+          ack_status_cw0,
+          ack_status_cw1,
+          ue->ulsch[eNB_id]->bundling, Nbundled,
+          cqi_status,
+          ri_status);
+	//#endif
+
+
+
+
+
+    if (Msg3_flag == 1) {
+      LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, nr_tti_rx %d Generating (RRCConnectionRequest) Msg3 (nb_rb %d, first_rb %d, round %d, rvidx %d) Msg3: %x.%x.%x|%x.%x.%x.%x.%x.%x\n",Mod_id,frame_tx,
+	    nr_tti_tx,
+	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
+	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
+	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
+	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
+	    ue->prach_resources[eNB_id]->Msg3[0],
+	    ue->prach_resources[eNB_id]->Msg3[1],
+	    ue->prach_resources[eNB_id]->Msg3[2],
+	    ue->prach_resources[eNB_id]->Msg3[3],
+	    ue->prach_resources[eNB_id]->Msg3[4],
+	    ue->prach_resources[eNB_id]->Msg3[5],
+	    ue->prach_resources[eNB_id]->Msg3[6],
+	    ue->prach_resources[eNB_id]->Msg3[7],
+	    ue->prach_resources[eNB_id]->Msg3[8]);
+#if UE_TIMING_TRACE
+      start_meas(&ue->ulsch_encoding_stats);
+#endif
+
+      if (abstraction_flag==0) {
+	if (ulsch_encoding(ue->prach_resources[eNB_id]->Msg3,
+			   ue,
+			   harq_pid,
+			   eNB_id,
+			   proc->nr_tti_rx,
+			   ue->transmission_mode[eNB_id],0,0)!=0) {
+	  LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
+	  //mac_xface->macphy_exit("Error in ulsch_coding");
+	  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+	  stop_meas(&ue->phy_proc_tx);
+	  printf("------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0));
+#endif
+	  return;
+	}
+      }
+
+#ifdef PHY_ABSTRACTION
+      else {
+        ulsch_encoding_emul(ue->prach_resources[eNB_id]->Msg3,ue,eNB_id,proc->nr_tti_rx,harq_pid,0);
+      }
+
+#endif
+
+#if UE_TIMING_TRACE
+      stop_meas(&ue->ulsch_encoding_stats);
+#endif
+      if (ue->mac_enabled == 1) {
+  // signal MAC that Msg3 was sent
+  //mac_xface->Msg3_transmitted(Mod_id,
+            CC_id,
+            frame_tx,
+            eNB_id);
+      }
+    } // Msg3_flag==1
+    else {
+      input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
+
+      if (ue->mac_enabled==1) {
+  //  LOG_D(PHY,"[UE  %d] ULSCH : Searching for MAC SDUs\n",Mod_id);
+  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) {
+    //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) {
+    access_mode=SCHEDULED_ACCESS;
+    //mac_xface->ue_get_sdu(Mod_id,
+        CC_id,
+        frame_tx,
+        proc->subframe_tx,
+        nr_tti_tx%(ue->frame_parms.ttis_per_subframe),
+        eNB_id,
+        ulsch_input_buffer,
+        input_buffer_length,
+        &access_mode);
+  }
+
+#ifdef DEBUG_PHY_PROC
+#ifdef DEBUG_ULSCH
+  LOG_D(PHY,"[UE] Frame %d, nr_tti_rx %d : ULSCH SDU (TX harq_pid %d)  (%d bytes) : \n",frame_tx,nr_tti_tx,harq_pid, ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3);
+
+  for (i=0; i<ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; i++)
+    LOG_T(PHY,"%x.",ulsch_input_buffer[i]);
+
+  LOG_T(PHY,"\n");
+#endif
+#endif
+      }
+      else {
+  unsigned int taus(void);
+
+  for (i=0; i<input_buffer_length; i++)
+    ulsch_input_buffer[i]= (uint8_t)(taus()&0xff);
+
+      }
+
+#if UE_TIMING_TRACE
+      start_meas(&ue->ulsch_encoding_stats);
+#endif
+      if (abstraction_flag==0) {
+
+	if (ulsch_encoding(ulsch_input_buffer,
+			   ue,
+			   harq_pid,
+			   eNB_id,
+			   proc->nr_tti_rx,
+         ue->transmission_mode[eNB_id],0,
+         Nbundled)!=0) {
+	  LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
+	  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+      stop_meas(&ue->phy_proc_tx);
+#endif
+	  return;
+	}
+      }
+
+#ifdef PHY_ABSTRACTION
+      else {
+        ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->nr_tti_rx,harq_pid,0);
+      }
+
+#endif
+#if UE_TIMING_TRACE
+      stop_meas(&ue->ulsch_encoding_stats);
+#endif
+    }
+
+    if (abstraction_flag == 0) {
+      if (ue->mac_enabled==1) {
+  nr_pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag);
+  ue->tx_power_dBm[nr_tti_tx] = ue->ulsch[eNB_id]->Po_PUSCH;
+      }
+      else {
+  ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm;
+      }
+      ue->tx_total_RE[nr_tti_tx] = nb_rb*12;
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+      tx_amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx],
+        ue->tx_power_max_dBm,
+        ue->frame_parms.N_RB_UL,
+        nb_rb);
+#else
+      tx_amp = AMP;
+#endif
+#if T_TRACER
+      T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx),T_INT(ue->tx_power_dBm[nr_tti_tx]),
+                    T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb));
+#endif
+
+#ifdef UE_DEBUG_TRACE
+      LOG_I(PHY,"[UE  %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
+	    Mod_id,harq_pid,frame_tx%1024,nr_tti_tx,ue->tx_power_dBm[nr_tti_tx],ue->tx_power_max_dBm, tx_amp);
+#endif
+
+      if (tx_amp>100)
+	tx_amp =100;
+
+      //LOG_I(PHY,"[UE  %d][PUSCH %d] after AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
+	//    Mod_id,harq_pid,frame_tx%1024,nr_tti_tx,ue->tx_power_dBm[nr_tti_tx],ue->tx_power_max_dBm, tx_amp);
+
+      
+#if UE_TIMING_TRACE
+
+      start_meas(&ue->ulsch_modulation_stats);
+#endif
+      ulsch_modulation(ue->common_vars.txdataF,
+           tx_amp,
+           frame_tx,
+           nr_tti_tx,
+           &ue->frame_parms,
+           ue->ulsch[eNB_id]);
+      for (aa=0; aa<1/*frame_parms->nb_antennas_tx*/; aa++)
+	generate_drs_pusch(ue,
+			   proc,
+			   eNB_id,
+			   tx_amp,
+			   nr_tti_tx,
+			   first_rb,
+			   nb_rb,
+			   aa);
+#if UE_TIMING_TRACE
+      stop_meas(&ue->ulsch_modulation_stats);
+#endif
+    }
+
+    if (abstraction_flag==1) {
+      // clear SR
+      ue->sr[nr_tti_tx]=0;
+    }
+  } // subframe_scheduling_flag==1
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_OUT);
+
+}
+
+void ue_srs_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag)
+{
+
+  //NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  //int8_t  frame_tx    = proc->frame_tx;
+  int8_t  nr_tti_tx = proc->nr_tti_tx;
+  int16_t tx_amp;
+  int16_t Po_SRS;
+  uint8_t nb_rb_srs;
+
+  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
+  uint8_t isSrsTxOccasion = pSoundingrs_ul_config_dedicated->srsUeSubframe;
+
+  if(isSrsTxOccasion)
+  {
+    ue->generate_ul_signal[eNB_id] = 1;
+    if (ue->mac_enabled==1)
+    {
+      srs_power_cntl(ue,proc,eNB_id, (uint8_t*)(&nb_rb_srs), abstraction_flag);
+      Po_SRS = ue->ulsch[eNB_id]->Po_SRS;
+    }
+    else
+    {
+      Po_SRS = ue->tx_power_max_dBm;
+    }
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+    if (ue->mac_enabled==1)
+    {
+    tx_amp = get_tx_amp(Po_SRS,
+                        ue->tx_power_max_dBm,
+                        ue->frame_parms.N_RB_UL,
+                        nb_rb_srs);
+    }
+    else
+    {
+        tx_amp = AMP;
+    }
+#else
+      tx_amp = AMP;
+#endif
+    LOG_D(PHY,"SRS PROC; TX_MAX_POWER %d, Po_SRS %d, NB_RB_UL %d, NB_RB_SRS %d TX_AMPL %d\n",ue->tx_power_max_dBm,
+            Po_SRS,
+            ue->frame_parms.N_RB_UL,
+            nb_rb_srs,
+            tx_amp);
+
+    uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12;
+    uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((nr_tti_tx*nsymb)+(nsymb-1));
+    generate_srs(&ue->frame_parms,
+     &ue->soundingrs_ul_config_dedicated[eNB_id],
+     &ue->common_vars.txdataF[eNB_id][symbol_offset],
+     tx_amp,
+     nr_tti_tx);
+  }
+}
+
+int16_t get_pucch2_cqi(PHY_VARS_NR_UE *ue,int eNB_id,int *len) {
+
+  if ((ue->transmission_mode[eNB_id]<4)||
+      (ue->transmission_mode[eNB_id]==7)) { // Mode 1-0 feedback
+    // 4-bit CQI message
+          /*LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id],
+                          ue->measurements.wideband_cqi_avg[eNB_id],
+                          sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
+                                    ue->transmission_mode[eNB_id]));*/
+    *len=4;
+    return(sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
+        ue->transmission_mode[eNB_id]));
+  }
+  else { // Mode 1-1 feedback, later
+          //LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]);
+    *len=0;
+    // 2-antenna ports RI=1, 6 bits (2 PMI, 4 CQI)
+
+    // 2-antenna ports RI=2, 8 bits (1 PMI, 7 CQI/DIFF CQI)
+    return(0);
+  }
+}
+
+
+int16_t get_pucch2_ri(PHY_VARS_NR_UE *ue,int eNB_id) {
+
+  return(1);
+}
+
+
+void get_pucch_param(PHY_VARS_NR_UE    *ue,
+                     UE_nr_rxtx_proc_t *proc,
+                     uint8_t        *ack_payload,
+                     PUCCH_FMT_t    format,
+                     uint8_t        eNB_id,
+                     uint8_t        SR,
+                     uint8_t        cqi_report,
+                     uint16_t       *pucch_resource,
+                     uint8_t        *pucch_payload,
+                     uint16_t       *plength)
+{
+
+    switch (format) {
+    case pucch_format1:
+    {
+        pucch_resource[0] = ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex;
+        pucch_payload[0]  = 0; // payload is ignored in case of format1
+        pucch_payload[1]  = 0; // payload is ignored in case of format1
+    }
+    break;
+
+    case pucch_format1a:
+    case pucch_format1b:
+    {
+        pucch_resource[0] = nr_get_n1_pucch(ue,
+                                         proc,
+                                         ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack,
+                                         eNB_id,
+                                         ack_payload,
+                                         SR);
+        pucch_payload[0]  = ack_payload[0];
+        pucch_payload[1]  = ack_payload[1];
+        //pucch_payload[1]  = 1;
+    }
+    break;
+
+    case pucch_format2:
+    {
+        pucch_resource[0]    = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex;
+        if(cqi_report)
+        {
+            pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,(int*)plength);
+        }
+        else
+        {
+            *plength = 1;
+            pucch_payload[0] = get_pucch2_ri(ue,eNB_id);
+        }
+    }
+    break;
+
+    case pucch_format2a:
+    case pucch_format2b:
+        LOG_E(PHY,"NO Resource available for PUCCH 2a/2b \n");
+    break;
+
+    case pucch_format3:
+      fprintf(stderr, "PUCCH format 3 not handled\n");
+      abort();
+    }
+}
+
+#ifdef NR_PUCCH_SCHED
+void ue_nr_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
+}
+#endif
+
+void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
+
+
+  uint8_t  pucch_ack_payload[2];
+  uint16_t pucch_resource;
+  ANFBmode_t bundling_flag;
+  PUCCH_FMT_t format;
+
+  uint8_t  SR_payload;
+  uint8_t  pucch_payload[2];
+  uint16_t len;
+
+  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  int frame_tx=proc->frame_tx;
+  int nr_tti_tx=proc->nr_tti_tx;
+  int Mod_id = ue->Mod_id;
+  int CC_id = ue->CC_id;
+  int tx_amp;
+  int16_t Po_PUCCH;
+  uint8_t ack_status_cw0=0;
+  uint8_t ack_status_cw1=0;
+  uint8_t nb_cw=0;
+  uint8_t cqi_status=0;
+  uint8_t ri_status=0;
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN);
+
+  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
+
+  // 36.213 8.2
+  /*if ackNackSRS_SimultaneousTransmission ==  TRUE and in the cell specific SRS subframes UE shall transmit
+    ACK/NACK and SR using the shortened PUCCH format. This shortened PUCCH format shall be used in a cell
+    specific SRS nr_tti_rx even if the UE does not transmit SRS in that nr_tti_rx
+  */
+
+  int harq_pid = nr_subframe2harq_pid(&ue->frame_parms,
+                                   frame_tx,
+                                   nr_tti_tx);
+
+  if(ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag)
+  {
+      LOG_D(PHY,"PUSCH is programmed on this nr_tti_rx [pid %d] AbsSuframe %d.%d ==> Skip PUCCH transmission \n",harq_pid,frame_tx,nr_tti_tx);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);
+      return;
+  }
+
+  uint8_t isShortenPucch = (pSoundingrs_ul_config_dedicated->srsCellSubframe && frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission);
+
+  bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
+
+  if ((frame_parms->frame_type==FDD) ||
+      (bundling_flag==bundling)    ||
+      ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((nr_tti_tx!=2)||(nr_tti_tx!=7)))) {
+    format = pucch_format1a;
+    LOG_D(PHY,"[UE] PUCCH 1a\n");
+  } else {
+    format = pucch_format1b;
+    LOG_D(PHY,"[UE] PUCCH 1b\n");
+  }
+
+  // Part - I
+  // Collect feedback that should be transmitted at this nr_tti_rx
+  // - SR
+  // - ACK/NACK
+  // - CQI
+  // - RI
+
+  SR_payload = 0;
+  if (nr_is_SR_TXOp(ue,proc,eNB_id)==1)
+  {
+      if (ue->mac_enabled==1) {
+          SR_payload = mac_xface->ue_get_SR(Mod_id,
+                  CC_id,
+                  frame_tx,
+                  eNB_id,
+                  ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->crnti,
+                  nr_tti_tx); // nr_tti_rx used for meas gap
+      }
+      else {
+          SR_payload = 1;
+      }
+  }
+
+  ack_status_cw0 = nr_get_ack(&ue->frame_parms,
+                       ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack,
+                       nr_tti_tx,
+                       proc->nr_tti_rx,
+                       pucch_ack_payload,
+                       0);
+
+  ack_status_cw1 = nr_get_ack(&ue->frame_parms,
+                       ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][1]->harq_ack,
+                       nr_tti_tx,
+                       proc->nr_tti_rx,
+                       pucch_ack_payload,
+                       1);
+
+  nb_cw = ( (ack_status_cw0 != 0) ? 1:0) + ( (ack_status_cw1 != 0) ? 1:0);
+
+  cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
+      (is_cqi_TXOp(ue,proc,eNB_id)==1));
+
+  ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
+           (is_ri_TXOp(ue,proc,eNB_id)==1));
+
+  // Part - II
+  // if nothing to report ==> exit function
+  if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0) )
+  {
+      LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n",
+            frame_tx%1024, nr_tti_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status);
+      return;
+  }
+
+  // Part - III
+  // Decide which PUCCH format should be used if needed
+  format = get_pucch_format(frame_parms->frame_type,
+                            frame_parms->Ncp,
+                            SR_payload,
+                            nb_cw,
+                            cqi_status,
+                            ri_status,
+                            bundling_flag);
+  // Determine PUCCH resources and payload: mandatory for pucch encoding
+  get_pucch_param(ue,
+                  proc,
+                  pucch_ack_payload,
+                  format,
+                  eNB_id,
+                  SR_payload,
+                  cqi_status,
+                  &pucch_resource,
+                  (uint8_t *)&pucch_payload,
+                  &len);
+
+
+  LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d (%d %d) AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n",
+	frame_tx%1024, nr_tti_tx, SR_payload, nb_cw, ack_status_cw0, ack_status_cw1, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]);
+
+  // Part - IV
+  // Generate PUCCH signal
+  ue->generate_ul_signal[eNB_id] = 1;
+
+  switch (format) {
+  case pucch_format1:
+  case pucch_format1a:
+  case pucch_format1b:
+  {
+      if (ue->mac_enabled == 1) {
+          Po_PUCCH = nr_pucch_power_cntl(ue,proc,nr_tti_tx,eNB_id,format);
+      }
+      else {
+          Po_PUCCH = ue->tx_power_max_dBm;
+      }
+      ue->tx_power_dBm[nr_tti_tx] = Po_PUCCH;
+      ue->tx_total_RE[nr_tti_tx] = 12;
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+      tx_amp = get_tx_amp(Po_PUCCH,
+              ue->tx_power_max_dBm,
+              ue->frame_parms.N_RB_UL,
+              1);
+#else
+      tx_amp = AMP;
+#endif
+#if T_TRACER
+      T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx),T_INT(ue->tx_power_dBm[nr_tti_tx]),
+              T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
+#endif
+
+#ifdef UE_DEBUG_TRACE
+      if(format == pucch_format1)
+      {
+          LOG_I(PHY,"[UE  %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
+                  Mod_id,
+                  ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->rnti,
+                  frame_tx%1024, nr_tti_tx,
+                  frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
+                  isShortenPucch,
+                  ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
+                  Po_PUCCH);
+      }
+      else
+      {
+          if (SR_payload>0) {
+              LOG_I(PHY,"[UE  %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n",
+                      Mod_id,
+                      ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->rnti,
+                      frame_tx % 1024, nr_tti_tx,
+                      (format == pucch_format1a? "1a": (
+                              format == pucch_format1b? "1b" : "??")),
+                              pucch_ack_payload[0],pucch_ack_payload[1],
+                              frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
+                              isShortenPucch,
+                              pucch_resource,
+                              Po_PUCCH,
+                              tx_amp);
+          } else {
+              LOG_I(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
+                      Mod_id,
+                      ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->rnti,
+                      frame_tx%1024, nr_tti_tx,ue->rx_offset_diff,
+                      (format == pucch_format1a? "1a": (
+                              format == pucch_format1b? "1b" : "??")),
+                              frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
+                              isShortenPucch,
+                              pucch_resource,pucch_payload[0],pucch_payload[1],SR_payload,
+                              Po_PUCCH,
+                              tx_amp);
+          }
+      }
+#endif
+
+#if T_TRACER
+      if(pucch_payload[0])
+      {
+          T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->rnti),
+                  T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->current_harq_pid));
+      }
+      else
+      {
+          T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->rnti),
+                  T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->current_harq_pid));
+      }
+#endif
+
+      if (abstraction_flag == 0) {
+
+          generate_pucch1x(ue->common_vars.txdataF,
+                  &ue->frame_parms,
+                  ue->ncs_cell,
+                  format,
+                  &ue->pucch_config_dedicated[eNB_id],
+                  pucch_resource,
+                  isShortenPucch,  // shortened format
+                  pucch_payload,
+                  tx_amp,
+                  nr_tti_tx);
+
+      } else {
+#ifdef PHY_ABSTRACTION
+          LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload);
+          generate_pucch_emul(ue,
+                  proc,
+                  format,
+                  ue->frame_parms.pucch_config_common.nCS_AN,
+                  pucch_payload,
+                  SR_payload);
+#endif
+      }
+  }
+  break;
+
+
+  case pucch_format2:
+  {
+      if (ue->mac_enabled == 1) {
+          Po_PUCCH = nr_pucch_power_cntl(ue,proc,nr_tti_tx,eNB_id,format);
+      }
+      else {
+          Po_PUCCH = ue->tx_power_max_dBm;
+      }
+      ue->tx_power_dBm[nr_tti_tx] = Po_PUCCH;
+      ue->tx_total_RE[nr_tti_tx] = 12;
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+      tx_amp =  get_tx_amp(Po_PUCCH,
+              ue->tx_power_max_dBm,
+              ue->frame_parms.N_RB_UL,
+              1);
+#else
+      tx_amp = AMP;
+#endif
+#if T_TRACER
+      T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx),T_INT(ue->tx_power_dBm[nr_tti_tx]),
+              T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
+#endif
+#ifdef UE_DEBUG_TRACE
+      LOG_I(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n",
+              Mod_id,
+              ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->rnti,
+              frame_tx%1024, nr_tti_tx,
+              Po_PUCCH,
+              isShortenPucch,
+              tx_amp);
+#endif
+      generate_pucch2x(ue->common_vars.txdataF,
+              &ue->frame_parms,
+              ue->ncs_cell,
+              format,
+              &ue->pucch_config_dedicated[eNB_id],
+              pucch_resource,
+              pucch_payload,
+              len,          // A
+              0,            // B2 not needed
+              tx_amp,
+              nr_tti_tx,
+              ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][eNB_id]->crnti);
+  }
+  break;
+
+  case pucch_format2a:
+      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n",
+              Mod_id,
+              ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->rnti,
+              frame_tx%1024, nr_tti_tx);
+      break;
+  case pucch_format2b:
+      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n",
+              Mod_id,
+              ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->rnti,
+              frame_tx%1024, nr_tti_tx);
+      break;
+  default:
+      break;
+  }
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);
+
+}
+
+void phy_procedures_UE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type) {
+
+
+  NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
+  //int32_t ulsch_start=0;
+  int nr_tti_tx = proc->nr_tti_tx;
+  int frame_tx = proc->frame_tx;
+  unsigned int aa;
+  uint8_t isSubframeSRS;
+
+  uint8_t next1_thread_id = ue->current_thread_id[proc->nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[proc->nr_tti_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
+
+  LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, nr_tti_tx);
+#if T_TRACER
+  T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx));
+#endif
+
+  ue->generate_ul_signal[eNB_id] = 0;
+#if UE_TIMING_TRACE
+  start_meas(&ue->phy_proc_tx);
+#endif
+
+#ifdef EMOS
+  //phy_procedures_emos_UE_TX(next_slot);
+#endif
+
+  ue->tx_power_dBm[nr_tti_tx]=-127;
+
+  if (abstraction_flag==0) {
+    for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+      memset(&ue->common_vars.txdataF[aa][nr_tti_tx*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti],
+       0,
+       frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t));
+    }
+  }
+
+  if (ue->UE_mode[eNB_id] != PRACH) {
+    // check cell srs nr_tti_rx and ue srs nr_tti_rx. This has an impact on pusch encoding
+    isSubframeSRS = nr_is_srs_occasion_common(&ue->frame_parms,proc->frame_tx,proc->nr_tti_tx);
+
+    ue_compute_srs_occasion(ue,proc,eNB_id,isSubframeSRS);
+
+    ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
+
+  }
+
+  if (ue->UE_mode[eNB_id] == PUSCH) {
+      // check if we need to use PUCCH 1a/1b
+      ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
+      // check if we need to use SRS
+      ue_srs_procedures(ue,proc,eNB_id,abstraction_flag);
+  } // UE_mode==PUSCH
+
+
+#ifdef CBA
+
+  if ((ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag >= 1) &&
+      (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == CBA_ACTIVE)) {
+    ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag=0; //-=1
+    //  ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
+    first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
+    nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
+    //cba_mcs=ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs;
+    input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
+    access_mode=CBA_ACCESS;
+
+    LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: CBA num dci %d\n",
+    Mod_id,frame_tx,nr_tti_tx,
+    ue->ulsch[eNB_id]->num_cba_dci[nr_tti_tx]);
+
+    /*mac_xface->ue_get_sdu(Mod_id,
+        CC_id,
+        frame_tx,
+        proc->subframe_tx,
+        nr_tti_tx%(ue->frame_parms.ttis_per_subframe),
+        eNB_id,
+        ulsch_input_buffer,
+        input_buffer_length,
+        &access_mode);*/
+
+    ue->ulsch[eNB_id]->num_cba_dci[nr_tti_tx]=0;
+
+    if (access_mode > UNKNOWN_ACCESS) {
+
+      if (abstraction_flag==0) {
+        if (ulsch_encoding(ulsch_input_buffer,
+                           ue,
+                           harq_pid,
+                           eNB_id,
+                           proc->nr_tti_rx,
+                           ue->transmission_mode[eNB_id],0,
+                           0)!=0) {  //  Nbundled, to be updated!!!!
+          LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
+          return;
+        }
+      }
+
+#ifdef PHY_ABSTRACTION
+      else {
+        ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->nr_tti_rx,harq_pid,0);
+      }
+
+#endif
+    } else {
+      ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
+      //reset_cba_uci(ue->ulsch[eNB_id]->o);
+      LOG_N(PHY,"[UE %d] Frame %d, nr_tti_rx %d: CBA transmission cancelled or postponed\n",
+      Mod_id, frame_tx,nr_tti_tx);
+    }
+  }
+
+#endif // end CBA
+
+
+  if (abstraction_flag == 0) {
+    ulsch_common_procedures(ue,proc, (ue->generate_ul_signal[eNB_id] == 0));
+  } // mode != PRACH
+
+
+  if ((ue->UE_mode[eNB_id] == PRACH) &&
+      (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
+
+    // check if we have PRACH opportunity
+
+    if (is_prach_subframe(&ue->frame_parms,frame_tx,nr_tti_tx)) {
+
+      ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+    }
+  } // mode is PRACH
+  else {
+    ue->generate_prach=0;
+  }
+
+  // reset DL ACK/NACK status
+  uint8_t N_bundled = 0;
+  if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0] != NULL)
+  {
+    nr_reset_ack(&ue->frame_parms,
+               ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack,
+               nr_tti_tx,
+               proc->nr_tti_rx,
+               ue->ulsch[eNB_id]->o_ACK,
+               &N_bundled,
+               0);
+    nr_reset_ack(&ue->frame_parms,
+               ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack,
+               nr_tti_tx,
+               proc->nr_tti_rx,
+               ue->ulsch[eNB_id]->o_ACK,
+               &N_bundled,
+               0);
+    nr_reset_ack(&ue->frame_parms,
+               ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack,
+               nr_tti_tx,
+               proc->nr_tti_rx,
+               ue->ulsch[eNB_id]->o_ACK,
+               &N_bundled,
+               0);
+  }
+
+  if (ue->dlsch_SI[eNB_id] != NULL)
+    nr_reset_ack(&ue->frame_parms,
+             ue->dlsch_SI[eNB_id]->harq_ack,
+             nr_tti_tx,
+             proc->nr_tti_rx,
+             ue->ulsch[eNB_id]->o_ACK,
+             &N_bundled,
+             0);
+
+
+  LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, nr_tti_tx);
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+  stop_meas(&ue->phy_proc_tx);
+#endif
+}
+
+void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type)
+{
+  int aa;//i,aa;
+  NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
+
+  if (abstraction_flag==0) {
+
+    for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+#if defined(EXMIMO) //this is the EXPRESS MIMO case
+      int i;
+      // set the whole tx buffer to RX
+      for (i=0; i<LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe; i++)
+  ue->common_vars.txdata[aa][i] = 0x00010001;
+
+#else //this is the normal case
+      memset(&ue->common_vars.txdata[aa][0],0,
+       (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe)*sizeof(int32_t));
+#endif //else EXMIMO
+
+    }
+  }
+}
+
+void ue_measurement_procedures(
+    uint16_t l,    // symbol index of each slot [0..6]
+    PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc, uint8_t eNB_id,
+    uint16_t slot, // slot index of each radio frame [0..19]
+    uint8_t abstraction_flag,runmode_t mode)
+{
+
+  //LOG_I(PHY,"ue_measurement_procedures l %d Ncp %d\n",l,ue->frame_parms.Ncp);
+
+  NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
+
+  int nr_tti_rx = proc->nr_tti_rx;
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);
+
+  if (l==0) {
+    // UE measurements on symbol 0
+    if (abstraction_flag==0) {
+      LOG_D(PHY,"Calling measurements nr_tti_rx %d, rxdata %p\n",nr_tti_rx,ue->common_vars.rxdata);
+
+      lte_ue_measurements(ue,
+        (nr_tti_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME),
+        (nr_tti_rx == 1) ? 1 : 0,
+        0,
+        0,
+        nr_tti_rx);
+    } else {
+      lte_ue_measurements(ue,
+        0,
+        0,
+        1,
+        0,
+      nr_tti_rx);
+    }
+#if T_TRACER
+    if(slot == 0)
+      T(T_UE_PHY_MEAS, T_INT(eNB_id),  T_INT(ue->Mod_id), T_INT(proc->frame_rx%1024), T_INT(proc->nr_tti_rx),
+                             T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)),
+                             T_INT((int)ue->measurements.rx_rssi_dBm[0]),
+                             T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
+                             T_INT((int)ue->measurements.rx_power_avg_dB[0]),
+                             T_INT((int)ue->measurements.n0_power_avg_dB),
+                             T_INT((int)ue->measurements.wideband_cqi_avg[0]),
+                             T_INT((int)ue->common_vars.freq_offset));
+#endif
+  }
+
+  if (l==(6-ue->frame_parms.Ncp)) {
+
+    // make sure we have signal from PSS/SSS for N0 measurement
+         // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n");
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN);
+    ue_rrc_measurements(ue,
+      slot,
+      abstraction_flag);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT);
+
+    if (abstraction_flag==1)
+      ue->sinr_eff =  sinr_eff_cqi_calc(ue, 0, nr_tti_rx);
+
+  }
+
+  // accumulate and filter timing offset estimation every nr_tti_rx (instead of every frame)
+  if (( (slot%2) == 0) && (l==(4-frame_parms->Ncp))) {
+
+    // AGC
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
+
+#ifndef OAI_USRP
+#ifndef OAI_BLADERF
+#ifndef OAI_LMSSDR
+#ifndef OAI_ADRV9371_ZC706
+    phy_adjust_gain (ue,dB_fixed(ue->measurements.rssi),0);
+#endif
+#endif
+#endif
+#endif
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
+
+    eNB_id = 0;
+
+    if (abstraction_flag == 0) {
+      if (ue->no_timing_correction==0)
+  lte_adjust_synch(&ue->frame_parms,
+       ue,
+       eNB_id,
+       nr_tti_rx,
+       0,
+       16384);
+    }
+
+  }
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
+}
+
+#ifdef EMOS
+void phy_procedures_emos_UE_RX(PHY_VARS_NR_UE *ue,uint8_t last_slot,uint8_t eNB_id)
+{
+
+  uint8_t i,j;
+  //uint16_t last_slot_emos;
+  uint32_t bytes;
+  int Mod_id = ue->Mod_id;
+
+  /*
+    if (last_slot<2)
+    last_slot_emos = last_slot;
+    else if (last_slot>9)
+    last_slot_emos = last_slot - 8;
+    else {
+    LOG_E(PHY,"emos rx last_slot_emos %d, last_slot %d\n", last_slot_emos,last_slot);
+    //mac_xface->macphy_exit("should never happen");
+    }
+  */
+
+#ifdef EMOS_CHANNEL
+
+  if ((last_slot==10) || (last_slot==11)) {
+    for (i=0; i<ue->frame_parms.nb_antennas_rx; i++)
+      for (j=0; j<ue->frame_parms.nb_antennas_tx; j++) {
+  // first OFDM symbol with pilots
+  memcpy(&emos_dump_UE.channel[i][j][(last_slot%2)*2*ue->frame_parms.ofdm_symbol_size],
+         &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][0],
+         ue->frame_parms.ofdm_symbol_size*sizeof(int));
+  // second OFDM symbol with pilots
+  memcpy(&emos_dump_UE.channel[i][j][((last_slot%2)*2+1)*ue->frame_parms.ofdm_symbol_size],
+         &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][(ue->frame_parms.Ncp == 0 ? 4 : 3)*ue->frame_parms.ofdm_symbol_size],
+         ue->frame_parms.ofdm_symbol_size*sizeof(int));
+      }
+  }
+
+#endif
+
+  if (last_slot==0) {
+    emos_dump_UE.timestamp = rt_get_time_ns();
+    emos_dump_UE.frame_rx = proc->frame_rx;
+    emos_dump_UE.UE_mode = ue->UE_mode[eNB_id];
+    emos_dump_UE.mimo_mode = ue->transmission_mode[eNB_id];
+    emos_dump_UE.freq_offset = ue->common_vars.freq_offset;
+    emos_dump_UE.timing_advance = ue->timing_advance;
+    emos_dump_UE.timing_offset  = ue->rx_offset;
+    emos_dump_UE.rx_total_gain_dB = ue->rx_total_gain_dB;
+    emos_dump_UE.eNb_id = eNB_id;
+    memcpy(&emos_dump_UE.PHY_measurements,&measurements,sizeof(PHY_MEASUREMENTS));
+  }
+
+  if (last_slot==1) {
+    emos_dump_UE.pbch_errors = ue->pbch_vars[eNB_id]->pdu_errors;
+    emos_dump_UE.pbch_errors_last = ue->pbch_vars[eNB_id]->pdu_errors_last;
+    emos_dump_UE.pbch_errors_conseq = ue->pbch_vars[eNB_id]->pdu_errors_conseq;
+    emos_dump_UE.pbch_fer = ue->pbch_vars[eNB_id]->pdu_fer;
+  }
+
+  if (last_slot==19) {
+    emos_dump_UE.dlsch_errors = ue->dlsch_errors[eNB_id];
+    emos_dump_UE.dlsch_errors_last = ue->dlsch_errors_last[eNB_id];
+    emos_dump_UE.dlsch_received = ue->dlsch_received[eNB_id];
+    emos_dump_UE.dlsch_received_last = ue->dlsch_received_last[eNB_id];
+    emos_dump_UE.dlsch_fer = ue->dlsch_fer[eNB_id];
+    emos_dump_UE.dlsch_cntl_errors = ue->dlsch_SI_errors[eNB_id];
+    emos_dump_UE.dlsch_ra_errors = ue->dlsch_ra_errors[eNB_id];
+    emos_dump_UE.total_TBS = ue->total_TBS[eNB_id];
+    emos_dump_UE.total_TBS_last = ue->total_TBS_last[eNB_id];
+    emos_dump_UE.bitrate = ue->bitrate[eNB_id];
+    emos_dump_UE.total_received_bits = ue->total_received_bits[eNB_id];
+    emos_dump_UE.pmi_saved = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->pmi_alloc;
+    emos_dump_UE.mcs = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid]->mcs;
+    emos_dump_UE.use_ia_receiver = openair_daq_vars.use_ia_receiver;
+
+    bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_UE, sizeof(fifo_dump_emos_UE));
+
+    if (bytes!=sizeof(fifo_dump_emos_UE)) {
+      LOG_W(PHY,"[UE  %d] frame %d, slot %d, Problem writing EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot);
+    } else {
+      if (proc->frame_rx%100==0) {
+  LOG_I(PHY,"[UE  %d] frame %d, slot %d, Writing %d bytes EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot, bytes);
+      }
+    }
+  }
+
+}
+#endif
+
+
+void restart_phy(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc, uint8_t eNB_id,uint8_t abstraction_flag)
+{
+
+  //  uint8_t last_slot;
+  uint8_t i;
+  LOG_I(PHY,"[UE  %d] frame %d, slot %d, restarting PHY!\n",ue->Mod_id,proc->frame_rx,proc->nr_tti_rx);
+  //mac_xface->macphy_exit("restart_phy called");
+  //   first_run = 1;
+
+  if (abstraction_flag ==0 ) {
+    ue->UE_mode[eNB_id] = NOT_SYNCHED;
+  } else {
+    ue->UE_mode[eNB_id] = PRACH;
+    ue->prach_resources[eNB_id]=NULL;
+  }
+
+  proc->frame_rx = -1;
+  proc->frame_tx = -1;
+  //  ue->synch_wait_cnt=0;
+  //  ue->sched_cnt=-1;
+
+  ue->pbch_vars[eNB_id]->pdu_errors_conseq=0;
+  ue->pbch_vars[eNB_id]->pdu_errors=0;
+
+  ue->pdcch_vars[0][eNB_id]->dci_errors = 0;
+  ue->pdcch_vars[0][eNB_id]->dci_missed = 0;
+  ue->pdcch_vars[0][eNB_id]->dci_false  = 0;
+  ue->pdcch_vars[0][eNB_id]->dci_received = 0;
+
+  ue->pdcch_vars[1][eNB_id]->dci_errors = 0;
+  ue->pdcch_vars[1][eNB_id]->dci_missed = 0;
+  ue->pdcch_vars[1][eNB_id]->dci_false  = 0;
+  ue->pdcch_vars[1][eNB_id]->dci_received = 0;
+
+  ue->dlsch_errors[eNB_id] = 0;
+  ue->dlsch_errors_last[eNB_id] = 0;
+  ue->dlsch_received[eNB_id] = 0;
+  ue->dlsch_received_last[eNB_id] = 0;
+  ue->dlsch_fer[eNB_id] = 0;
+  ue->dlsch_SI_received[eNB_id] = 0;
+  ue->dlsch_ra_received[eNB_id] = 0;
+  ue->dlsch_p_received[eNB_id] = 0;
+  ue->dlsch_SI_errors[eNB_id] = 0;
+  ue->dlsch_ra_errors[eNB_id] = 0;
+  ue->dlsch_p_errors[eNB_id] = 0;
+
+  ue->dlsch_mch_received[eNB_id] = 0;
+
+  for (i=0; i < MAX_MBSFN_AREA ; i ++) {
+    ue->dlsch_mch_received_sf[i][eNB_id] = 0;
+    ue->dlsch_mcch_received[i][eNB_id] = 0;
+    ue->dlsch_mtch_received[i][eNB_id] = 0;
+    ue->dlsch_mcch_errors[i][eNB_id] = 0;
+    ue->dlsch_mtch_errors[i][eNB_id] = 0;
+    ue->dlsch_mcch_trials[i][eNB_id] = 0;
+    ue->dlsch_mtch_trials[i][eNB_id] = 0;
+  }
+
+  //ue->total_TBS[eNB_id] = 0;
+  //ue->total_TBS_last[eNB_id] = 0;
+  //ue->bitrate[eNB_id] = 0;
+  //ue->total_received_bits[eNB_id] = 0;
+}
+
+
+void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc, uint8_t abstraction_flag)
+{
+
+  //  int i;
+  int pbch_tx_ant=0;
+  uint8_t pbch_phase;
+  uint16_t frame_tx;
+  static uint8_t first_run = 1;
+  uint8_t pbch_trials = 0;
+
+  DevAssert(ue);
+
+  int frame_rx = proc->frame_rx;
+  int nr_tti_rx = proc->nr_tti_rx;
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
+
+  pbch_phase=(frame_rx%4);
+
+  if (pbch_phase>=4)
+    pbch_phase=0;
+
+  for (pbch_trials=0; pbch_trials<4; pbch_trials++) {
+    //for (pbch_phase=0;pbch_phase<4;pbch_phase++) {
+    //LOG_I(PHY,"[UE  %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id);
+    if (abstraction_flag == 0) {
+      pbch_tx_ant = rx_pbch(ue, proc,
+          ue->pbch_vars[eNB_id],
+          &ue->frame_parms,
+          eNB_id,
+          ue->frame_parms.mode1_flag==1?SISO:ALAMOUTI,
+          ue->high_speed_flag,
+          pbch_phase);
+
+
+
+    }
+
+#ifdef PHY_ABSTRACTION
+    else {
+      pbch_tx_ant = rx_pbch_emul(ue,
+         eNB_id,
+         pbch_phase);
+    }
+
+#endif
+
+    if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) {
+      break;
+    }
+
+    pbch_phase++;
+
+    if (pbch_phase>=4)
+      pbch_phase=0;
+  }
+
+
+
+  if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) {
+
+    if (opt_enabled) {
+      static uint8_t dummy[3];
+      dummy[0] = ue->pbch_vars[eNB_id]->decoded_output[2];
+      dummy[1] = ue->pbch_vars[eNB_id]->decoded_output[1];
+      dummy[2] = ue->pbch_vars[eNB_id]->decoded_output[0];
+      trace_pdu(1, dummy, 3, ue->Mod_id, 0, 0,
+          frame_rx, nr_tti_rx, 0, 0);
+      LOG_D(OPT,"[UE %d][PBCH] Frame %d trace pdu for PBCH\n",
+          ue->Mod_id, nr_tti_rx);
+    }
+
+    if (pbch_tx_ant>2) {
+      LOG_W(PHY,"[openair][SCHED][SYNCH] PBCH decoding: pbch_tx_ant>2 not supported\n");
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
+      return;
+    }
+
+
+    ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0;
+    frame_tx = (((int)(ue->pbch_vars[eNB_id]->decoded_output[2]&0x03))<<8);
+    frame_tx += ((int)(ue->pbch_vars[eNB_id]->decoded_output[1]&0xfc));
+    frame_tx += pbch_phase;
+
+    //if (ue->mac_enabled==1) {
+    //mac_xface->dl_phy_sync_success(ue->Mod_id,frame_rx,eNB_id,first_run);
+      //}
+
+#ifdef EMOS
+    //emos_dump_UE.frame_tx = frame_tx;
+    //emos_dump_UE.mimo_mode = ue->pbch_vars[eNB_id]->decoded_output[1];
+#endif
+
+    if (first_run) {
+      first_run = 0;
+
+      proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
+      proc->frame_tx = proc->frame_rx;
+      for(int th_id=0; th_id<RX_NB_TH; th_id++)
+      {
+        ue->proc.proc_rxtx[th_id].frame_rx = proc->frame_rx;
+        ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_tx;
+
+        printf("[UE %d] frame %d, nr_tti_rx %d: Adjusting frame counter (PBCH ant_tx=%d, frame_tx=%d, phase %d, rx_offset %d) => new frame %d\n",
+ 	    ue->Mod_id,
+ 	    ue->proc.proc_rxtx[th_id].frame_rx,
+ 	    nr_tti_rx,
+ 	    pbch_tx_ant,
+ 	    frame_tx,
+ 	    pbch_phase,
+ 	    ue->rx_offset,
+ 	    proc->frame_rx);
+      }
+
+
+      frame_rx = proc->frame_rx;
+
+    } else if (((frame_tx & 0x03FF) != (proc->frame_rx & 0x03FF))) {
+      //(pbch_tx_ant != ue->frame_parms.nb_antennas_tx)) {
+      LOG_D(PHY,"[UE %d] frame %d, nr_tti_rx %d: Re-adjusting frame counter (PBCH ant_tx=%d, frame_rx=%d, frame%%1024=%d, phase %d).\n",
+      ue->Mod_id,
+      proc->frame_rx,
+      nr_tti_rx,
+      pbch_tx_ant,
+      frame_tx,
+      frame_rx & 0x03FF,
+      pbch_phase);
+
+      proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
+      proc->frame_tx = proc->frame_rx;
+      frame_rx = proc->frame_rx;
+      
+      for(int th_id=0; th_id<RX_NB_TH; th_id++)
+      {
+        ue->proc.proc_rxtx[th_id].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
+        ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_rx;
+      }
+
+    }
+
+#ifdef DEBUG_PHY_PROC
+    LOG_D(PHY,"[UE %d] frame %d, nr_tti_rx %d, Received PBCH (MIB): mode1_flag %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
+    ue->Mod_id,
+    frame_rx,
+    nr_tti_rx,
+    ue->frame_parms.mode1_flag,
+    pbch_tx_ant,
+    frame_tx,
+    ue->frame_parms.N_RB_DL,
+    ue->frame_parms.phich_config_common.phich_duration,
+    ue->frame_parms.phich_config_common.phich_resource);
+#endif
+
+  } else {
+    /*
+    LOG_E(PHY,"[UE %d] frame %d, nr_tti_rx %d, Error decoding PBCH!\n",
+    ue->Mod_id,frame_rx, nr_tti_rx);
+
+    LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset);
+
+
+    write_output("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_subframe,1,1);
+
+    write_output("H00.m","h00",&(ue->common_vars.dl_ch_estimates[0][0][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
+    write_output("H10.m","h10",&(ue->common_vars.dl_ch_estimates[0][2][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
+
+    write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1);
+    write_output("PBCH_rxF0_ext.m","pbch0_ext",ue->pbch_vars[0]->rxdataF_ext[0],12*4*6,1,1);
+    write_output("PBCH_rxF0_comp.m","pbch0_comp",ue->pbch_vars[0]->rxdataF_comp[0],12*4*6,1,1);
+    write_output("PBCH_rxF_llr.m","pbch_llr",ue->pbch_vars[0]->llr,(ue->frame_parms.Ncp==0) ? 1920 : 1728,1,4);
+    exit(-1);
+    */
+
+    ue->pbch_vars[eNB_id]->pdu_errors_conseq++;
+    ue->pbch_vars[eNB_id]->pdu_errors++;
+    if (ue->mac_enabled == 1) {
+      //mac_xface->out_of_sync_ind(ue->Mod_id,frame_rx,eNB_id);
+    }
+    else{
+      if (ue->pbch_vars[eNB_id]->pdu_errors_conseq>=100) {
+  LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
+  //mac_xface->macphy_exit("More that 100 consecutive PBCH errors!");
+      }
+    }
+  }
+
+  if (frame_rx % 100 == 0) {
+    ue->pbch_vars[eNB_id]->pdu_fer = ue->pbch_vars[eNB_id]->pdu_errors - ue->pbch_vars[eNB_id]->pdu_errors_last;
+    ue->pbch_vars[eNB_id]->pdu_errors_last = ue->pbch_vars[eNB_id]->pdu_errors;
+  }
+
+#ifdef DEBUG_PHY_PROC
+  LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
+  ue->Mod_id,frame_rx, nr_tti_rx,
+  ue->pbch_vars[eNB_id]->pdu_errors,
+  ue->pbch_vars[eNB_id]->pdu_errors_conseq);
+#endif
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
+}
+
+
+#endif //(0)
+
+#ifdef NR_PDCCH_SCHED
+int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t abstraction_flag)
+{
+
+  //  unsigned int dci_cnt=0, i;  //removed for nr_ue_pdcch_procedures and added in the loop for nb_coreset_active
+  #ifdef NR_PDCCH_SCHED_DEBUG
+    printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_ue_pdcch_procedures() \n");
+  #endif
+
+  int frame_rx = proc->frame_rx;
+  int nr_tti_rx = proc->nr_tti_rx;
+  NR_DCI_ALLOC_t dci_alloc_rx[8];
+  uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
+
+  uint16_t tc_rnti = 1; // FIXME
+  uint16_t int_rnti = 1; // FIXME
+  uint16_t sfi_rnti = 1; // FIXME
+  uint16_t tpc_pusch_rnti =1; // FIXME
+  uint16_t tpc_pucch_rnti = 1; // FIXME
+  uint16_t tpc_srs_rnti = 1; // FIXME
+  // s in TS 38.212 Subclause 10.1, for each active BWP the UE can deal with 10 different search spaces
+  // FIXME ! this value has to be obtained by higher-layer parameters
+  int nb_searchspace_total = NR_NBR_SEARCHSPACE_ACT_BWP - 1;
+  // p in TS 38.212 Subclause 10.1, for each active BWP the UE can deal with 3 different CORESETs (including coresetId 0 for common search space)
+  // FIXME ! this value will be obtained from IE PDCCH-Config or PDCCH-ConfigCommon (SIB)
+  int nb_coreset_total = NR_NBR_CORESET_ACT_BWP - 1;
+  int nb_searchspace_active=0;
+  NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]];
+  NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id];
+
+  // First we have to identify each searchSpace active at a time and do PDCCH monitoring corresponding to current searchSpace
+  // Up to 10 searchSpaces can be configured to UE (s<=10)
+  for (nb_searchspace_active=0; nb_searchspace_active<nb_searchspace_total; nb_searchspace_active++){
+    int nb_coreset_active=0;
+    // Verify that monitoring is required at the slot nr_tti_rx. We will run pdcch procedure only if do_pdcch_monitoring_current_slot=1
+    int do_pdcch_monitoring_current_slot=0;
+    // For Type0-PDCCH searchspace, we need to calculate the monitoring slot from Tables 13-1 .. 13-15 in TS 38.213 Subsection 13
+    NR_UE_SLOT_PERIOD_OFFSET_t sl_period_offset_mon = pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset;
+    if (sl_period_offset_mon == sl1) {
+      do_pdcch_monitoring_current_slot=1; // PDCCH monitoring in every slot
+    } else if (nr_tti_rx%(int)sl_period_offset_mon == pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset_offset) {
+      do_pdcch_monitoring_current_slot=1; // PDCCH monitoring in every monitoringSlotPeriodicityAndOffset slot with offset
+    }
+    /*
+     * FIXME
+     * For PDCCH monitoring when overlap with SS/PBCH according to 38.213 v15.1.0 Section 10
+     * To be implemented LATER !!!
+     */
+    #ifdef NR_PDCCH_SCHED_DEBUG
+      printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> nb_searchspace_active=%d do_pdcch_monitoring_current_slot=%d\n",
+              nb_searchspace_active,
+              do_pdcch_monitoring_current_slot);
+    #endif
+
+    if (do_pdcch_monitoring_current_slot) {
+      // the searchSpace indicates that we need to monitor PDCCH in current nr_tti_rx
+      // get the parameters describing the current SEARCHSPACE
+      int searchSpace_id                              = pdcch_vars2->searchSpace[nb_searchspace_active].searchSpaceId;
+      // the CORESET id applicable to the current SearchSpace
+      int searchSpace_coreset_id                      = pdcch_vars2->searchSpace[nb_searchspace_active].controlResourceSetId;
+      // FIXME this variable is a bit string (14 bits) identifying every OFDM symbol in a slot.
+      // at the moment we will not take into consideration this variable and we will consider that the OFDM symbol offset is always the first OFDM in a symbol
+      uint16_t symbol_within_slot_mon                 = pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSymbolWithinSlot;
+      // get the remaining parameters describing the current SEARCHSPACE:     // FIXME! To be defined where we get this information from
+      NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L1         = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel1;
+      NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L2         = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel2;
+      NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L4         = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel4;
+      NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L8         = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel8;
+      NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L16        = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel16;
+                                                                                                  // FIXME! A table of five enum elements
+      // searchSpaceType indicates whether this is a common search space or a UE-specific search space
+      int searchSpaceType                             = pdcch_vars2->searchSpace[nb_searchspace_active].searchSpaceType.type;
+
+      while ((searchSpace_coreset_id != pdcch_vars2->coreset[nb_coreset_active].controlResourceSetId) && (nb_coreset_active<nb_coreset_total)) {
+        // we need to identify the CORESET associated to the active searchSpace
+        nb_coreset_active++;
+      }
+      if (nb_coreset_active >= nb_coreset_total) return 0; // the coreset_id could not be found. There is a problem
+
+      unsigned int dci_cnt=0, i;
+
+      // get the parameters describing the current CORESET
+      int coreset_duration                                      = pdcch_vars2->coreset[nb_coreset_active].duration;
+      uint64_t coreset_freq_dom                                 = pdcch_vars2->coreset[nb_coreset_active].frequencyDomainResources;
+      int coreset_shift_index                                   = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.shiftIndex;
+      NR_UE_CORESET_REG_bundlesize_t coreset_bundlesize         = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.reg_bundlesize;
+      NR_UE_CORESET_interleaversize_t coreset_interleaversize   = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.interleaversize;
+      NR_UE_CORESET_precoder_granularity_t precoder_granularity = pdcch_vars2->coreset[nb_coreset_active].precoderGranularity;
+      int tci_statesPDCCH                                       = pdcch_vars2->coreset[nb_coreset_active].tciStatesPDCCH;
+      int tci_present                                           = pdcch_vars2->coreset[nb_coreset_active].tciPresentInDCI;
+      uint16_t pdcch_DMRS_scrambling_id                         = pdcch_vars2->coreset[nb_coreset_active].pdcchDMRSScramblingID;
+
+      // this table contains 48 (NBR_NR_DCI_FIELDS) elements for each dci field described in TS 38.212. Each element represents the size in bits for each dci field
+      uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS] = {0};
+      // this is the UL bandwidth part. FIXME! To be defined where this value comes from
+      uint16_t n_RB_ULBWP = 100;
+      // this is the DL bandwidth part. FIXME! To be defined where this value comes from
+      uint16_t n_RB_DLBWP = 100;
+
+      // A set of PDCCH candidates for a UE to monitor is defined in terms of PDCCH search spaces.
+      // Searchspace types:
+      // Type0-PDCCH  common search space for a DCI format with CRC scrambled by a SI-RNTI
+                   // number of consecutive resource blocks and a number of consecutive symbols for
+                   // the control resource set of the Type0-PDCCH common search space from
+                   // the four most significant bits of RMSI-PDCCH-Config as described in Tables 13-1 through 13-10
+                   // and determines PDCCH monitoring occasions
+                   // from the four least significant bits of RMSI-PDCCH-Config,
+                   // included in MasterInformationBlock, as described in Tables 13-11 through 13-15
+      // Type0A-PDCCH common search space for a DCI format with CRC scrambled by a SI-RNTI
+      // Type1-PDCCH  common search space for a DCI format with CRC scrambled by a RA-RNTI, or a TC-RNTI, or a C-RNTI
+      // Type2-PDCCH  common search space for a DCI format with CRC scrambled by a P-RNTI
+      // Type3-PDCCH  common search space for a DCI format with CRC scrambled by INT-RNTI, or SFI-RNTI,
+                   // or TPC-PUSCH-RNTI, or TPC-PUCCH-RNTI, or TPC-SRS-RNTI, or C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
+
+
+#ifdef PHY_ABSTRACTION
+  int CC_id;
+  int UE_id;
+  uint8_t harq_pid;
+#endif
+
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN);
+#if UE_TIMING_TRACE
+  start_meas(&ue->dlsch_rx_pdcch_stats);
+#endif
+
+      //  if (nr_tti_rx != 5)
+      //    return 0;
+      if (abstraction_flag == 0)  {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
+/*      rx_pdcch(ue,
+              proc->frame_rx,
+              nr_tti_rx,
+              eNB_id,
+              (ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
+              ue->high_speed_flag,
+              ue->is_secondary_ue);*/ //removed for nr_ue_pdcch_procedures
+        #ifdef NR_PDCCH_SCHED_DEBUG
+          printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_rx_pdcch(nb_coreset_active=%d, searchSpaceType=%d)\n",
+                  nb_coreset_active,
+                  searchSpaceType);
+        #endif
+        nr_rx_pdcch(ue,
+                    proc->frame_rx,
+                    nr_tti_rx,
+                    eNB_id,
+                    //(ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI, // NR_DL_FRAME_PARMS struct has been modified, and 'mode1_flag' needs to be included
+                    SISO,
+                    ue->high_speed_flag,
+                    ue->is_secondary_ue,
+                    nb_coreset_active,
+                    (symbol_within_slot_mon&0x3FFF),
+                    searchSpaceType);
+        #ifdef NR_PDCCH_SCHED_DEBUG
+          printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_rx_pdcch(nb_coreset_active=%d, searchSpaceType=%d)\n",
+                  nb_coreset_active,
+                  searchSpaceType);
+        #endif
+
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN);
+
+/*
+	    //printf("Decode SIB frame param agregation + DCI %d %d \n",agregationLevel,dciFormat);
+
+	    //agregation level == FF means no configuration on
+	    if(ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->agregationLevel == 0xFF || ue->decode_SIB)
+	    {
+	        // search all possible dcis
+	        dci_cnt = dci_decoding_procedure(ue,
+	                dci_alloc_rx,
+	                (ue->UE_mode[eNB_id] < PUSCH)? 1 : 0,  // if we're in PUSCH don't listen to common search space,
+	                                                       // later when we need paging or RA during connection, update this ...
+	                eNB_id,nr_tti_rx);
+	    }
+	    else
+	    {
+	        // search only preconfigured dcis
+	        // search C RNTI dci
+	        dci_cnt = dci_CRNTI_decoding_procedure(ue,
+	                dci_alloc_rx,
+	                ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dciFormat,
+	                ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->agregationLevel,
+	                eNB_id,
+	                nr_tti_rx);
+	    }
+*/  //removed for nr_ue_pdcch_procedures
+        if (searchSpaceType == common) {  // search all possible dci's for COMMON SEARCH SPACES according to the current SEARCHSPACE configuration
+          #ifdef NR_PDCCH_SCHED_DEBUG
+            printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_dci_decoding_procedure(searchSpaceType=%d, nb_searchspace_active=%d, nb_coreset_active=%d) -> dci_cnt=%d\n",
+                    searchSpaceType,
+                    nb_searchspace_active,
+                    nb_coreset_active,
+                    dci_cnt);
+          #endif
+          dci_cnt = nr_dci_decoding_procedure(nb_searchspace_active,
+                                              nb_coreset_active,
+                                              ue,
+                                              dci_alloc_rx,
+                                              searchSpaceType,  // if we're in PUSCH don't listen to common search space,
+                                                                // later when we need paging or RA during connection, update this ...
+                                              eNB_id,
+                                              nr_tti_rx,
+                                              dci_fields_sizes,
+                                              n_RB_ULBWP,
+                                              n_RB_DLBWP);
+          #ifdef NR_PDCCH_SCHED_DEBUG
+            printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%d\n",dci_cnt);
+          #endif
+        }
+        if (searchSpaceType == ue_specific){// search all possible dci's for UE-SPECIFIC SEARCH SPACES according to the current SEARCHSPACE configuration
+          #ifdef NR_PDCCH_SCHED_DEBUG
+            printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_dci_decoding_procedure(searchSpaceType=%d, nb_searchspace_active=%d, nb_coreset_active=%d) -> dci_cnt=%d\n",
+                    searchSpaceType,
+                    nb_searchspace_active,
+                    nb_coreset_active,
+                    dci_cnt);
+          #endif
+          dci_cnt = nr_dci_decoding_procedure(nb_searchspace_active,
+                                              nb_coreset_active,
+                                              ue,
+                                              dci_alloc_rx,
+                                              searchSpaceType,  // if we're in PUSCH don't listen to common search space,
+                                                                // later when we need paging or RA during connection, update this ...
+                                              eNB_id,
+                                              nr_tti_rx,
+                                              dci_fields_sizes,
+                                              n_RB_ULBWP,
+                                              n_RB_DLBWP);
+          #ifdef NR_PDCCH_SCHED_DEBUG
+            printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%d\n",dci_cnt);
+          #endif
+        }
+
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
+        //LOG_D(PHY,"[UE  %d][PUSCH] Frame %d nr_tti_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_tti_rx);
+
+        /*  if (is_phich_subframe(&ue->frame_parms,nr_tti_rx)) {
+              VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_IN);
+              rx_phich(ue,proc,nr_tti_rx,eNB_id);
+              VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT);
+            }*/ //removed for nr_ue_pdcch_procedures
+      }
+#if 0
+	#ifdef PHY_ABSTRACTION
+	  else {
+	    for (i=0; i<NB_eNB_INST; i++) {
+	      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
+	  if (PHY_vars_eNB_g[i][CC_id]->frame_parms.Nid_cell == ue->frame_parms.Nid_cell)
+	    break;
+
+	      if (CC_id < MAX_NUM_CCs)
+	  break;
+	    }
+
+	    if (i==NB_eNB_INST) {
+	      LOG_E(PHY,"[UE  %d] phy_procedures_lte_ue.c: FATAL : Could not find attached eNB for DCI emulation (Nid_cell %d)!!!!\n",ue->Mod_id,ue->frame_parms.Nid_cell);
+	      //mac_xface->macphy_exit("Could not find attached eNB for DCI emulation");
+	      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
+	      return(-1);
+	    }
+
+	    LOG_D(PHY,"Calling dci_decoding_proc_emul ...\n");
+	    dci_cnt = dci_decoding_procedure_emul(ue->pdcch_vars[nr_tti_rx&1],
+	                                          PHY_vars_eNB_g[i][CC_id]->num_ue_spec_dci[nr_tti_rx&1],
+	                                          PHY_vars_eNB_g[i][CC_id]->num_common_dci[nr_tti_rx&1],
+	                                          PHY_vars_eNB_g[i][CC_id]->dci_alloc[nr_tti_rx&1],
+	                                          dci_alloc_rx,
+	                                          eNB_id);
+	    //    printf("DCI: dci_cnt %d\n",dci_cnt);
+	    UE_id = (uint32_t)nr_find_ue((int16_t)ue->pdcch_vars[nr_tti_rx&1][eNB_id]->crnti,PHY_vars_eNB_g[i][CC_id]);
+
+	    if (UE_id>=0) {
+	      //      printf("Checking PHICH for UE  %d (eNB %d)\n",UE_id,i);
+	      //if (is_phich_subframe(&ue->frame_parms,nr_tti_rx)) {
+	      //harq_pid = phich_subframe_to_harq_pid(&ue->frame_parms,frame_rx,nr_tti_rx);
+              //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == ACTIVE) {
+	      //ue->ulsch[eNB_id]->harq_processes[harq_pid]->phich_ACK=1;
+	      //ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag =0;
+	      //ue->ulsch[eNB_id]->harq_processes[harq_pid]->status = IDLE;
+	      //ue->ulsch_Msg3_active[eNB_id] = 0;
+	      //ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
+	      //LOG_D(PHY,"Msg3 inactive\n");
+              //} // harq_pid is ACTIVE
+	      //} // This is a PHICH nr_tti_rx
+	    } // UE_id exists
+	  }
+
+	#endif
+#endif
+      uint8_t *nCCE_current = &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->nCCE[nr_tti_rx];
+      uint8_t *nCCE_dest = &ue->pdcch_vars[next1_thread_id][eNB_id]->nCCE[nr_tti_rx];
+      uint8_t *nCCE_dest1 = &ue->pdcch_vars[next2_thread_id][eNB_id]->nCCE[nr_tti_rx];
+      memcpy(nCCE_dest, nCCE_current, sizeof(uint8_t));
+      memcpy(nCCE_dest1, nCCE_current, sizeof(uint8_t));
+
+      LOG_D(PHY,"current_thread %d next1_thread %d next2_thread %d \n", ue->current_thread_id[nr_tti_rx], next1_thread_id, next2_thread_id);
+
+      LOG_D(PHY,"[UE  %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n",
+                 ue->Mod_id,frame_rx%1024,nr_tti_rx,mode_string[ue->UE_mode[eNB_id]],
+                 dci_cnt,
+                 dci_alloc_rx[0].rnti,
+                 ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+                 dci_alloc_rx[0].format );
+      ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dci_received += dci_cnt;
+
+#ifdef EMOS
+  //emos_dump_UE.dci_cnt[nr_tti_rx] = dci_cnt;
+#endif
+
+      for (i=0; i<dci_cnt; i++) {
+        /*
+         * This is the NR part
+         */
+        if ((dci_alloc_rx[i].rnti == SI_RNTI) && (dci_alloc_rx[i].format == format1_0)){
+          nr_generate_ue_ul_dlsch_params_from_dci(ue,
+                                                  eNB_id,
+                                                  frame_rx,
+                                                  nr_tti_rx,
+                                                  (void *)&dci_alloc_rx[i].dci_pdu,
+                                                  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+                                                  dci_alloc_rx[i].dci_length,
+                                                  dci_alloc_rx[i].format,
+                                                  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->ulsch[eNB_id],
+                                                  &ue->frame_parms,
+                                                  ue->pdsch_config_dedicated,
+                                                  SI_RNTI,
+                                                  0,
+                                                  P_RNTI,
+                                                  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+                                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti: 0,
+                                                  &dci_fields_sizes,
+                                                  n_RB_ULBWP,
+                                                  n_RB_DLBWP);
+          ue->dlsch_SI_received[eNB_id]++;
+        }
+
+        if ((dci_alloc_rx[i].rnti == P_RNTI) && (dci_alloc_rx[i].format == format1_0)){
+          ue->dlsch_p_received[eNB_id]++;
+        }
+
+        if ((dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) && (dci_alloc_rx[i].format == format1_0)){
+          nr_generate_ue_ul_dlsch_params_from_dci(ue,
+                                                  eNB_id,
+                                                  frame_rx,
+                                                  nr_tti_rx,
+                                                  (void *)&dci_alloc_rx[i].dci_pdu,
+                                                  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+                                                  dci_alloc_rx[i].dci_length,
+                                                  dci_alloc_rx[i].format,
+                                                  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->ulsch[eNB_id],
+                                                  &ue->frame_parms,
+                                                  ue->pdsch_config_dedicated,
+                                                  SI_RNTI,
+                                                  ue->prach_resources[eNB_id]->ra_RNTI,
+                                                  P_RNTI,
+                                                  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+                                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti: 0,
+                                                  &dci_fields_sizes,
+                                                  n_RB_ULBWP,
+                                                  n_RB_DLBWP);
+          ue->dlsch_ra_received[eNB_id]++;
+        }
+
+        if ((dci_alloc_rx[i].rnti == sfi_rnti) && (dci_alloc_rx[i].format == format2_0)){
+        }
+
+        if ((dci_alloc_rx[i].rnti == int_rnti) && (dci_alloc_rx[i].format == format2_1)){
+        }
+
+        if ((dci_alloc_rx[i].rnti == tpc_pusch_rnti) && (dci_alloc_rx[i].format == format2_2)){
+        }
+
+        if ((dci_alloc_rx[i].rnti == tpc_srs_rnti) && (dci_alloc_rx[i].format == format2_3)){
+        }
+
+        if ((dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti) && (dci_alloc_rx[i].format == format0_0)){
+          nr_generate_ue_ul_dlsch_params_from_dci(ue,
+                                                  eNB_id,
+                                                  frame_rx,
+                                                  nr_tti_rx,
+                                                  (void *)&dci_alloc_rx[i].dci_pdu,
+                                                  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+                                                  dci_alloc_rx[i].dci_length,
+                                                  dci_alloc_rx[i].format,
+                                                  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->ulsch[eNB_id],
+                                                  &ue->frame_parms,
+                                                  ue->pdsch_config_dedicated,
+                                                  SI_RNTI,
+                                                  0,
+                                                  P_RNTI,
+                                                  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+                                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti: 0,
+                                                  &dci_fields_sizes,
+                                                  n_RB_ULBWP,
+                                                  n_RB_DLBWP);
+        }
+
+        if ((dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti) && (dci_alloc_rx[i].format == format0_1)){ // This format not implemented at a first time. FIXME
+        }
+
+        if ((dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti) && (dci_alloc_rx[i].format == format1_0)){
+          nr_generate_ue_ul_dlsch_params_from_dci(ue,
+                                                  eNB_id,
+                                                  frame_rx,
+                                                  nr_tti_rx,
+                                                  (void *)&dci_alloc_rx[i].dci_pdu,
+                                                  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+                                                  dci_alloc_rx[i].dci_length,
+                                                  dci_alloc_rx[i].format,
+                                                  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id],
+                                                  ue->ulsch[eNB_id],
+                                                  &ue->frame_parms,
+                                                  ue->pdsch_config_dedicated,
+                                                  SI_RNTI,
+                                                  0,
+                                                  P_RNTI,
+                                                  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+                                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti: 0,
+                                                  &dci_fields_sizes,
+                                                  n_RB_ULBWP,
+                                                  n_RB_DLBWP);
+          ue->dlsch_received[eNB_id]++;
+        }
+
+        if ((dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti) && (dci_alloc_rx[i].format == format1_1)){ // This format not implemented at a first time. FIXME
+        }
+
+#if 0
+	/*
+	 * This is the LTE part to be removed
+	 */
+	    if ((ue->UE_mode[eNB_id]>PRACH) && (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti) && (dci_alloc_rx[i].format != format0)) {
+
+	      LOG_D(PHY,"[UE  %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
+		    ue->Mod_id,dci_alloc_rx[i].rnti,
+		    frame_rx%1024,nr_tti_rx,
+		    dci_alloc_rx[i].format,
+		    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+		    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->nCCE[nr_tti_rx],
+		    get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
+
+	      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+
+	      if ((ue->UE_mode[eNB_id] > PRACH) &&
+		  (generate_ue_dlsch_params_from_dci(frame_rx,
+						     nr_tti_rx,
+						     (void *)&dci_alloc_rx[i].dci_pdu,
+						     ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+						     dci_alloc_rx[i].format,
+						     ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+						     ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+						     ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id],
+						     &ue->frame_parms,
+						     ue->pdsch_config_dedicated,
+						     SI_RNTI,
+						     0,
+						     P_RNTI,
+						     ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+						     ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti: 0)==0)) {
+
+	          // update TPC for PUCCH
+	          if((dci_alloc_rx[i].format == format1)   ||
+	              (dci_alloc_rx[i].format == format1A) ||
+	              (dci_alloc_rx[i].format == format1B) ||
+	              (dci_alloc_rx[i].format == format2)  ||
+	              (dci_alloc_rx[i].format == format2A) ||
+	              (dci_alloc_rx[i].format == format2B))
+	          {
+	            //ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->g_pucch += ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
+	            int32_t delta_pucch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
+	            for(int th_id=0; th_id<RX_NB_TH; th_id++)
+	            {
+	                ue->dlsch[th_id][eNB_id][0]->g_pucch += delta_pucch;
+	            }
+	            LOG_D(PHY,"update TPC for PUCCH %d.%d / pid %d delta_PUCCH %d g_pucch %d %d \n",frame_rx, nr_tti_rx,ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid,
+	                    delta_pucch,
+	                    ue->dlsch[0][eNB_id][0]->g_pucch,
+	                    ue->dlsch[1][eNB_id][0]->g_pucch
+	                    //ue->dlsch[2][eNB_id][0]->g_pucch
+	                    );
+	          }
+
+	  ue->dlsch_received[eNB_id]++;
+
+	#ifdef DEBUG_PHY_PROC
+		LOG_D(PHY,"[UE  %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format);
+		dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+		LOG_D(PHY,"[UE %d] *********** dlsch->active in nr_tti_rx %d=> %d\n",ue->Mod_id,nr_tti_rx,ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active);
+	#endif
+
+	  // we received a CRNTI, so we're in PUSCH
+	  if (ue->UE_mode[eNB_id] != PUSCH) {
+	#ifdef DEBUG_PHY_PROC
+	          LOG_I(PHY,"[UE  %d] Frame %d, nr_tti_rx %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,nr_tti_rx,ue->pdcch_vars[nr_tti_rx&1][eNB_id]->crnti);
+	#endif
+	    //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	    ue->UE_mode[eNB_id] = PUSCH;
+	    //mac_xface->macphy_exit("Connected. Exiting\n");
+	  }
+	      } else {
+	  LOG_E(PHY,"[UE  %d] Frame %d, nr_tti_rx %d: Problem in DCI!\n",ue->Mod_id,frame_rx,nr_tti_rx);
+	  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	      }
+	    }
+
+	    else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
+	       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
+
+	#ifdef DEBUG_PHY_PROC
+	      LOG_I(PHY,"[UE  %d] nr_tti_rx %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,nr_tti_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
+	#endif
+
+
+	      if (generate_ue_dlsch_params_from_dci(frame_rx,
+	              nr_tti_rx,
+	              (void *)&dci_alloc_rx[i].dci_pdu,
+	              SI_RNTI,
+	              dci_alloc_rx[i].format,
+						    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+						    ue->pdsch_vars_SI[eNB_id],
+	              &ue->dlsch_SI[eNB_id],
+	              &ue->frame_parms,
+	              ue->pdsch_config_dedicated,
+	              SI_RNTI,
+	              0,
+	              P_RNTI,
+	              ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+	              0)==0) {
+
+	  ue->dlsch_SI_received[eNB_id]++;
+
+
+	  LOG_I(PHY,"[UE  %d] Frame %d, nr_tti_rx %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,nr_tti_rx,dci_alloc_rx[i].format==format1A?"A":"C");
+	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+
+	      }
+	    }
+
+	    else if ((dci_alloc_rx[i].rnti == P_RNTI) &&
+	       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
+
+	#ifdef DEBUG_PHY_PROC
+	      LOG_I(PHY,"[UE  %d] nr_tti_rx %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,nr_tti_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
+	#endif
+
+
+	      if (generate_ue_dlsch_params_from_dci(frame_rx,
+	              nr_tti_rx,
+	              (void *)&dci_alloc_rx[i].dci_pdu,
+	            P_RNTI,
+	              dci_alloc_rx[i].format,
+						    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+						    ue->pdsch_vars_p[eNB_id],
+	              &ue->dlsch_SI[eNB_id],
+	              &ue->frame_parms,
+	              ue->pdsch_config_dedicated,
+	              SI_RNTI,
+	              0,
+	              P_RNTI,
+	              ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+	                                            0)==0) {
+
+	  ue->dlsch_p_received[eNB_id]++;
+	  LOG_D(PHY,"[UE  %d] Frame %d, nr_tti_rx %d : Generate UE DLSCH P_RNTI format 1%s\n",ue->Mod_id,frame_rx,nr_tti_rx,dci_alloc_rx[i].format==format1A?"A":"C");
+	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+
+	      }
+	    }
+
+	    else if ((ue->prach_resources[eNB_id]) &&
+	       (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) &&
+	       (dci_alloc_rx[i].format == format1A)) {
+
+	#ifdef DEBUG_PHY_PROC
+	      LOG_D(PHY,"[UE  %d][RAPROC] nr_tti_rx %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,nr_tti_rx,dci_alloc_rx[i].rnti,i);
+
+	      //if (((frame_rx%100) == 0) || (frame_rx < 20))
+	      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	      //mac_xface->macphy_exit("so far so good...\n");
+	#endif
+
+
+	      if (generate_ue_dlsch_params_from_dci(frame_rx,
+	              nr_tti_rx,
+	              (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
+	              ue->prach_resources[eNB_id]->ra_RNTI,
+	              format1A,
+						    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+						    ue->pdsch_vars_ra[eNB_id],
+	              &ue->dlsch_ra[eNB_id],
+	              &ue->frame_parms,
+	              ue->pdsch_config_dedicated,
+	              SI_RNTI,
+	              ue->prach_resources[eNB_id]->ra_RNTI,
+	              P_RNTI,
+	              ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+	                                            0)==0) {
+
+	  ue->dlsch_ra_received[eNB_id]++;
+
+	#ifdef DEBUG_PHY_PROC
+	  LOG_D(PHY,"[UE  %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n",
+	        ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]);
+	#endif
+	      }
+	    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti) &&
+		       (dci_alloc_rx[i].format == format0)) {
+
+	#ifdef DEBUG_PHY_PROC
+	      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d nr_tti_rx %d: Found rnti %x, format 0, dci_cnt %d\n",
+	      ue->Mod_id,frame_rx,nr_tti_rx,dci_alloc_rx[i].rnti,i);
+	#endif
+
+	      ue->ulsch_no_allocation_counter[eNB_id] = 0;
+	      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
+
+	      if ((ue->UE_mode[eNB_id] > PRACH) &&
+		  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
+						     ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+						     nr_tti_rx,
+						     format0,
+						     ue,
+						     proc,
+						     SI_RNTI,
+						     0,
+						     P_RNTI,
+						     CBA_RNTI,
+						     eNB_id,
+						     0)==0)) {
+	#if T_TRACER
+	    NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+	    uint8_t harq_pid = nr_subframe2harq_pid(frame_parms,
+	                                 nr_pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,proc->nr_tti_rx),
+	                                 nr_pdcch_alloc2ul_subframe(frame_parms,proc->nr_tti_rx));
+
+	    T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->nr_tti_rx), T_INT(ue->Mod_id),
+	      T_INT(dci_alloc_rx[i].rnti), T_INT(harq_pid),
+	      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs),
+	      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round),
+	      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb),
+	      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb),
+	      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS));
+	#endif
+	#ifdef DEBUG_PHY_PROC
+	  LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (nr_tti_rx %d)\n",ue->Mod_id,nr_tti_rx);
+	#endif
+
+	      }
+	    } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) &&
+	         (dci_alloc_rx[i].format == format0)) {
+	      // UE could belong to more than one CBA group
+	      // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups]
+	#ifdef DEBUG_PHY_PROC
+	      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d nr_tti_rx %d: Found cba rnti %x, format 0, dci_cnt %d\n",
+	      ue->Mod_id,frame_rx,nr_tti_rx,dci_alloc_rx[i].rnti,i);
+	      /*
+	  if (((frame_rx%100) == 0) || (frame_rx < 20))
+	  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	      */
+	#endif
+
+	      ue->ulsch_no_allocation_counter[eNB_id] = 0;
+	      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
+
+	      if ((ue->UE_mode[eNB_id] > PRACH) &&
+	    (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
+	               ue->ulsch[eNB_id]->cba_rnti[0],
+	               nr_tti_rx,
+	               format0,
+	               ue,
+	               proc,
+	               SI_RNTI,
+	               0,
+	               P_RNTI,
+	               CBA_RNTI,
+	               eNB_id,
+	               0)==0)) {
+
+	#ifdef DEBUG_PHY_PROC
+	  LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (nr_tti_rx %d)\n",ue->Mod_id,nr_tti_rx);
+	#endif
+	  ue->ulsch[eNB_id]->num_cba_dci[(nr_tti_rx+4)%10]++;
+	      }
+	    }
+
+	    else {
+	#ifdef DEBUG_PHY_PROC
+	      LOG_D(PHY,"[UE  %d] frame %d, nr_tti_rx %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,nr_tti_rx,i,dci_alloc_rx[i].rnti,
+		    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+		    ue->ulsch[eNB_id]->cba_rnti[0],
+		    dci_alloc_rx[i].format);
+
+	      //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	#endif
+	    }
+#endif //(0)
+
+
+
+      } // end for loop dci_cnt
+#if UE_TIMING_TRACE
+  stop_meas(&ue->dlsch_rx_pdcch_stats);
+#endif
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
+
+    } // end if do_pdcch_monitoring_current_slot
+  } // end for loop nb_searchspacet_active
+  return(0);
+}
+#endif
+
+#if 0
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t abstraction_flag)
+{
+
+  unsigned int dci_cnt=0, i;
+
+  int frame_rx = proc->frame_rx;
+  int nr_tti_rx = proc->nr_tti_rx;
+  DCI_ALLOC_t dci_alloc_rx[8];
+
+  uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
+
+#ifdef PHY_ABSTRACTION
+  int CC_id;
+  int UE_id;
+  uint8_t harq_pid;
+#endif
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN);
+#if UE_TIMING_TRACE
+  start_meas(&ue->dlsch_rx_pdcch_stats);
+#endif
+
+  //  if (nr_tti_rx != 5)
+  //    return 0;
+  if (abstraction_flag == 0)  {
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
+    rx_pdcch(ue,
+             proc->frame_rx,
+             nr_tti_rx,
+             eNB_id,
+             (ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
+             ue->high_speed_flag,
+             ue->is_secondary_ue);
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN);
+
+
+    //printf("Decode SIB frame param agregation + DCI %d %d \n",agregationLevel,dciFormat);
+
+    //agregation level == FF means no configuration on
+    if(ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->agregationLevel == 0xFF || ue->decode_SIB)
+    {
+        // search all possible dcis
+        dci_cnt = dci_decoding_procedure(ue,
+                dci_alloc_rx,
+                (ue->UE_mode[eNB_id] < PUSCH)? 1 : 0,  // if we're in PUSCH don't listen to common search space,
+                                                       // later when we need paging or RA during connection, update this ...
+                eNB_id,nr_tti_rx);
+    }
+    else
+    {
+        // search only preconfigured dcis
+        // search C RNTI dci
+        dci_cnt = dci_CRNTI_decoding_procedure(ue,
+                dci_alloc_rx,
+                ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dciFormat,
+                ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->agregationLevel,
+                eNB_id,
+                nr_tti_rx);
+    }
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
+    //LOG_D(PHY,"[UE  %d][PUSCH] Frame %d nr_tti_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_tti_rx);
+
+    if (is_phich_subframe(&ue->frame_parms,nr_tti_rx)) {
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_IN);
+      rx_phich(ue,proc,
+         nr_tti_rx,eNB_id);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT);
+    }
+  }
+
+#ifdef PHY_ABSTRACTION
+  else {
+    for (i=0; i<NB_eNB_INST; i++) {
+      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
+  if (PHY_vars_eNB_g[i][CC_id]->frame_parms.Nid_cell == ue->frame_parms.Nid_cell)
+    break;
+
+      if (CC_id < MAX_NUM_CCs)
+  break;
+    }
+
+    if (i==NB_eNB_INST) {
+      LOG_E(PHY,"[UE  %d] phy_procedures_lte_ue.c: FATAL : Could not find attached eNB for DCI emulation (Nid_cell %d)!!!!\n",ue->Mod_id,ue->frame_parms.Nid_cell);
+      //mac_xface->macphy_exit("Could not find attached eNB for DCI emulation");
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
+      return(-1);
+    }
+
+    LOG_D(PHY,"Calling dci_decoding_proc_emul ...\n");
+    dci_cnt = dci_decoding_procedure_emul(ue->pdcch_vars[nr_tti_rx&1],
+                                          PHY_vars_eNB_g[i][CC_id]->num_ue_spec_dci[nr_tti_rx&1],
+                                          PHY_vars_eNB_g[i][CC_id]->num_common_dci[nr_tti_rx&1],
+                                          PHY_vars_eNB_g[i][CC_id]->dci_alloc[nr_tti_rx&1],
+                                          dci_alloc_rx,
+                                          eNB_id);
+    //    printf("DCI: dci_cnt %d\n",dci_cnt);
+    UE_id = (uint32_t)nr_find_ue((int16_t)ue->pdcch_vars[nr_tti_rx&1][eNB_id]->crnti,PHY_vars_eNB_g[i][CC_id]);
+
+    if (UE_id>=0) {
+      //      printf("Checking PHICH for UE  %d (eNB %d)\n",UE_id,i);
+      if (is_phich_subframe(&ue->frame_parms,nr_tti_rx)) {
+  harq_pid = phich_subframe_to_harq_pid(&ue->frame_parms,frame_rx,nr_tti_rx);
+
+  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == ACTIVE) {
+    // ue->ulsch[eNB_id]->harq_processes[harq_pid]->phich_ACK=1;
+    ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag =0;
+    ue->ulsch[eNB_id]->harq_processes[harq_pid]->status = IDLE;
+    ue->ulsch_Msg3_active[eNB_id] = 0;
+    ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
+    LOG_D(PHY,"Msg3 inactive\n");
+
+  } // harq_pid is ACTIVE
+      } // This is a PHICH nr_tti_rx
+    } // UE_id exists
+  }
+
+#endif
+
+  uint8_t *nCCE_current = &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->nCCE[nr_tti_rx];
+  uint8_t *nCCE_dest = &ue->pdcch_vars[next1_thread_id][eNB_id]->nCCE[nr_tti_rx];
+  uint8_t *nCCE_dest1 = &ue->pdcch_vars[next2_thread_id][eNB_id]->nCCE[nr_tti_rx];
+  memcpy(nCCE_dest, nCCE_current, sizeof(uint8_t));
+  memcpy(nCCE_dest1, nCCE_current, sizeof(uint8_t));
+
+  LOG_D(PHY,"current_thread %d next1_thread %d next2_thread %d \n", ue->current_thread_id[nr_tti_rx], next1_thread_id, next2_thread_id);
+
+  LOG_D(PHY,"[UE  %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n",
+       ue->Mod_id,frame_rx%1024,nr_tti_rx,mode_string[ue->UE_mode[eNB_id]],
+       dci_cnt,
+       dci_alloc_rx[0].rnti,
+       ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+       dci_alloc_rx[0].format );
+
+  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dci_received += dci_cnt;
+
+#ifdef EMOS
+  //emos_dump_UE.dci_cnt[nr_tti_rx] = dci_cnt;
+#endif
+
+  for (i=0; i<dci_cnt; i++) {
+
+    if ((ue->UE_mode[eNB_id]>PRACH) &&
+	(dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti) &&
+	(dci_alloc_rx[i].format != format0)) {
+
+      LOG_D(PHY,"[UE  %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
+	    ue->Mod_id,dci_alloc_rx[i].rnti,
+	    frame_rx%1024,nr_tti_rx,
+	    dci_alloc_rx[i].format,
+	    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+	    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->nCCE[nr_tti_rx],
+	    get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
+
+      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+
+      if ((ue->UE_mode[eNB_id] > PRACH) &&
+	  (generate_ue_dlsch_params_from_dci(frame_rx,
+					     nr_tti_rx,
+					     (void *)&dci_alloc_rx[i].dci_pdu,
+					     ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+					     dci_alloc_rx[i].format,
+					     ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+					     ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+					     ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id],
+					     &ue->frame_parms,
+					     ue->pdsch_config_dedicated,
+					     SI_RNTI,
+					     0,
+					     P_RNTI,
+					     ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+					     ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti: 0)==0)) {
+
+          // update TPC for PUCCH
+          if((dci_alloc_rx[i].format == format1)   ||
+              (dci_alloc_rx[i].format == format1A) ||
+              (dci_alloc_rx[i].format == format1B) ||
+              (dci_alloc_rx[i].format == format2)  ||
+              (dci_alloc_rx[i].format == format2A) ||
+              (dci_alloc_rx[i].format == format2B))
+          {
+            //ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->g_pucch += ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
+            int32_t delta_pucch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
+            for(int th_id=0; th_id<RX_NB_TH; th_id++)
+            {
+                ue->dlsch[th_id][eNB_id][0]->g_pucch += delta_pucch;
+            }
+            LOG_D(PHY,"update TPC for PUCCH %d.%d / pid %d delta_PUCCH %d g_pucch %d %d \n",frame_rx, nr_tti_rx,ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid,
+                    delta_pucch,
+                    ue->dlsch[0][eNB_id][0]->g_pucch,
+                    ue->dlsch[1][eNB_id][0]->g_pucch
+                    //ue->dlsch[2][eNB_id][0]->g_pucch
+                    );
+          }
+
+  ue->dlsch_received[eNB_id]++;
+
+#ifdef DEBUG_PHY_PROC
+	LOG_D(PHY,"[UE  %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format);
+	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	LOG_D(PHY,"[UE %d] *********** dlsch->active in nr_tti_rx %d=> %d\n",ue->Mod_id,nr_tti_rx,ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active);
+#endif
+
+  // we received a CRNTI, so we're in PUSCH
+  if (ue->UE_mode[eNB_id] != PUSCH) {
+#ifdef DEBUG_PHY_PROC
+          LOG_I(PHY,"[UE  %d] Frame %d, nr_tti_rx %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,nr_tti_rx,ue->pdcch_vars[nr_tti_rx&1][eNB_id]->crnti);
+#endif
+    //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+    ue->UE_mode[eNB_id] = PUSCH;
+    //mac_xface->macphy_exit("Connected. Exiting\n");
+  }
+      } else {
+  LOG_E(PHY,"[UE  %d] Frame %d, nr_tti_rx %d: Problem in DCI!\n",ue->Mod_id,frame_rx,nr_tti_rx);
+  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+      }
+    }
+
+    else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
+       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
+
+#ifdef DEBUG_PHY_PROC
+      LOG_I(PHY,"[UE  %d] nr_tti_rx %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,nr_tti_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
+#endif
+
+
+      if (generate_ue_dlsch_params_from_dci(frame_rx,
+              nr_tti_rx,
+              (void *)&dci_alloc_rx[i].dci_pdu,
+              SI_RNTI,
+              dci_alloc_rx[i].format,
+					    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+					    ue->pdsch_vars_SI[eNB_id],
+              &ue->dlsch_SI[eNB_id],
+              &ue->frame_parms,
+              ue->pdsch_config_dedicated,
+              SI_RNTI,
+              0,
+              P_RNTI,
+              ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+              0)==0) {
+
+  ue->dlsch_SI_received[eNB_id]++;
+
+
+  LOG_I(PHY,"[UE  %d] Frame %d, nr_tti_rx %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,nr_tti_rx,dci_alloc_rx[i].format==format1A?"A":"C");
+  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+
+      }
+    }
+
+    else if ((dci_alloc_rx[i].rnti == P_RNTI) &&
+       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
+
+#ifdef DEBUG_PHY_PROC
+      LOG_I(PHY,"[UE  %d] nr_tti_rx %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,nr_tti_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
+#endif
+
+
+      if (generate_ue_dlsch_params_from_dci(frame_rx,
+              nr_tti_rx,
+              (void *)&dci_alloc_rx[i].dci_pdu,
+            P_RNTI,
+              dci_alloc_rx[i].format,
+					    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+					    ue->pdsch_vars_p[eNB_id],
+              &ue->dlsch_SI[eNB_id],
+              &ue->frame_parms,
+              ue->pdsch_config_dedicated,
+              SI_RNTI,
+              0,
+              P_RNTI,
+              ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+                                            0)==0) {
+
+  ue->dlsch_p_received[eNB_id]++;
+  LOG_D(PHY,"[UE  %d] Frame %d, nr_tti_rx %d : Generate UE DLSCH P_RNTI format 1%s\n",ue->Mod_id,frame_rx,nr_tti_rx,dci_alloc_rx[i].format==format1A?"A":"C");
+  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+
+      }
+    }
+
+    else if ((ue->prach_resources[eNB_id]) &&
+       (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) &&
+       (dci_alloc_rx[i].format == format1A)) {
+
+#ifdef DEBUG_PHY_PROC
+      LOG_D(PHY,"[UE  %d][RAPROC] nr_tti_rx %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,nr_tti_rx,dci_alloc_rx[i].rnti,i);
+
+      //if (((frame_rx%100) == 0) || (frame_rx < 20))
+      //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+      //mac_xface->macphy_exit("so far so good...\n");
+#endif
+
+
+      if (generate_ue_dlsch_params_from_dci(frame_rx,
+              nr_tti_rx,
+              (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
+              ue->prach_resources[eNB_id]->ra_RNTI,
+              format1A,
+					    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id],
+					    ue->pdsch_vars_ra[eNB_id],
+              &ue->dlsch_ra[eNB_id],
+              &ue->frame_parms,
+              ue->pdsch_config_dedicated,
+              SI_RNTI,
+              ue->prach_resources[eNB_id]->ra_RNTI,
+              P_RNTI,
+              ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+                                            0)==0) {
+
+  ue->dlsch_ra_received[eNB_id]++;
+
+#ifdef DEBUG_PHY_PROC
+  LOG_D(PHY,"[UE  %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n",
+        ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]);
+#endif
+      }
+    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti) &&
+	       (dci_alloc_rx[i].format == format0)) {
+
+#ifdef DEBUG_PHY_PROC
+      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d nr_tti_rx %d: Found rnti %x, format 0, dci_cnt %d\n",
+      ue->Mod_id,frame_rx,nr_tti_rx,dci_alloc_rx[i].rnti,i);
+#endif
+
+      ue->ulsch_no_allocation_counter[eNB_id] = 0;
+      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
+
+      if ((ue->UE_mode[eNB_id] > PRACH) &&
+	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
+					     ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+					     nr_tti_rx,
+					     format0,
+					     ue,
+					     proc,
+					     SI_RNTI,
+					     0,
+					     P_RNTI,
+					     CBA_RNTI,
+					     eNB_id,
+					     0)==0)) {
+#if T_TRACER
+    NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+    uint8_t harq_pid = nr_subframe2harq_pid(frame_parms,
+                                 nr_pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,proc->nr_tti_rx),
+                                 nr_pdcch_alloc2ul_subframe(frame_parms,proc->nr_tti_rx));
+
+    T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->nr_tti_rx), T_INT(ue->Mod_id),
+      T_INT(dci_alloc_rx[i].rnti), T_INT(harq_pid),
+      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs),
+      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round),
+      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb),
+      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb),
+      T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS));
+#endif
+#ifdef DEBUG_PHY_PROC
+  LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (nr_tti_rx %d)\n",ue->Mod_id,nr_tti_rx);
+#endif
+
+      }
+    } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) &&
+         (dci_alloc_rx[i].format == format0)) {
+      // UE could belong to more than one CBA group
+      // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups]
+#ifdef DEBUG_PHY_PROC
+      LOG_D(PHY,"[UE  %d][PUSCH] Frame %d nr_tti_rx %d: Found cba rnti %x, format 0, dci_cnt %d\n",
+      ue->Mod_id,frame_rx,nr_tti_rx,dci_alloc_rx[i].rnti,i);
+      /*
+  if (((frame_rx%100) == 0) || (frame_rx < 20))
+  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+      */
+#endif
+
+      ue->ulsch_no_allocation_counter[eNB_id] = 0;
+      //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
+
+      if ((ue->UE_mode[eNB_id] > PRACH) &&
+    (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
+               ue->ulsch[eNB_id]->cba_rnti[0],
+               nr_tti_rx,
+               format0,
+               ue,
+               proc,
+               SI_RNTI,
+               0,
+               P_RNTI,
+               CBA_RNTI,
+               eNB_id,
+               0)==0)) {
+
+#ifdef DEBUG_PHY_PROC
+  LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (nr_tti_rx %d)\n",ue->Mod_id,nr_tti_rx);
+#endif
+  ue->ulsch[eNB_id]->num_cba_dci[(nr_tti_rx+4)%10]++;
+      }
+    }
+
+    else {
+#ifdef DEBUG_PHY_PROC
+      LOG_D(PHY,"[UE  %d] frame %d, nr_tti_rx %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,nr_tti_rx,i,dci_alloc_rx[i].rnti,
+	    ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+	    ue->ulsch[eNB_id]->cba_rnti[0],
+	    dci_alloc_rx[i].format);
+
+      //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+#endif
+    }
+
+  }
+#if UE_TIMING_TRACE
+  stop_meas(&ue->dlsch_rx_pdcch_stats);
+#endif
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
+  return(0);
+}
+
+
+
+void ue_pmch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc,int eNB_id,int abstraction_flag) {
+
+  int nr_tti_rx = proc->nr_tti_rx;
+  int frame_rx = proc->frame_rx;
+  int pmch_mcs=-1;
+#if defined(Rel10) || defined(Rel14)
+  int CC_id = ue->CC_id;
+#endif
+  uint8_t sync_area=255;
+  uint8_t mcch_active;
+  int l;
+  int ret=0;
+
+  if (is_pmch_subframe(frame_rx,nr_tti_rx,&ue->frame_parms)) {
+    LOG_D(PHY,"ue calling pmch nr_tti_rx ..\n ");
+
+    LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: Querying for PMCH demodulation\n",
+    ue->Mod_id,(nr_tti_rx==9?-1:0)+frame_rx,nr_tti_rx);
+#if defined(Rel10) || defined(Rel14)
+    /*pmch_mcs = mac_xface->ue_query_mch(ue->Mod_id,
+               CC_id,
+               frame_rx,
+               nr_tti_rx,
+               eNB_id,
+               &sync_area,
+               &mcch_active);*/
+
+#else
+    pmch_mcs=-1;
+#endif
+
+    if (pmch_mcs>=0) {
+      LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: Programming PMCH demodulation for mcs %d\n",ue->Mod_id,frame_rx,nr_tti_rx,pmch_mcs);
+      fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0);
+
+      if (abstraction_flag == 0 ) {
+  for (l=2; l<12; l++) {
+
+    slot_fep_mbsfn(ue,
+       l,
+       nr_tti_rx,
+       0,0);//ue->rx_offset,0);
+  }
+
+  for (l=2; l<12; l++) {
+    rx_pmch(ue,
+      0,
+      nr_tti_rx,
+      l);
+  }
+
+
+  ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms,
+                   ue->dlsch_MCH[0]->harq_processes[0]->nb_rb,
+                   ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
+                   ue->dlsch_MCH[0]->harq_processes[0]->Qm,
+                   1,
+                   2,
+                   frame_rx,
+                   nr_tti_rx,
+                   0);
+
+  dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0],
+         ue->dlsch_MCH[0]->harq_processes[0]->G,
+         ue->pdsch_vars_MCH[0]->llr[0],0,nr_tti_rx<<1);
+
+#ifdef UE_DLSCH_PARALLELISATION
+  ret = dlsch_decoding_mthread(ue,proc, eNB_id,
+             ue->pdsch_vars_MCH[0]->llr[0],
+             &ue->frame_parms,
+             ue->dlsch_MCH[0],
+             ue->dlsch_MCH[0]->harq_processes[0],
+             frame_rx,
+             nr_tti_rx,
+             0,
+             0,1);
+#else
+  ret = dlsch_decoding(ue,
+           ue->pdsch_vars_MCH[0]->llr[0],
+           &ue->frame_parms,
+           ue->dlsch_MCH[0],
+           ue->dlsch_MCH[0]->harq_processes[0],
+           frame_rx,
+           nr_tti_rx,
+           0,
+           0,1);
+  printf("start pmch dlsch decoding\n");
+#endif
+      } else { // abstraction
+#ifdef PHY_ABSTRACTION
+  ret = dlsch_decoding_emul(ue,
+          nr_tti_rx,
+          5, // PMCH
+          eNB_id);
+#endif
+      }
+
+      if (mcch_active == 1)
+  ue->dlsch_mcch_trials[sync_area][0]++;
+      else
+  ue->dlsch_mtch_trials[sync_area][0]++;
+
+      if (ret == (1+ue->dlsch_MCH[0]->max_turbo_iterations)) {
+  if (mcch_active == 1)
+    ue->dlsch_mcch_errors[sync_area][0]++;
+  else
+    ue->dlsch_mtch_errors[sync_area][0]++;
+
+  LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
+        ue->Mod_id,
+              frame_rx,nr_tti_rx,
+        ue->dlsch_mcch_errors[sync_area][0],
+        ue->dlsch_mtch_errors[sync_area][0],
+        ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
+        ue->dlsch_MCH[0]->max_turbo_iterations,
+        ue->dlsch_MCH[0]->harq_processes[0]->G);
+  dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,nr_tti_rx);
+#ifdef DEBUG_DLSCH
+
+  for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) {
+    LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]);
+  }
+
+  LOG_T(PHY,"\n");
+#endif
+
+  if (nr_tti_rx==9)
+    //mac_xface->macphy_exit("Why are we exiting here?");
+      } else { // decoding successful
+#if defined(Rel10) || defined(Rel14)
+
+  if (mcch_active == 1) {
+    /*mac_xface->ue_send_mch_sdu(ue->Mod_id,
+             CC_id,
+             frame_rx,
+             ue->dlsch_MCH[0]->harq_processes[0]->b,
+             ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
+             eNB_id,// not relevant in eMBMS context
+             sync_area);*/
+    ue->dlsch_mcch_received[sync_area][0]++;
+
+
+    if (ue->dlsch_mch_received_sf[nr_tti_rx%5][0] == 1 ) {
+      ue->dlsch_mch_received_sf[nr_tti_rx%5][0]=0;
+    } else {
+      ue->dlsch_mch_received[0]+=1;
+      ue->dlsch_mch_received_sf[nr_tti_rx][0]=1;
+    }
+
+
+  }
+#endif // Rel10 || Rel14
+      } // decoding sucessful
+    } // pmch_mcs>=0
+  } // is_pmch_subframe=true
+}
+
+void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t *current_harq_processes)
+{
+      harq_processes_dest->B              = current_harq_processes->B              ;
+      harq_processes_dest->C              = current_harq_processes->C              ;
+      harq_processes_dest->Cminus         = current_harq_processes->Cminus         ;
+      harq_processes_dest->Cplus          = current_harq_processes->Cplus          ;
+      harq_processes_dest->DCINdi         = current_harq_processes->DCINdi         ;
+      harq_processes_dest->F              = current_harq_processes->F              ;
+      harq_processes_dest->G              = current_harq_processes->G              ;
+      harq_processes_dest->Kminus         = current_harq_processes->Kminus         ;
+      harq_processes_dest->Kplus          = current_harq_processes->Kplus          ;
+      harq_processes_dest->Nl             = current_harq_processes->Nl             ;
+      harq_processes_dest->Qm             = current_harq_processes->Qm             ;
+      harq_processes_dest->TBS            = current_harq_processes->TBS            ;
+      harq_processes_dest->b              = current_harq_processes->b              ;
+      harq_processes_dest->codeword       = current_harq_processes->codeword       ;
+      harq_processes_dest->delta_PUCCH    = current_harq_processes->delta_PUCCH    ;
+      harq_processes_dest->dl_power_off   = current_harq_processes->dl_power_off   ;
+      harq_processes_dest->first_tx       = current_harq_processes->first_tx       ;
+      harq_processes_dest->mcs            = current_harq_processes->mcs            ;
+      harq_processes_dest->mimo_mode      = current_harq_processes->mimo_mode      ;
+      harq_processes_dest->nb_rb          = current_harq_processes->nb_rb          ;
+      harq_processes_dest->pmi_alloc      = current_harq_processes->pmi_alloc      ;
+      harq_processes_dest->rb_alloc_even[0]  = current_harq_processes->rb_alloc_even[0] ;
+      harq_processes_dest->rb_alloc_even[1]  = current_harq_processes->rb_alloc_even[1] ;
+      harq_processes_dest->rb_alloc_even[2]  = current_harq_processes->rb_alloc_even[2] ;
+      harq_processes_dest->rb_alloc_even[3]  = current_harq_processes->rb_alloc_even[3] ;
+      harq_processes_dest->rb_alloc_odd[0]  = current_harq_processes->rb_alloc_odd[0]  ;
+      harq_processes_dest->rb_alloc_odd[1]  = current_harq_processes->rb_alloc_odd[1]  ;
+      harq_processes_dest->rb_alloc_odd[2]  = current_harq_processes->rb_alloc_odd[2]  ;
+      harq_processes_dest->rb_alloc_odd[3]  = current_harq_processes->rb_alloc_odd[3]  ;
+      harq_processes_dest->round          = current_harq_processes->round          ;
+      harq_processes_dest->rvidx          = current_harq_processes->rvidx          ;
+      harq_processes_dest->status         = current_harq_processes->status         ;
+      harq_processes_dest->vrb_type       = current_harq_processes->vrb_type       ;
+}
+
+void copy_ack_struct(nr_harq_status_t *harq_ack_dest, nr_harq_status_t *current_harq_ack)
+{
+    memcpy(harq_ack_dest, current_harq_ack, sizeof(nr_harq_status_t));
+}
+
+void ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1, int s0, int s1, int abstraction_flag) {
+
+  int nr_tti_rx = proc->nr_tti_rx;
+  int m;
+  int harq_pid;
+  int i_mod,eNB_id_i,dual_stream_UE;
+  int first_symbol_flag=0;
+
+  if (dlsch0->active == 0)
+    return;
+
+  for (m=s0;m<=s1;m++) {
+
+    if (dlsch0 && (!dlsch1))  {
+      harq_pid = dlsch0->current_harq_pid;
+      LOG_D(PHY,"[UE %d] PDSCH active in nr_tti_rx %d, harq_pid %d Symbol %d\n",ue->Mod_id,nr_tti_rx,harq_pid,m);
+
+      if ((pdsch==PDSCH) &&
+          (ue->transmission_mode[eNB_id] == 5) &&
+          (dlsch0->harq_processes[harq_pid]->dl_power_off==0) &&
+          (ue->use_ia_receiver ==1)) {
+        dual_stream_UE = 1;
+        eNB_id_i = ue->n_connected_eNB;
+        i_mod =  dlsch0->harq_processes[harq_pid]->Qm;
+
+      }
+      else if((pdsch==PDSCH) && (ue->transmission_mode[eNB_id]==3))
+      {
+          dual_stream_UE = rx_IC_dual_stream;
+          eNB_id_i       = eNB_id;
+          i_mod          = 0;
+      }
+      else {
+        dual_stream_UE = 0;
+        eNB_id_i = eNB_id+1;
+        i_mod = 0;
+      }
+
+      //TM7 UE specific channel estimation here!!!
+      if (ue->transmission_mode[eNB_id]==7) {
+        if (ue->frame_parms.Ncp==0) {
+          if ((m==3) || (m==6) || (m==9) || (m==12))
+            //LOG_D(PHY,"[UE %d] dlsch->active in nr_tti_rx %d => %d, l=%d\n",phy_vars_ue->Mod_id,nr_tti_rx,phy_vars_ue->dlsch_ue[eNB_id][0]->active, l);
+            lte_dl_bf_channel_estimation(ue,eNB_id,0,nr_tti_rx*2+(m>6?1:0),5,m);
+        } else {
+          LOG_E(PHY,"[UE %d]Beamforming channel estimation not supported yet for TM7 extented CP.\n",ue->Mod_id);
+        }
+      }
+
+      if ((m==s0) && (m<4))
+          first_symbol_flag = 1;
+      else
+          first_symbol_flag = 0;
+#if UE_TIMING_TRACE
+      uint8_t slot = 0;
+      if(m >= ue->frame_parms.symbols_per_tti>>1)
+        slot = 1;
+      start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]);
+#endif
+      // process DLSCH received in first slot
+      rx_pdsch(ue,
+	       pdsch,
+	       eNB_id,
+	       eNB_id_i,
+	       proc->frame_rx,
+	       nr_tti_rx,  // nr_tti_rx,
+	       m,
+	       first_symbol_flag,
+	       dual_stream_UE,
+	       i_mod,
+	       dlsch0->current_harq_pid);
+#if UE_TIMING_TRACE
+      stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,nr_tti_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,nr_tti_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+      if(first_symbol_flag)
+      {
+          proc->first_symbol_available = 1;
+      }
+    } // CRNTI active
+  }
+}
+
+void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
+
+  int frame_rx = proc->frame_rx;
+  int nr_tti_rx = proc->nr_tti_rx;
+  int timing_advance;
+  NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[eNB_id];
+  int harq_pid = 0;
+  uint8_t *rar;
+  uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
+
+  LOG_D(PHY,"[UE  %d][RAPROC] Frame %d nr_tti_rx %d Received RAR  mode %d\n",
+  ue->Mod_id,
+  frame_rx,
+  nr_tti_rx, ue->UE_mode[eNB_id]);
+
+
+  if (ue->mac_enabled == 1) {
+    if ((ue->UE_mode[eNB_id] != PUSCH) &&
+  (ue->prach_resources[eNB_id]->Msg3!=NULL)) {
+      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d nr_tti_rx %d Invoking MAC for RAR (current preamble %d)\n",
+	    ue->Mod_id,frame_rx,
+	    nr_tti_rx,
+	    ue->prach_resources[eNB_id]->ra_PreambleIndex);
+      
+/*      timing_advance = mac_xface->ue_process_rar(ue->Mod_id,
+						 ue->CC_id,
+						 frame_rx,
+						 ue->prach_resources[eNB_id]->ra_RNTI,
+						 dlsch0->harq_processes[0]->b,
+						 &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+						 ue->prach_resources[eNB_id]->ra_PreambleIndex,
+						 dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
+*/
+      ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
+      ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
+      
+      if (timing_advance!=0xffff) {
+
+              LOG_D(PHY,"[UE  %d][RAPROC] Frame %d nr_tti_rx %d Got rnti %x and timing advance %d from RAR\n",
+              ue->Mod_id,
+              frame_rx,
+              nr_tti_rx,
+              ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+              timing_advance);
+
+  // remember this c-rnti is still a tc-rnti
+
+  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti_is_temporary = 1;
+	      
+	//timing_advance = 0;
+	nr_process_timing_advance_rar(ue,proc,timing_advance);
+	      
+	if (mode!=debug_prach) {
+	  ue->ulsch_Msg3_active[eNB_id]=1;
+	  nr_get_Msg3_alloc(&ue->frame_parms,
+			 nr_tti_rx,
+			 frame_rx,
+			 &ue->ulsch_Msg3_frame[eNB_id],
+			 &ue->ulsch_Msg3_subframe[eNB_id]);
+	  
+	  LOG_D(PHY,"[UE  %d][RAPROC] Got Msg3_alloc Frame %d nr_tti_rx %d: Msg3_frame %d, Msg3_subframe %d\n",
+		ue->Mod_id,
+		frame_rx,
+		nr_tti_rx,
+		ue->ulsch_Msg3_frame[eNB_id],
+		ue->ulsch_Msg3_subframe[eNB_id]);
+	  harq_pid = nr_subframe2harq_pid(&ue->frame_parms,
+				       ue->ulsch_Msg3_frame[eNB_id],
+				       ue->ulsch_Msg3_subframe[eNB_id]);
+	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
+	  
+	  ue->UE_mode[eNB_id] = RA_RESPONSE;
+	  //      ue->Msg3_timer[eNB_id] = 10;
+	  ue->ulsch[eNB_id]->power_offset = 6;
+	  ue->ulsch_no_allocation_counter[eNB_id] = 0;
+	}
+      } else { // PRACH preamble doesn't match RAR
+  LOG_W(PHY,"[UE  %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n",
+        ue->Mod_id,
+        ue->prach_resources[eNB_id]->ra_PreambleIndex);
+      }
+    } // mode != PUSCH
+  }
+  else {
+    rar = dlsch0->harq_processes[0]->b+1;
+    timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
+    nr_process_timing_advance_rar(ue,proc,timing_advance);
+  }
+
+}
+
+void ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
+       UE_nr_rxtx_proc_t *proc,
+       int eNB_id,
+       PDSCH_t pdsch,
+       NR_UE_DLSCH_t *dlsch0,
+       NR_UE_DLSCH_t *dlsch1,
+       int *dlsch_errors,
+       runmode_t mode,
+       int abstraction_flag) {
+
+  int harq_pid;
+  int frame_rx = proc->frame_rx;
+  int nr_tti_rx = proc->nr_tti_rx;
+  int ret=0, ret1=0;
+  int CC_id = ue->CC_id;
+  NR_UE_PDSCH *pdsch_vars;
+  uint8_t is_cw0_active = 0;
+  uint8_t is_cw1_active = 0;
+
+  if (dlsch0==NULL)
+      AssertFatal(0,"dlsch0 should be defined at this level \n");
+
+  harq_pid = dlsch0->current_harq_pid;
+  is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
+
+  if(dlsch1)
+    is_cw1_active = dlsch1->harq_processes[harq_pid]->status;
+
+  LOG_D(PHY,"AbsSubframe %d.%d Start Turbo Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, nr_tti_rx, harq_pid, is_cw0_active);
+  LOG_D(PHY,"AbsSubframe %d.%d Start Turbo Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, nr_tti_rx, harq_pid, is_cw1_active);
+
+  if(is_cw0_active && is_cw1_active)
+  {
+      dlsch0->Kmimo = 2;
+      dlsch1->Kmimo = 2;
+  }
+  else
+  {
+      dlsch0->Kmimo = 1;
+  }
+  if (1) {
+    switch (pdsch) {
+    case SI_PDSCH:
+      pdsch_vars = ue->pdsch_vars_SI[eNB_id];
+      break;
+    case RA_PDSCH:
+      pdsch_vars = ue->pdsch_vars_ra[eNB_id];
+      break;
+    case P_PDSCH:
+      pdsch_vars = ue->pdsch_vars_p[eNB_id];
+      break;
+    case PDSCH:
+      pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id];
+      break;
+    case PMCH:
+    case PDSCH1:
+      LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch);
+      pdsch_vars = NULL;
+      return;
+      break;
+    default:
+      pdsch_vars = NULL;
+      return;
+      break;
+
+    }
+    if (frame_rx < *dlsch_errors)
+      *dlsch_errors=0;
+
+    if (pdsch==RA_PDSCH) {
+      if (ue->prach_resources[eNB_id]!=NULL)
+  dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+      else {
+  LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,nr_tti_rx);
+  //mac_xface->macphy_exit("prach_resources is NULL");
+  return;
+      }
+    }
+
+    if (abstraction_flag == 0) {
+
+      // start turbo decode for CW 0
+      dlsch0->harq_processes[harq_pid]->G = get_G(&ue->frame_parms,
+						  dlsch0->harq_processes[harq_pid]->nb_rb,
+						  dlsch0->harq_processes[harq_pid]->rb_alloc_even,
+						  dlsch0->harq_processes[harq_pid]->Qm,
+						  dlsch0->harq_processes[harq_pid]->Nl,
+						  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+						  frame_rx,
+						  nr_tti_rx,
+						  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
+#if UE_TIMING_TRACE
+      start_meas(&ue->dlsch_unscrambling_stats);
+#endif
+      dlsch_unscrambling(&ue->frame_parms,
+			 0,
+			 dlsch0,
+			 dlsch0->harq_processes[harq_pid]->G,
+			 pdsch_vars->llr[0],
+			 0,
+			 nr_tti_rx<<1);
+#if UE_TIMING_TRACE
+      stop_meas(&ue->dlsch_unscrambling_stats);
+#endif
+
+#if 0
+      LOG_I(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d  ------  \n", frame_rx, nr_tti_rx, harq_pid);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->Kmimo);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_tti_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols);
+#endif
+
+#if UE_TIMING_TRACE
+      start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]);
+#endif
+
+#ifdef UE_DLSCH_PARALLELISATION
+		 ret = dlsch_decoding_mthread(ue,proc,eNB_id,
+			   pdsch_vars->llr[0],
+			   &ue->frame_parms,
+			   dlsch0,
+			   dlsch0->harq_processes[harq_pid],
+			   frame_rx,
+			   nr_tti_rx,
+			   harq_pid,
+			   pdsch==PDSCH?1:0,
+			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
+#else
+      ret = dlsch_decoding(ue,
+			   pdsch_vars->llr[0],
+			   &ue->frame_parms,
+			   dlsch0,
+			   dlsch0->harq_processes[harq_pid],
+			   frame_rx,
+			   nr_tti_rx,
+			   harq_pid,
+			   pdsch==PDSCH?1:0,//proc->decoder_switch,
+			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
+      //printf("start cW0 dlsch decoding\n");
+#endif
+
+#if UE_TIMING_TRACE
+      stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]);
+#if DISABLE_LOG_X
+      printf(" --> Unscrambling for CW0 %5.3f\n",
+              (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+      printf("AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
+              frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
+#else
+      LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n",
+              (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+      LOG_I(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
+              frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
+#endif
+
+#endif
+      if(is_cw1_active)
+      {
+          // start turbo decode for CW 1
+          dlsch1->harq_processes[harq_pid]->G = get_G(&ue->frame_parms,
+                  dlsch1->harq_processes[harq_pid]->nb_rb,
+                  dlsch1->harq_processes[harq_pid]->rb_alloc_even,
+                  dlsch1->harq_processes[harq_pid]->Qm,
+                  dlsch1->harq_processes[harq_pid]->Nl,
+                  ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+                  frame_rx,
+                  nr_tti_rx,
+                  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
+#if UE_TIMING_TRACE
+          start_meas(&ue->dlsch_unscrambling_stats);
+#endif
+          dlsch_unscrambling(&ue->frame_parms,
+                  0,
+                  dlsch1,
+                  dlsch1->harq_processes[harq_pid]->G,
+                  pdsch_vars->llr[1],
+                  1,
+                  nr_tti_rx<<1);
+#if UE_TIMING_TRACE
+          stop_meas(&ue->dlsch_unscrambling_stats);
+#endif
+
+#if 0
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->Kmimo);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_tti_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols);
+#endif
+
+#if UE_TIMING_TRACE
+          start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]);
+#endif
+
+#ifdef UE_DLSCH_PARALLELISATION
+          ret1 = dlsch_decoding_mthread(ue,proc, eNB_id,
+                            pdsch_vars->llr[1],
+                            &ue->frame_parms,
+                            dlsch1,
+                            dlsch1->harq_processes[harq_pid],
+                            frame_rx,
+                            nr_tti_rx,
+                            harq_pid,
+                            pdsch==PDSCH?1:0,
+                            dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+#else
+
+          ret1 = dlsch_decoding(ue,
+                  pdsch_vars->llr[1],
+                  &ue->frame_parms,
+                  dlsch1,
+                  dlsch1->harq_processes[harq_pid],
+                  frame_rx,
+                  nr_tti_rx,
+                  harq_pid,
+                  pdsch==PDSCH?1:0,//proc->decoder_switch,
+                  dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+          printf("start cw1 dlsch decoding\n");
+#endif
+
+#if UE_TIMING_TRACE
+          stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]);
+#if DISABLE_LOG_X
+          printf(" --> Unscrambling for CW1 %5.3f\n",
+                  (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+          printf("AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
+                  frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
+#else
+          LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n",
+                  (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+          LOG_D(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
+                  frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
+#endif
+
+#endif
+          LOG_I(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
+                  frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
+      }
+
+      LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------  \n", frame_rx, nr_tti_rx);
+    }
+
+    else {
+      LOG_D(PHY,"Calling dlsch_decoding_emul ...\n");
+#ifdef PHY_ABSTRACTION
+      ret = dlsch_decoding_emul(ue,
+        nr_tti_rx,
+        pdsch,
+        eNB_id);
+#endif
+    }
+
+    // Check CRC for CW 0
+    if (ret == (1+dlsch0->max_turbo_iterations)) {
+      *dlsch_errors=*dlsch_errors+1;
+
+      if(dlsch0->rnti != 0xffff)
+      {
+      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n",
+            ue->Mod_id,dlsch0->rnti,
+            harq_pid,frame_rx,nr_tti_rx,
+            dlsch0->harq_processes[harq_pid]->rvidx,
+            dlsch0->harq_processes[harq_pid]->round,
+            dlsch0->harq_processes[harq_pid]->mcs,
+            dlsch0->harq_processes[harq_pid]->TBS);
+      }
+
+
+    } else {
+        if(dlsch0->rnti != 0xffff)
+        {
+      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n",
+            ue->Mod_id,dlsch0->rnti,
+            harq_pid,frame_rx,nr_tti_rx,
+            dlsch0->harq_processes[harq_pid]->rvidx,
+            dlsch0->harq_processes[harq_pid]->round,
+            dlsch0->harq_processes[harq_pid]->mcs,
+            dlsch0->harq_processes[harq_pid]->TBS);
+        }
+
+#ifdef DEBUG_DLSCH
+      int j;
+      LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
+
+      for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
+  LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
+
+      LOG_T(PHY,"\n");
+#endif
+
+
+  switch (pdsch) {
+  case PDSCH:
+      if (ue->mac_enabled == 1) 
+    //mac_xface->ue_send_sdu(ue->Mod_id,
+         CC_id,
+         frame_rx,
+         nr_tti_rx,
+         dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
+         dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3,
+         eNB_id);
+    break;
+  case SI_PDSCH:
+    //mac_xface->ue_decode_si(ue->Mod_id,
+          CC_id,
+          frame_rx,
+          eNB_id,
+          ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
+          ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
+    break;
+  case P_PDSCH:
+      if (ue->mac_enabled == 1) 
+    //mac_xface->ue_decode_p(ue->Mod_id,
+         CC_id,
+         frame_rx,
+         eNB_id,
+         ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
+         ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
+    break;
+  case RA_PDSCH:
+      if (ue->mac_enabled == 1) 
+    process_rar(ue,proc,eNB_id,mode,abstraction_flag);
+    break;
+  case PDSCH1:
+    LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n");
+    AssertFatal(1==0,"exiting");
+    break;
+  case PMCH:
+    LOG_E(PHY,"Shouldn't have PMCH here\n");
+    AssertFatal(1==0,"exiting");
+    break;
+  
+      }
+      ue->total_TBS[eNB_id] =  ue->total_TBS[eNB_id] +
+  dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
+      ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] +
+  dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
+    }
+    // Check CRC for CW 1
+    if(is_cw1_active)
+    {
+        if (ret1 == (1+dlsch0->max_turbo_iterations)) {
+            LOG_I(PHY,"[UE  %d][PDSCH %x/%d] Frame %d nr_tti_rx %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n",
+                    ue->Mod_id,dlsch0->rnti,
+                    harq_pid,frame_rx,nr_tti_rx,
+                    dlsch0->harq_processes[harq_pid]->rvidx,
+                    dlsch0->harq_processes[harq_pid]->mcs,
+                    dlsch0->harq_processes[harq_pid]->TBS);
+
+        } else {
+            LOG_I(PHY,"[UE  %d][PDSCH %x/%d] Frame %d nr_tti_rx %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n",
+                    ue->Mod_id,dlsch0->rnti,
+                    harq_pid,frame_rx,nr_tti_rx,
+                    dlsch0->harq_processes[harq_pid]->rvidx,
+                    dlsch0->harq_processes[harq_pid]->mcs,
+                    dlsch0->harq_processes[harq_pid]->TBS);
+
+
+            if (ue->mac_enabled == 1) {
+                switch (pdsch) {
+                case PDSCH:
+                    if(is_cw1_active)
+                        /*mac_xface->ue_send_sdu(ue->Mod_id,
+                                CC_id,
+                                frame_rx,
+                                nr_tti_rx,
+                                dlsch1->harq_processes[dlsch1->current_harq_pid]->b,
+                                dlsch1->harq_processes[dlsch1->current_harq_pid]->TBS>>3,
+                                eNB_id);*/
+                    break;
+                case SI_PDSCH:
+                case P_PDSCH:
+                case RA_PDSCH:
+                case PDSCH1:
+                case PMCH:
+                    AssertFatal(0,"exiting");
+                    break;
+                }
+            }
+        }
+    }
+
+#ifdef DEBUG_PHY_PROC
+    LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d nr_tti_rx %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n",
+    ue->Mod_id,
+    dlsch0->rnti,harq_pid,
+    frame_rx,nr_tti_rx,ret,
+    dlsch0->harq_processes[harq_pid]->mcs,
+    dlsch0->harq_processes[harq_pid]->rvidx,
+    dlsch0->harq_processes[harq_pid]->TBS);
+
+    if (frame_rx%100==0) {
+      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d nr_tti_rx %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n",
+      ue->Mod_id,dlsch0->rnti,
+      frame_rx,nr_tti_rx,
+      ue->dlsch_errors[eNB_id],
+      ue->dlsch_received[eNB_id],
+      ue->dlsch_fer[eNB_id],
+      ue->measurements.wideband_cqi_tot[eNB_id]);
+    }
+
+#endif
+
+  }
+
+
+}
+
+/*!
+ * \brief This is the UE synchronize thread.
+ * It performs band scanning and synchonization.
+ * \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
+ * \returns a pointer to an int. The storage is not on the heap and must not be freed.
+ */
+#ifdef UE_SLOT_PARALLELISATION
+#define FIFO_PRIORITY   40
+void *UE_thread_slot1_dl_processing(void *arg) {
+
+    static __thread int UE_dl_slot1_processing_retval;
+    struct rx_tx_thread_data *rtd = arg;
+    UE_nr_rxtx_proc_t *proc = rtd->proc;
+    PHY_VARS_NR_UE    *ue   = rtd->UE;
+
+    int frame_rx;
+    uint8_t nr_tti_rx;
+    uint8_t pilot0;
+    uint8_t pilot1;
+    uint8_t slot1;
+
+    uint8_t next_nr_tti_rx;
+    uint8_t next_subframe_slot0;
+
+    proc->instance_cnt_slot1_dl_processing=-1;
+    proc->nr_tti_rx=proc->sub_frame_start;
+
+    char threadname[256];
+    sprintf(threadname,"UE_thread_slot1_dl_processing_%d", proc->sub_frame_start);
+
+    cpu_set_t cpuset;
+    CPU_ZERO(&cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.slot1_proc_one != -1 )
+        CPU_SET(threads.slot1_proc_one, &cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 )
+        CPU_SET(threads.slot1_proc_two, &cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 )
+        CPU_SET(threads.slot1_proc_three, &cpuset);
+
+    init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
+                threadname);
+
+    while (!oai_exit) {
+        if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error locking mutex for UE slot1 dl processing\n" );
+            exit_fun("nothing to add");
+        }
+        while (proc->instance_cnt_slot1_dl_processing < 0) {
+            // most of the time, the thread is waiting here
+            pthread_cond_wait( &proc->cond_slot1_dl_processing, &proc->mutex_slot1_dl_processing );
+        }
+        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE slot1 dl processing \n" );
+            exit_fun("nothing to add");
+        }
+
+        /*for(int th_idx=0; th_idx< RX_NB_TH; th_idx++)
+        {
+        frame_rx    = ue->proc.proc_rxtx[0].frame_rx;
+        nr_tti_rx = ue->proc.proc_rxtx[0].nr_tti_rx;
+        printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, nr_tti_rx);
+        }*/
+        frame_rx    = proc->frame_rx;
+        nr_tti_rx = proc->nr_tti_rx;
+        next_nr_tti_rx    = (1+nr_tti_rx)%10;
+        next_subframe_slot0 = next_nr_tti_rx<<1;
+
+        slot1  = (nr_tti_rx<<1) + 1;
+        pilot0 = 0;
+
+        //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, nr_tti_rx);
+
+        if (ue->frame_parms.Ncp == 0) {  // normal prefix
+            pilot1 = 4;
+        } else { // extended prefix
+            pilot1 = 3;
+        }
+
+        /**** Slot1 FE Processing ****/
+#if UE_TIMING_TRACE
+        start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]);
+#endif
+        // I- start dl slot1 processing
+        // do first symbol of next downlink nr_tti_rx for channel estimation
+        /*
+        // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next nr_tti_rx ofdmSym11)
+        if (nr_subframe_select(&ue->frame_parms,next_nr_tti_rx) != SF_UL)
+        {
+            front_end_fft(ue,
+                    pilot0,
+                    next_subframe_slot0,
+                    0,
+                    0);
+        }
+
+        front_end_fft(ue,
+                pilot1,
+                slot1,
+                0,
+                0);
+         */
+        // 1- perform FFT
+        for (int l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
+        {
+            //if( (l != pilot0) && (l != pilot1))
+            {
+#if UE_TIMING_TRACE
+                start_meas(&ue->ofdm_demod_stats);
+#endif
+                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+                //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot1,l);
+                front_end_fft(ue,
+                        l,
+                        slot1,
+                        0,
+                        0);
+                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+                stop_meas(&ue->ofdm_demod_stats);
+#endif
+            }
+        } // for l=1..l2
+
+        if (nr_subframe_select(&ue->frame_parms,next_nr_tti_rx) != SF_UL)
+        {
+            //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_tti_rx,next_subframe_slot0,pilot0);
+            front_end_fft(ue,
+                    pilot0,
+                    next_subframe_slot0,
+                    0,
+                    0);
+        }
+
+        // 2- perform Channel Estimation for slot1
+        for (int l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
+        {
+            if(l == pilot1)
+            {
+                //wait until channel estimation for pilot0/slot1 is available
+                uint32_t wait = 0;
+                while(proc->chan_est_pilot0_slot1_available == 0)
+                {
+                    usleep(1);
+                    wait++;
+                }
+                //printf("[slot1 dl processing] ChanEst symbol %d slot %d wait%d\n",l,slot1,wait);
+            }
+            //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot1,l);
+            front_end_chanEst(ue,
+                    l,
+                    slot1,
+                    0);
+            ue_measurement_procedures(l-1,ue,proc,0,1+(nr_tti_rx<<1),0,ue->mode);
+        }
+        //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_tti_rx,next_subframe_slot0,pilot0);
+        front_end_chanEst(ue,
+                pilot0,
+                next_subframe_slot0,
+                0);
+
+        if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1))
+        {
+            ue_pbch_procedures(0,ue,proc,0);
+        }
+
+        proc->chan_est_slot1_available = 1;
+        //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,nr_tti_rx);
+        //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_tti_rx);
+
+        //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_tti_rx);
+
+
+#if UE_TIMING_TRACE
+        stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]);
+#if DISABLE_LOG_X
+        printf("[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_tti_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0));
+#else
+        LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_tti_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+    //wait until pdcch is decoded
+    uint32_t wait = 0;
+    while(proc->dci_slot0_available == 0)
+    {
+        usleep(1);
+        wait++;
+    }
+    //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,nr_tti_rx,wait);
+
+
+    /**** Pdsch Procedure Slot1 ****/
+    // start slot1 thread for Pdsch Procedure (slot1)
+    // do procedures for C-RNTI
+    //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,nr_tti_rx);
+
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]);
+#endif
+    // start slave thread for Pdsch Procedure (slot1)
+    // do procedures for C-RNTI
+    uint8_t eNB_id = 0;
+    uint8_t abstraction_flag = 0;
+    if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
+        //wait until first ofdm symbol is processed
+        //wait = 0;
+        //while(proc->first_symbol_available == 0)
+        //{
+        //    usleep(1);
+        //    wait++;
+        //}
+        //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,nr_tti_rx,wait);
+
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                PDSCH,
+                ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0],
+                NULL,
+                (ue->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+        LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+        LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                SI_PDSCH,
+                ue->dlsch_SI[eNB_id],
+                NULL,
+                (ue->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+    }
+
+    // do procedures for P-RNTI
+    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                P_PDSCH,
+                ue->dlsch_p[eNB_id],
+                NULL,
+                (ue->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+    }
+    // do procedures for RA-RNTI
+    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                RA_PDSCH,
+                ue->dlsch_ra[eNB_id],
+                NULL,
+                (ue->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+    }
+
+    proc->llr_slot1_available=1;
+    //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,nr_tti_rx);
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_tti_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_tti_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+        if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
+            exit_fun("noting to add");
+        }
+        proc->instance_cnt_slot1_dl_processing--;
+        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE FEP Slo1\n" );
+            exit_fun("noting to add");
+        }
+    }
+    // thread finished
+        free(arg);
+        return &UE_dl_slot1_processing_retval;
+}
+#endif
+
+#ifdef UE_SLOT_PARALLELISATION
+int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
+        uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,
+        relaying_type_t r_type)  {
+
+    int l,l2;
+    int pmch_flag=0;
+    int frame_rx = proc->frame_rx;
+    int nr_tti_rx = proc->nr_tti_rx;
+    uint8_t pilot0;
+    uint8_t pilot1;
+    uint8_t slot0;
+    uint8_t slot1;
+    uint8_t first_ofdm_sym;
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
+
+#if T_TRACER
+    T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_tti_rx));
+
+    T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_tti_rx), T_INT(0),
+            T_BUFFER(&ue->common_vars.rxdata[0][nr_tti_rx*ue->frame_parms.samples_per_subframe],
+                    ue->frame_parms.samples_per_subframe * 4));
+#endif
+
+    // start timers
+#ifdef UE_DEBUG_TRACE
+    LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, nr_tti_rx);
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]]);
+    start_meas(&ue->ue_front_end_stat[ue->current_thread_id[nr_tti_rx]]);
+#endif
+
+    pmch_flag = is_pmch_subframe(frame_rx,nr_tti_rx,&ue->frame_parms) ? 1 : 0;
+
+    if (do_pdcch_flag) {
+        // deactivate reception until we scan pdcch
+        if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0])
+            ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
+        if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1])
+            ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1]->active = 0;
+
+        if (ue->dlsch_SI[eNB_id])
+            ue->dlsch_SI[eNB_id]->active = 0;
+        if (ue->dlsch_p[eNB_id])
+            ue->dlsch_p[eNB_id]->active = 0;
+        if (ue->dlsch_ra[eNB_id])
+            ue->dlsch_ra[eNB_id]->active = 0;
+    }
+
+#ifdef DEBUG_PHY_PROC
+    LOG_D(PHY,"[%s %d] Frame %d nr_tti_rx %d: Doing phy_procedures_UE_RX\n",
+            (r_type == multicast_relay) ? "RN/UE" : "UE",
+                    ue->Mod_id,frame_rx, nr_tti_rx);
+#endif
+
+
+
+
+    if (nr_subframe_select(&ue->frame_parms,nr_tti_rx) == SF_S) { // S-subframe, do first 5 symbols only
+        l2 = 5;
+    } else if (pmch_flag == 1) { // do first 2 symbols only
+        l2 = 1;
+    } else { // normal nr_tti_rx, last symbol to be processed is the first of the second slot
+        l2 = (ue->frame_parms.symbols_per_tti/2)-1;
+    }
+
+    int prev_nr_tti_rx = (nr_tti_rx - 1)<0? 9: (nr_tti_rx - 1);
+    if (nr_subframe_select(&ue->frame_parms,prev_nr_tti_rx) != SF_DL) {
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        // RX processing of symbols l=0...l2
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        first_ofdm_sym = 0;
+    } else {
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        first_ofdm_sym = 1;
+    }
+    slot0  = (nr_tti_rx<<1);
+    slot1  = (nr_tti_rx<<1) + 1;
+    pilot0 = 0;
+    if (ue->frame_parms.Ncp == 0) {  // normal prefix
+        pilot1 = 4;
+    } else { // extended prefix
+        pilot1 = 3;
+    }
+
+    //LOG_I(PHY,"Set available channelEst to 0 AbsSubframe %d.%d \n",frame_rx,nr_tti_rx);
+    //LOG_I(PHY,"Set available llrs slot1 to 0 AbsSubframe %d.%d \n",frame_rx,nr_tti_rx);
+    //LOG_I(PHY,"Set available dci info slot0 to 0 AbsSubframe %d.%d \n",frame_rx,nr_tti_rx);
+    proc->chan_est_pilot0_slot1_available=0;
+    proc->llr_slot1_available=0;
+    proc->dci_slot0_available=0;
+    proc->first_symbol_available=0;
+    proc->chan_est_slot1_available=0;
+    //proc->channel_level=0;
+
+    if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
+        LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE slot1 dl processing\n",ue->Mod_id );
+        exit_fun("nothing to add");
+    }
+
+    proc->instance_cnt_slot1_dl_processing++;
+    if (proc->instance_cnt_slot1_dl_processing == 0)
+    {
+    LOG_D(PHY,"unblock slot1 dl processing thread blocked on instance_cnt_slot1_dl_processing : %d \n", proc->instance_cnt_slot1_dl_processing );
+        if (pthread_cond_signal(&proc->cond_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE slot1 processing thread\n", ue->Mod_id);
+            exit_fun("nothing to add");
+        }
+        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE slot1 dl processing \n",ue->Mod_id );
+            exit_fun("nothing to add");
+        }
+
+    } else
+    {
+        LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", ue->Mod_id, proc->instance_cnt_slot1_dl_processing);
+        if (proc->instance_cnt_slot1_dl_processing > 2)
+            exit_fun("instance_cnt_slot1_dl_processing > 2");
+    }
+    //AssertFatal(pthread_cond_signal(&proc->cond_slot1_dl_processing) ==0 ,"");
+    AssertFatal(pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) ==0,"");
+
+
+    /**** Slot0 FE Processing ****/
+    // I- start main thread for FFT/ChanEst symbol: 0/1 --> 7
+#if UE_TIMING_TRACE
+    start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][0]);
+#endif
+    // 1- perform FFT for pilot ofdm symbols first (ofdmSym7 ofdmSym4 or (ofdmSym6 ofdmSym3))
+    //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot1,pilot0);
+    front_end_fft(ue,
+            pilot0,
+            slot1,
+            0,
+            0);
+    //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot0,pilot1);
+    front_end_fft(ue,
+            pilot1,
+            slot0,
+            0,
+            0);
+    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot0,pilot1);
+    front_end_chanEst(ue,
+            pilot1,
+            slot0,
+            0);
+    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot1,pilot0);
+    front_end_chanEst(ue,
+            pilot0,
+            slot1,
+            0);
+    proc->chan_est_pilot0_slot1_available = 1;
+    //printf("Set available channelEst to 1 AbsSubframe %d.%d \n",frame_rx,nr_tti_rx);
+
+    // 2- perform FFT for other ofdm symbols other than pilots
+    for (l=first_ofdm_sym; l<=l2; l++)
+    {
+        if( (l != pilot0) && (l != pilot1))
+        {
+            //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot0,l);
+#if UE_TIMING_TRACE
+            start_meas(&ue->ofdm_demod_stats);
+#endif
+            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+            front_end_fft(ue,
+                    l,
+                    slot0,
+                    0,
+                    0);
+            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+            stop_meas(&ue->ofdm_demod_stats);
+#endif
+        }
+    } // for l=1..l2
+
+    // 3- perform Channel Estimation for slot0
+    for (l=first_ofdm_sym; l<=l2; l++)
+    {
+        if( (l != pilot0) && (l != pilot1))
+        {
+            //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot0,l);
+            front_end_chanEst(ue,
+                    l,
+                    slot0,
+                    0);
+        }
+        ue_measurement_procedures(l-1,ue,proc,eNB_id,(nr_tti_rx<<1),abstraction_flag,mode);
+    }
+
+    if (do_pdcch_flag) {
+#if UE_TIMING_TRACE
+        start_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+#endif
+        if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) {
+            LOG_E(PHY,"[UE  %d] Frame %d, nr_tti_rx %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,nr_tti_rx);
+#if UE_TIMING_TRACE
+            stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+#if DISABLE_LOG_X
+            printf("[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,nr_tti_rx,ue->pdcch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#else
+            LOG_D(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,nr_tti_rx,ue->pdcch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+            //proc->dci_slot0_available = 1;
+            return(-1);
+        }
+        //proc->dci_slot0_available=1;
+#if UE_TIMING_TRACE
+        stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+#if DISABLE_LOG_X
+        printf("[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,nr_tti_rx,ue->pdcch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#else
+        LOG_D(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,nr_tti_rx,ue->pdcch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+    }
+
+    //printf("num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols);
+
+    // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
+#if UE_TIMING_TRACE
+    stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][0]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,nr_tti_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][0].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,nr_tti_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][0].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+    //wait until slot1 FE is done
+    uint32_t wait = 0;
+    while(proc->chan_est_slot1_available == 0)
+    {
+        usleep(1);
+        wait++;
+    }
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[nr_tti_rx]]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,nr_tti_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][0].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,nr_tti_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][0].p_time/(cpuf*1000.0));
+#endif
+#endif
+    /**** End nr_tti_rx FE Processing ****/
+
+
+#if 0
+    //Trigger LLR parallelized for Slot 1
+    proc->dci_slot0_available=1;
+    printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,nr_tti_rx);
+#endif
+
+    /**** Pdsch Procedure Slot0 ****/
+    // start main thread for Pdsch Procedure (slot0)
+    // do procedures for C-RNTI
+    //printf("AbsSubframe %d.%d Pdsch Procedure (slot0)\n",frame_rx%1024,nr_tti_rx);
+    //printf("AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,nr_tti_rx, ue->dlsch[ue->current_thread_id[nr_tti_rx]][0][0]->active);
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][0]);
+#endif
+    if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                PDSCH,
+                ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                SI_PDSCH,
+                ue->dlsch_SI[eNB_id],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                P_PDSCH,
+                ue->dlsch_p[eNB_id],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for RA-RNTI
+    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                RA_PDSCH,
+                ue->dlsch_ra[eNB_id],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
+    }
+
+#if 1
+    // LLR linear
+    proc->dci_slot0_available=1;
+    //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,nr_tti_rx);
+#endif
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][0]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,nr_tti_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][0].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,nr_tti_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][0].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+    //wait until LLR Slot1 is done
+    wait = 0;
+    while(proc->llr_slot1_available == 0)
+    {
+        usleep(1);
+        wait++;
+    }
+
+
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,nr_tti_rx,ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,nr_tti_rx,ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+    //printf("[slot0 dl processing] AbsSubframe %d.%d Channel Decoder Start wait %d\n",frame_rx,nr_tti_rx,wait);
+
+
+    //=====================================================================//
+#if UE_TIMING_TRACE
+    start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+#endif
+
+    LOG_D(PHY,"==> Start Turbo Decoder active dlsch %d SI %d RA %d \n",ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active,
+    		ue->dlsch_SI[eNB_id]->active,
+			//ue->dlsch_p[eNB_id]->active,
+			ue->dlsch_ra[eNB_id]->active);
+    // Start Turbo decoder
+    if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+        ue_dlsch_procedures(ue,
+                proc,
+                eNB_id,
+                PDSCH,
+                ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0],
+                ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1],
+                &ue->dlsch_errors[eNB_id],
+                mode,
+                abstraction_flag);
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+        ue_dlsch_procedures(ue,
+                proc,
+                eNB_id,
+                SI_PDSCH,
+                ue->dlsch_SI[eNB_id],
+                NULL,
+                &ue->dlsch_SI_errors[eNB_id],
+                mode,
+                abstraction_flag);
+        ue->dlsch_SI[eNB_id]->active = 0;
+    }
+
+    // do procedures for P-RNTI
+    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+        ue_dlsch_procedures(ue,
+                proc,
+                eNB_id,
+                P_PDSCH,
+                ue->dlsch_p[eNB_id],
+                NULL,
+                &ue->dlsch_p_errors[eNB_id],
+                mode,
+                abstraction_flag);
+        ue->dlsch_p[eNB_id]->active = 0;
+    }
+    // do procedures for RA-RNTI
+    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+        ue_dlsch_procedures(ue,
+                proc,
+                eNB_id,
+                RA_PDSCH,
+                ue->dlsch_ra[eNB_id],
+                NULL,
+                &ue->dlsch_ra_errors[eNB_id],
+                mode,
+                abstraction_flag);
+        ue->dlsch_ra[eNB_id]->active = 0;
+    }
+
+#if UE_TIMING_TRACE
+        stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+#if DISABLE_LOG_X
+        printf("[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,nr_tti_rx,ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#else
+        LOG_D(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,nr_tti_rx,ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#endif
+
+#endif
+
+        // duplicate harq structure
+        uint8_t          current_harq_pid        = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid;
+        NR_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[current_harq_pid];
+        nr_harq_status_t    *current_harq_ack       = &ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_ack[nr_tti_rx];
+
+        // For Debug parallelisation
+        //if (current_harq_ack->ack == 0) {
+            //printf("[slot0 dl processing][End of Channel Decoding] AbsSubframe %d.%d Decode Fail for HarqId%d Round%d\n",frame_rx,nr_tti_rx,current_harq_pid,current_harq_processes->round);
+        //}
+        for(uint8_t rx_th_idx=1; rx_th_idx<RX_NB_TH; rx_th_idx++)
+        {
+            NR_DL_UE_HARQ_t *harq_processes_dest  = ue->dlsch[ue->current_thread_id[(nr_tti_rx+rx_th_idx)%10]][eNB_id][0]->harq_processes[current_harq_pid];
+            nr_harq_status_t    *harq_ack_dest        = &ue->dlsch[ue->current_thread_id[(nr_tti_rx+rx_th_idx)%10]][eNB_id][0]->harq_ack[nr_tti_rx];
+
+            copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
+            copy_ack_struct(harq_ack_dest, current_harq_ack);
+
+        }
+    /*
+    NR_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[(nr_tti_rx+1)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
+    NR_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[(nr_tti_rx+2)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
+
+    nr_harq_status_t *current_harq_ack = &ue->dlsch[nr_tti_rx%RX_NB_TH][eNB_id][0]->harq_ack[nr_tti_rx];
+    nr_harq_status_t *harq_ack_dest    = &ue->dlsch[(nr_tti_rx+1)%RX_NB_TH][eNB_id][0]->harq_ack[nr_tti_rx];
+    nr_harq_status_t *harq_ack_dest1    = &ue->dlsch[(nr_tti_rx+2)%RX_NB_TH][eNB_id][0]->harq_ack[nr_tti_rx];
+
+    copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
+    copy_ack_struct(harq_ack_dest, current_harq_ack);
+
+    copy_harq_proc_struct(harq_processes_dest1, current_harq_processes);
+    copy_ack_struct(harq_ack_dest1, current_harq_ack);
+    */
+    if (nr_tti_rx==9) {
+        if (frame_rx % 10 == 0) {
+            if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
+                ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]);
+
+            ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
+            ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
+        }
+
+
+        ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100;
+        ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id];
+        LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
+                ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
+                ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
+
+#if UE_AUTOTEST_TRACE
+        if ((frame_rx % 100 == 0)) {
+            LOG_I(PHY,"[UE  %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx);
+        }
+#endif
+
+    }
+
+#ifdef EMOS
+    phy_procedures_emos_UE_RX(ue,slot,eNB_id);
+#endif
+
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]]);
+#if DISABLE_LOG_X
+    printf("------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,nr_tti_rx,ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,nr_tti_rx,ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+    LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, nr_tti_rx);
+    return (0);
+}
+#endif
+
+#endif
+
+
+
+
+int phy_procedures_UE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
+			 uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,
+			 relaying_type_t r_type) {
+
+  int l,l2;
+  int pilot1;
+  int pmch_flag=0;
+  int frame_rx = proc->frame_rx;
+  int nr_tti_rx = proc->nr_tti_rx;
+  proc->decoder_switch = 0;
+  //int counter_decoder = 0;
+
+  uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
+
+#if T_TRACER
+  T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_tti_rx));
+
+  T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_tti_rx), T_INT(0),
+    T_BUFFER(&ue->common_vars.rxdata[0][nr_tti_rx*ue->frame_parms.samples_per_subframe],
+             ue->frame_parms.samples_per_subframe * 4));
+#endif
+
+  // start timers
+#ifdef UE_DEBUG_TRACE
+  LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, nr_tti_rx);
+#endif
+
+#if UE_TIMING_TRACE
+  start_meas(&ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]]);
+  start_meas(&ue->generic_stat);
+#endif
+
+  pmch_flag = is_pmch_subframe(frame_rx,nr_tti_rx,&ue->frame_parms) ? 1 : 0;
+
+  if (do_pdcch_flag) {
+  // deactivate reception until we scan pdcch
+  if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0])
+    ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
+  if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1])
+    ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1]->active = 0;
+
+  if (ue->dlsch_SI[eNB_id])
+    ue->dlsch_SI[eNB_id]->active = 0;
+  if (ue->dlsch_p[eNB_id])
+    ue->dlsch_p[eNB_id]->active = 0;
+  if (ue->dlsch_ra[eNB_id])
+    ue->dlsch_ra[eNB_id]->active = 0;
+  }
+
+#ifdef DEBUG_PHY_PROC
+  LOG_D(PHY,"[%s %d] Frame %d nr_tti_rx %d: Doing phy_procedures_UE_RX\n",
+  (r_type == multicast_relay) ? "RN/UE" : "UE",
+  ue->Mod_id,frame_rx, nr_tti_rx);
+#endif
+
+  if (ue->frame_parms.Ncp == 0) {  // normal prefix
+    pilot1 = 4;
+  } else { // extended prefix
+    pilot1 = 3;
+  }
+
+
+  if (nr_subframe_select(&ue->frame_parms,nr_tti_rx) == SF_S) { // S-subframe, do first 5 symbols only
+    l2 = 5;
+  } else if (pmch_flag == 1) { // do first 2 symbols only
+    l2 = 1;
+  } else { // normal nr_tti_rx, last symbol to be processed is the first of the second slot
+    l2 = (ue->frame_parms.symbols_per_tti/2)-1;
+  }
+
+  int prev_nr_tti_rx = (nr_tti_rx - 1)<0? 9: (nr_tti_rx - 1);
+  if (nr_subframe_select(&ue->frame_parms,prev_nr_tti_rx) != SF_DL) {
+    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    // RX processing of symbols l=0...l2
+    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    l=0;
+  } else {
+    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
+    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    l=1;
+  }
+
+  LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+  LOG_D(PHY," ------  --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+
+
+
+  for (; l<=3; l++) {
+    if (abstraction_flag == 0) {
+#if UE_TIMING_TRACE
+        start_meas(&ue->ofdm_demod_stats);
+#endif
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+      slot_fep_pbch(ue,
+         l,
+         (nr_tti_rx<<1),
+         0,
+         0,
+         0);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+      stop_meas(&ue->ofdm_demod_stats);
+#endif
+    }
+
+    //ue_measurement_procedures(l-1,ue,proc,eNB_id,(nr_tti_rx<<1),abstraction_flag,mode);
+
+    if (do_pdcch_flag) {
+//      if ((l==pilot1) || ((pmch_flag==1)&(l==l2)))  {
+//	LOG_D(PHY,"[UE  %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id);
+
+	//start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[nr_tti_rx]]);
+	if (nr_ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) {
+	  LOG_E(PHY,"[UE  %d] Frame %d, nr_tti_rx %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,nr_tti_rx);
+	  return(-1);
+	}
+	//stop_meas(&ue->rx_pdcch_stats[ue->current_thread_id[nr_tti_rx]]);
+    //printf("nr_tti_rx %d n_pdcch_sym %d pdcch procedures  %5.3f \n",
+    //        nr_tti_rx, ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+    //     (ue->rx_pdcch_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
+	LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols);
+//      }
+    }
+
+  } // for l=1..l2
+
+#if 0
+  ue_measurement_procedures(l-1,ue,proc,eNB_id,(nr_tti_rx<<1),abstraction_flag,mode);
+
+  LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+    // If this is PMCH, call procedures and return
+  if (pmch_flag == 1) {
+    ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
+    return 0;
+  }
+
+  slot_fep_pbch(ue,
+     0,
+     1+(nr_tti_rx<<1),
+     0,
+     0,
+     0);
+
+  // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
+#if UE_TIMING_TRACE
+  stop_meas(&ue->generic_stat);
+#if DISABLE_LOG_X
+  printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",nr_tti_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+  LOG_D(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",nr_tti_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
+
+#endif
+
+  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+#if UE_TIMING_TRACE
+  start_meas(&ue->generic_stat);
+#endif
+  // do procedures for C-RNTI
+  if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			PDSCH,
+			ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0],
+			NULL,
+			ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+			ue->frame_parms.symbols_per_tti>>1,
+			abstraction_flag);
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+  }
+
+  LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+  // do procedures for SI-RNTI
+  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
+    ue_pdsch_procedures(ue,
+
+			proc,
+			eNB_id,
+			SI_PDSCH,
+			ue->dlsch_SI[eNB_id],
+			NULL,
+			ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+			ue->frame_parms.symbols_per_tti>>1,
+			abstraction_flag);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
+  }
+
+  // do procedures for SI-RNTI
+  if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			P_PDSCH,
+			ue->dlsch_p[eNB_id],
+			NULL,
+			ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+			ue->frame_parms.symbols_per_tti>>1,
+			abstraction_flag);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
+  }
+
+  // do procedures for RA-RNTI
+  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			RA_PDSCH,
+			ue->dlsch_ra[eNB_id],
+			NULL,
+			ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
+			ue->frame_parms.symbols_per_tti>>1,
+			abstraction_flag);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
+  }
+
+  LOG_D(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+  LOG_D(PHY," ------  --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+
+  if (nr_subframe_select(&ue->frame_parms,nr_tti_rx) != SF_S) {  // do front-end processing for second slot, and first symbol of next nr_tti_rx
+    for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++) {
+      if (abstraction_flag == 0) {
+#if UE_TIMING_TRACE
+          start_meas(&ue->ofdm_demod_stats);
+#endif
+	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+	slot_fep(ue,
+		 l,
+		 1+(nr_tti_rx<<1),
+		 0,
+		 0,
+		 0);
+	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->ofdm_demod_stats);
+#endif
+      }
+
+      ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(nr_tti_rx<<1),abstraction_flag,mode);
+
+    } // for l=1..l2
+
+    // do first symbol of next downlink nr_tti_rx for channel estimation
+    int next_nr_tti_rx = (1+nr_tti_rx)%10;
+    if (nr_subframe_select(&ue->frame_parms,next_nr_tti_rx) != SF_UL)
+    {
+      slot_fep(ue,
+         0,
+         (next_nr_tti_rx<<1),
+         0,
+         0,
+         0);
+    }
+  } // not an S-subframe
+#if UE_TIMING_TRACE
+  stop_meas(&ue->generic_stat);
+#if DISABLE_LOG_X
+  printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",nr_tti_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+  LOG_D(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",nr_tti_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
+
+#endif
+
+  LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+
+  if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1))
+  {
+    ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
+  }
+
+
+
+  // do procedures for C-RNTI
+  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+  if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
+	/*proc->counter_decoder++;
+	printf("counter decoder %d\n", proc->counter_decoder);
+	if (proc->counter_decoder > 6)
+		{
+			proc->decoder_switch = 1;
+			printf("switch to LDPC\n");
+		}*/
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+#endif
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			PDSCH,
+			ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0],
+			NULL,
+			1+(ue->frame_parms.symbols_per_tti>>1),
+			ue->frame_parms.symbols_per_tti-1,
+			abstraction_flag);
+    LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+    LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_tti_rx);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+    start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+#endif
+    ue_dlsch_procedures(ue,
+			proc,
+			eNB_id,
+			PDSCH,
+			ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0],
+			ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1],
+			&ue->dlsch_errors[eNB_id],
+			mode,
+			abstraction_flag);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+#if DISABLE_LOG_X
+    printf("[SFN %d] Slot1:       Pdsch Proc %5.2f\n",nr_tti_rx,ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+    printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_tti_rx,ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[SFN %d] Slot1:       Pdsch Proc %5.2f\n",nr_tti_rx,ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+    LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_tti_rx,ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#endif
+
+#endif
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+
+  }
+#if UE_TIMING_TRACE
+  start_meas(&ue->generic_stat);
+#endif
+
+#if 0
+  if(nr_tti_rx==5 &&  ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20){
+       //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
+       //write_output("llr.m","llr",  &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
+
+       write_output("rxdataF0_current.m"    , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+
+       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+
+       write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+       write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
+       write_output("rxdataF_comp00.m","rxdataF_comp00",         &ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
+       //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1);
+       //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1);
+
+       AssertFatal (0,"");
+  }
+#endif
+
+  // do procedures for SI-RNTI
+  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+    ue_pdsch_procedures(ue,
+      proc,
+      eNB_id,
+      SI_PDSCH,
+      ue->dlsch_SI[eNB_id],
+      NULL,
+      1+(ue->frame_parms.symbols_per_tti>>1),
+      ue->frame_parms.symbols_per_tti-1,
+      abstraction_flag);
+
+    ue_dlsch_procedures(ue,
+      proc,
+      eNB_id,
+      SI_PDSCH,
+      ue->dlsch_SI[eNB_id],
+      NULL,
+      &ue->dlsch_SI_errors[eNB_id],
+      mode,
+      abstraction_flag);
+    ue->dlsch_SI[eNB_id]->active = 0;
+  }
+
+  // do procedures for P-RNTI
+  if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+    ue_pdsch_procedures(ue,
+      proc,
+      eNB_id,
+      P_PDSCH,
+      ue->dlsch_p[eNB_id],
+      NULL,
+      1+(ue->frame_parms.symbols_per_tti>>1),
+      ue->frame_parms.symbols_per_tti-1,
+      abstraction_flag);
+
+    ue_dlsch_procedures(ue,
+      proc,
+      eNB_id,
+      P_PDSCH,
+      ue->dlsch_p[eNB_id],
+      NULL,
+      &ue->dlsch_p_errors[eNB_id],
+      mode,
+      abstraction_flag);
+    ue->dlsch_p[eNB_id]->active = 0;
+  }
+  // do procedures for RA-RNTI
+  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+    ue_pdsch_procedures(ue,
+      proc,
+      eNB_id,
+      RA_PDSCH,
+      ue->dlsch_ra[eNB_id],
+      NULL,
+      1+(ue->frame_parms.symbols_per_tti>>1),
+      ue->frame_parms.symbols_per_tti-1,
+      abstraction_flag);
+    ue_dlsch_procedures(ue,
+      proc,
+      eNB_id,
+      RA_PDSCH,
+      ue->dlsch_ra[eNB_id],
+      NULL,
+      &ue->dlsch_ra_errors[eNB_id],
+      mode,
+      abstraction_flag);
+    ue->dlsch_ra[eNB_id]->active = 0;
+  }
+
+  // duplicate harq structure
+
+  uint8_t          current_harq_pid        = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid;
+  NR_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[current_harq_pid];
+  NR_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[next1_thread_id][eNB_id][0]->harq_processes[current_harq_pid];
+  NR_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[next2_thread_id][eNB_id][0]->harq_processes[current_harq_pid];
+
+  nr_harq_status_t *current_harq_ack = &ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_ack[nr_tti_rx];
+  nr_harq_status_t *harq_ack_dest    = &ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack[nr_tti_rx];
+  nr_harq_status_t *harq_ack_dest1    = &ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack[nr_tti_rx];
+
+  copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
+  copy_ack_struct(harq_ack_dest, current_harq_ack);
+
+  copy_harq_proc_struct(harq_processes_dest1, current_harq_processes);
+  copy_ack_struct(harq_ack_dest1, current_harq_ack);
+
+  if (nr_tti_rx==9) {
+    if (frame_rx % 10 == 0) {
+      if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
+  ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]);
+
+      ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
+      ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
+    }
+
+
+    ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100;
+    ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id];
+    LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
+    ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
+    ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
+
+  #if UE_AUTOTEST_TRACE
+    if ((frame_rx % 100 == 0)) {
+      LOG_I(PHY,"[UE  %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx);
+    }
+  #endif
+
+  }
+
+#if UE_TIMING_TRACE
+  stop_meas(&ue->generic_stat);
+  printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
+
+#ifdef EMOS
+  phy_procedures_emos_UE_RX(ue,slot,eNB_id);
+#endif
+
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
+
+#if UE_TIMING_TRACE
+  stop_meas(&ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]]);
+#if DISABLE_LOG_X
+  printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_tti_rx,ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#else
+  LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_tti_rx,ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+#endif
+
+  LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, nr_tti_rx);
+  return (0);
+}
+
+
+#if 0
+#if defined(Rel10) || defined(Rel14)
+
+int phy_procedures_RN_UE_RX(uint8_t slot_rx, uint8_t next_slot, relaying_type_t r_type)
+{
+
+  int do_proc =0; // do nothing by default
+
+  switch(r_type) {
+  case no_relay:
+    do_proc=no_relay; // perform the normal UE operation
+    break;
+
+  case multicast_relay:
+    if (slot_rx > 12)
+      do_proc = 0; // do nothing
+    else // SF#1, SF#2, SF3, SF#3, SF#4, SF#5, SF#6(do rx slot 12)
+      do_proc = multicast_relay ; // do PHY procedures UE RX
+
+    break;
+
+  default: // should'not be here
+    LOG_W(PHY,"Not supported relay type %d, do nothing \n", r_type);
+    do_proc= 0;
+    break;
+  }
+
+  return do_proc;
+}
+#endif
+
+void phy_procedures_UE_lte(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,
+			   relaying_type_t r_type)
+{
+#if defined(ENABLE_ITTI)
+  MessageDef   *msg_p;
+  const char   *msg_name;
+  instance_t    instance;
+  unsigned int  Mod_id;
+  int           result;
+#endif
+
+  int           frame_rx = proc->frame_rx;
+  int           frame_tx = proc->frame_tx;
+  int           nr_tti_rx = proc->nr_tti_rx;
+  int           nr_tti_tx = proc->nr_tti_tx;
+//#ifdef UE_NR_PHY_DEMO
+//  int           nr_tti_rx = proc->nr_tti_rx;
+//  int           nr_tti_tx = proc->nr_tti_tx;
+//#endif
+
+#undef DEBUG_PHY_PROC
+
+  UE_L2_STATE_t ret;
+  int slot;
+
+  if (ue->mac_enabled == 0) {
+    ue->UE_mode[eNB_id]=PUSCH;
+  }
+
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1);
+#if UE_TIMING_TRACE
+  start_meas(&ue->phy_proc[ue->current_thread_id[nr_tti_rx]]);
+#endif
+#if defined(ENABLE_ITTI)
+
+  do {
+    // Checks if a message has been sent to PHY sub-task
+    itti_poll_msg (TASK_PHY_UE, &msg_p);
+
+    if (msg_p != NULL) {
+      msg_name = ITTI_MSG_NAME (msg_p);
+      instance = ITTI_MSG_INSTANCE (msg_p);
+      Mod_id = instance - NB_eNB_INST;
+
+      switch (ITTI_MSG_ID(msg_p)) {
+      case PHY_FIND_CELL_REQ:
+  LOG_I(PHY, "[UE %d] Received %s\n", Mod_id, msg_name);
+
+  /* TODO process the message */
+  break;
+
+      default:
+  LOG_E(PHY, "[UE %d] Received unexpected message %s\n", Mod_id, msg_name);
+  break;
+      }
+
+      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
+      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+    }
+  } while(msg_p != NULL);
+
+#endif
+
+  for (slot=0;slot<2;slot++) {
+
+    if ((nr_subframe_select(&ue->frame_parms,nr_tti_tx)==SF_UL)||
+  (ue->frame_parms.frame_type == FDD)) {
+      phy_procedures_UE_TX(ue,proc,eNB_id,abstraction_flag,mode,r_type);
+    }
+
+    if ((nr_subframe_select(&ue->frame_parms,nr_tti_rx)==SF_DL) ||
+  (ue->frame_parms.frame_type == FDD)) {
+#if defined(Rel10) || defined(Rel14)
+
+      if (phy_procedures_RN_UE_RX(nr_tti_rx, nr_tti_tx, r_type) != 0 )
+#endif
+	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode,r_type);
+    }
+
+    if ((nr_subframe_select(&ue->frame_parms,nr_tti_tx)==SF_S) &&
+  (slot==1)) {
+      phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag,r_type);
+    }
+
+    if ((nr_subframe_select(&ue->frame_parms,nr_tti_rx)==SF_S) &&
+  (slot==0)) {
+#if defined(Rel10) || defined(Rel14)
+
+      if (phy_procedures_RN_UE_RX(nr_tti_rx, nr_tti_tx, r_type) != 0 )
+#endif
+	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode,r_type);
+    }
+
+    if (ue->mac_enabled==1) {
+      if (slot==0) {
+//#ifdef UE_NR_PHY_DEMO
+        ret = mac_xface->ue_scheduler(ue->Mod_id,
+            frame_rx,
+            proc->subframe_rx,
+            nr_tti_rx%(ue->frame_parms.ttis_per_subframe),
+            frame_tx,
+            proc->subframe_tx,
+            nr_tti_tx%(ue->frame_parms.ttis_per_subframe),
+            nr_subframe_select(&ue->frame_parms,nr_tti_tx),
+            eNB_id,
+            0/*FIXME CC_id*/);
+//#else
+/*        ret = mac_xface->ue_scheduler(ue->Mod_id,
+            frame_rx,
+            nr_tti_rx,
+            frame_tx,
+            nr_tti_tx,
+            nr_subframe_select(&ue->frame_parms,nr_tti_tx),
+            eNB_id,*/
+//            0/*FIXME CC_id*/);
+//#endif
+
+  if (ret == CONNECTION_LOST) {
+    LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d RRC Connection lost, returning to PRACH\n",ue->Mod_id,
+    frame_rx,nr_tti_tx);
+    ue->UE_mode[eNB_id] = PRACH;
+    //      mac_xface->macphy_exit("Connection lost");
+  } else if (ret == PHY_RESYNCH) {
+    LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d RRC Connection lost, trying to resynch\n",
+    ue->Mod_id,
+    frame_rx,nr_tti_tx);
+    ue->UE_mode[eNB_id] = RESYNCH;
+    //     mac_xface->macphy_exit("Connection lost");
+  } else if (ret == PHY_HO_PRACH) {
+    LOG_I(PHY,"[UE %d] Frame %d, nr_tti_rx %d, return to PRACH and perform a contention-free access\n",
+    ue->Mod_id,frame_rx,nr_tti_tx);
+    ue->UE_mode[eNB_id] = PRACH;
+  }
+      }
+    }
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->phy_proc[ue->current_thread_id[nr_tti_rx]]);
+#endif
+  } // slot
+}
+#endif
+
diff --git a/openair2/LAYER2/NR_MAC_UE/extern.h b/openair2/LAYER2/NR_MAC_UE/extern.h
new file mode 100644
index 0000000000000000000000000000000000000000..abe787b2b0e864dfa4548f9617f63cd2123a67cf
--- /dev/null
+++ b/openair2/LAYER2/NR_MAC_UE/extern.h
@@ -0,0 +1,125 @@
+/*
+ * 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.1  (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 extern.h
+* \brief mac externs
+* \author  Navid Nikaein and Raymond Knopp
+* \date 2010 - 2014
+* \version 1.0
+* \email navid.nikaein@eurecom.fr
+* @ingroup _mac
+
+*/
+
+#ifndef __MAC_EXTERN_H__
+#define __MAC_EXTERN_H__
+
+
+#ifdef USER_MODE
+//#include "stdio.h"
+#endif //USER_MODE
+//#include "PHY/defs.h"
+#include "PHY/defs_nr_UE.h"
+#include "defs.h"
+#include "COMMON/mac_rrc_primitives.h"
+#ifdef PHY_EMUL
+//#include "SIMULATION/simulation_defs.h"
+#endif //PHY_EMUL
+//#include "PHY_INTERFACE/defs.h"
+//#include "RRC/LITE/defs.h"
+
+extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
+//extern uint32_t EBSR_Level[63];
+extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
+//extern uint32_t Extended_BSR_TABLE[63];  ----currently not used 
+
+extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
+
+extern const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
+
+extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
+
+extern UE_MAC_INST *UE_mac_inst;
+extern eNB_MAC_INST *eNB_mac_inst;
+extern eNB_RRC_INST *eNB_rrc_inst;
+extern UE_RRC_INST *UE_rrc_inst;
+extern UE_MAC_INST *ue_mac_inst;
+extern MAC_RLC_XFACE *Mac_rlc_xface;
+extern uint8_t Is_rrc_registered;
+
+extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
+extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
+
+
+
+//#ifndef USER_MODE
+//extern MAC_xface *mac_xface;
+extern RRC_XFACE *Rrc_xface;
+
+extern uint8_t Is_rrc_registered;
+
+#ifndef PHY_EMUL
+#ifndef PHYSIM
+#define NB_INST 1
+#else
+extern unsigned char NB_INST;
+#endif
+extern unsigned char NB_eNB_INST;
+extern unsigned char NB_UE_INST;
+extern unsigned char NB_RN_INST;
+extern unsigned short NODE_ID[1];
+extern void* bigphys_malloc(int);
+#else
+extern EMULATION_VARS *Emul_vars;
+#endif //PHY_EMUL
+
+
+extern int cqi_to_mcs[16];
+
+extern uint32_t RRC_CONNECTION_FLAG;
+
+extern uint8_t rb_table[33];
+
+extern DCI0_5MHz_TDD_1_6_t       UL_alloc_pdu;
+
+extern DCI1A_5MHz_TDD_1_6_t      RA_alloc_pdu;
+extern DCI1A_5MHz_TDD_1_6_t      DLSCH_alloc_pdu1A;
+extern DCI1A_5MHz_TDD_1_6_t      BCCH_alloc_pdu;
+
+extern DCI1A_5MHz_TDD_1_6_t      CCCH_alloc_pdu;
+extern DCI1_5MHz_TDD_t           DLSCH_alloc_pdu;
+
+extern DCI0_5MHz_FDD_t       UL_alloc_pdu_fdd;
+
+extern DCI1A_5MHz_FDD_t      DLSCH_alloc_pdu1A_fdd;
+extern DCI1A_5MHz_FDD_t      RA_alloc_pdu_fdd;
+extern DCI1A_5MHz_FDD_t      BCCH_alloc_pdu_fdd;
+
+extern DCI1A_5MHz_FDD_t      CCCH_alloc_pdu_fdd;
+extern DCI1_5MHz_FDD_t       DLSCH_alloc_pdu_fdd;
+
+extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1;
+extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
+extern DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
+
+#endif //DEF_H
+
+
diff --git a/openair2/LAYER2/NR_MAC_UE/vars.h b/openair2/LAYER2/NR_MAC_UE/vars.h
new file mode 100644
index 0000000000000000000000000000000000000000..56a4ccba9dab649b8a40609850adb1ced1f0e1ab
--- /dev/null
+++ b/openair2/LAYER2/NR_MAC_UE/vars.h
@@ -0,0 +1,155 @@
+/*
+ * 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.1  (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 vars.h
+* \brief mac vars
+* \author  Navid Nikaein and Raymond Knopp
+* \date 2010 - 2014
+* \version 1.0
+* \email navid.nikaein@eurecom.fr
+* @ingroup _mac
+
+*/
+
+
+#ifndef __MAC_VARS_H__
+#define __MAC_VARS_H__
+#ifdef USER_MODE
+//#include "stdio.h"
+#endif //USER_MODE
+#include "PHY/defs.h"
+#include "defs.h"
+#include "PHY_INTERFACE/defs.h"
+#include "COMMON/mac_rrc_primitives.h"
+
+const uint32_t BSR_TABLE[BSR_TABLE_SIZE]= {0,10,12,14,17,19,22,26,31,36,42,49,57,67,78,91,
+                                           105,125,146,171,200,234,274,321,376,440,515,603,706,826,967,1132,
+                                           1326,1552,1817,2127,2490,2915,3413,3995,4677,5467,6411,7505,8787,10287,12043,14099,
+                                           16507,19325,22624,26487,31009,36304,42502,49759,58255,68201,79846,93479,109439, 128125,150000, 300000
+                                          };
+// extended bsr table--currently not used										  
+const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] = {0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,
+                                                     181,223,274,337,414,509,625,769,945,1162,1429,
+                                                     1757,2161,2657,3267,4017,4940,6074,7469,9185,
+                                                     11294,13888,17077,20999,25822,31752,39045,48012,
+                                                     59039,72598,89272,109774,134986,165989,204111,
+                                                     250990,308634,379519,466683,573866,705666,867737,
+                                                     1067031,1312097,1613447,1984009,2439678,3000000,
+                                                     6000000};
+
+//#define MAX_SIZE_OF_AGG3   576 
+//#define MAX_SIZE_OF_AGG2   288
+//#define MAX_SIZE_OF_AGG1   144
+//#define MAX_SIZE_OF_AGG0   72
+
+/*
+ * If the CQI is low, then scheduler will use a higher aggregation level and lower aggregation level otherwise
+ * this is also dependent to transmission mode, where an offset could be defined
+ */
+// the follwoing three tables are calibrated for TXMODE 1 and 2
+const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= { 
+  {3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size= 37 bits
+  //{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 41
+  {3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 41
+  {3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 43
+  {3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0}   // 20_DCI0_CRC_SIZE = 44
+};
+const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= { 
+  {3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size < 38 bits
+  {3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE  < 43
+  {3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE  < 47
+  {3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0}   // 20_DCI0_CRC_SIZE  < 55
+};
+const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= { 
+  {3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size= 47 bits
+  {3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 55
+  {3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 59
+  {3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0}   // 20_DCI0_CRC_SIZE = 64
+};
+
+//uint32_t EBSR_Level[63]={0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181};
+
+MAC_xface *mac_xface;
+
+uint32_t RRC_CONNECTION_FLAG;
+
+UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX];
+eNB_MAC_INST *eNB_mac_inst; //[NB_MODULE_MAX];
+MAC_RLC_XFACE *Mac_rlc_xface;
+
+/// Primary component carrier index of eNB
+int pCC_id[NUMBER_OF_eNB_MAX];
+
+
+
+eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
+eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
+
+/*
+#ifndef USER_MODE
+RRC_XFACE *Rrc_xface;
+MAC_xface *mac_xface;
+#else
+#include "PHY_INTERFACE/extern.h"
+#include "RRC/LITE/extern.h"
+#endif
+*/
+
+uint8_t Is_rrc_registered;
+
+#ifdef OPENAIR2
+unsigned char NB_eNB_INST=0;
+unsigned char NB_UE_INST=0;
+unsigned char NB_RN_INST=0;
+unsigned char NB_INST=0;
+#endif
+
+
+DCI0_5MHz_TDD_1_6_t       UL_alloc_pdu;
+
+DCI1A_5MHz_TDD_1_6_t      DLSCH_alloc_pdu1A;
+DCI1A_5MHz_TDD_1_6_t      RA_alloc_pdu;
+DCI1A_5MHz_TDD_1_6_t      BCCH_alloc_pdu;
+
+DCI1A_5MHz_TDD_1_6_t      CCCH_alloc_pdu;
+DCI1_5MHz_TDD_t           DLSCH_alloc_pdu;
+
+#if defined(Rel10) || defined(Rel14)
+DCI1C_5MHz_t                 MCCH_alloc_pdu;
+#endif
+
+DCI0_5MHz_FDD_t       UL_alloc_pdu_fdd;
+
+DCI1A_5MHz_FDD_t      DLSCH_alloc_pdu1A_fdd;
+DCI1A_5MHz_FDD_t      RA_alloc_pdu_fdd;
+DCI1A_5MHz_FDD_t      BCCH_alloc_pdu_fdd;
+
+DCI1A_5MHz_FDD_t      CCCH_alloc_pdu_fdd;
+DCI1_5MHz_FDD_t       DLSCH_alloc_pdu_fdd;
+
+DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1;
+DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
+
+DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
+
+#endif
+
+
diff --git a/targets/RT/USER/nr-softmodem.h b/targets/RT/USER/nr-softmodem.h
index 5a85e6deaf6809f796fdefb8a4901221c8afd243..13ac6dc329ff43dd786fc09ab9a423f61b2578af 100644
--- a/targets/RT/USER/nr-softmodem.h
+++ b/targets/RT/USER/nr-softmodem.h
@@ -30,6 +30,7 @@
 #include "PHY/types.h"
 
 #include "flexran_agent.h"
+#include "PHY/defs_gNB.h"
 
 #if defined(ENABLE_ITTI)
 #if defined(ENABLE_USE_MME)