diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 29257e482f3fb745ff2fc2a3907db196191c3de8..3472b14efcf09695f156d57ee6cbd69cc89ff1b3 100755
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1101,7 +1101,9 @@
                                  (Test16: 11 PTRS, 0 Interpolated Symbols),
                                  (Test17: Mapping type A, 2 DMRS Symbols),
                                  (Test18: Mapping type A, 3 DMRS Symbols),
-                                 (Test19: Mapping type B, 4 DMRS Symbols)</desc>
+                                 (Test19: Mapping type B, 4 DMRS Symbols),
+                                 (Test20: 4x4 MIMO, 1 Layer),
+                                 (Test21: 4x4 MIMO, 2 Layers)</desc>
       <pre_compile_prog></pre_compile_prog>
       <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
       <compile_prog_args> --phy_simulators  -c </compile_prog_args>
@@ -1126,8 +1128,10 @@
                   -n100 -s5 -T 2 0 4
                   -n100 -s2 -U 2 0 1
                   -n100 -s2 -U 2 0 2
-                  -n100 -s2 -U 2 1 3</main_exec_args>
-      <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19</tags>
+                  -n100 -s2 -U 2 1 3
+                  -n10 -s20 -U 3 0 0 2 -gR -x1 -y4 -z4
+                  -n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4</main_exec_args>
+      <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21</tags>
       <search_expr_true>PDSCH test OK</search_expr_true>
       <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
       <nruns>3</nruns>
@@ -1314,11 +1318,11 @@
                       -n100 -s5 -T 2 1 2 -U 2 0 2
                       -n100 -s5 -T 2 2 2 -U 2 1 2
                       -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3
-                      -n100 -s2 -Z
-                      -n100 -s2 -Z -r75
-                      -n100 -s2 -Z -r216 -R217
-                      -n100 -s2 -Z -r270 -R273
-                      -n100 -s2 -Z -U 2 0 2
+                      -n100 -s5 -Z
+                      -n100 -s5 -Z -r75
+                      -n50 -s5 -Z -r216 -R217
+                      -n50 -s5 -Z -r270 -R273
+                      -n100 -s5 -Z -U 2 0 2
                       -n100 -m16 -s10 -z2</main_exec_args>
 
       <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15</tags>
diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md
index 2171fc2f1fd567a655701ea92fa468d9f7c43919..7c202dc52de2c52aefdb53edebb4872b9674266e 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -257,7 +257,7 @@ The following features are valid for the gNB and the 5G-NR UE.
 *  FDD
 *  Normal CP
 *  30 kHz subcarrier spacing
-*  Bandwidths up to 80MHz (217 Physical Resource Blocks)
+*  Bandwidths: 10, 20, 40, 80, 100MHz (273 Physical Resource Blocks)
 *  Intermediate downlink and uplink frequencies to interface with IF equipment
 *  Single antenna port (single beam)
 *  Slot format: 14 OFDM symbols in UL or DL
@@ -277,10 +277,20 @@ The following features are valid for the gNB and the 5G-NR UE.
    - user-specific search space configured by RRC
    - DCI formats: 00, 10 (01 and 11 **under integration**)
 *  Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
-   - Single symbol DMRS, DMRS-TypeA-Position Pos2,  DMRS configuration type 1
-   - PDSCH mapping type A
+   - PDSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1, 2 and 4 TX antennas
+   - Support for up to 2 layers (currently limited to DMRS configuration type 2)
 *  NR-CSI Generation of sequence at PHY (**under integration**)
 *  NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
+   - PUSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1 RX antenna
+   - Support for 1 layer
 *  NR-PUCCH 
    - Format 0 (2 bits, mainly for ACK/NACK)
    - Format 2 (up to 64 bits, mainly for CSI feedback)
@@ -320,27 +330,33 @@ The following features are valid for the gNB and the 5G-NR UE.
 - Creates TUN interface to PDCP to inject and receive user-place traffic
 - Will only work with OAI gNB configured in the same mode
 
-##  UE PHY Layer ##
+##  NR UE PHY Layer ##
 
 *  Initial synchronization
 *  Time tracking based on PBCH DMRS
-*  Time tracking based on PBCH DMRS
 *  Frequency offset estimation
-*  PBCH RX
-*  PDCCH RX
-*  PDSCH RX, including a first version of dual stream receiver for PDSCH  
 *  30KHz SCS for FR1 and 120 KHz SCS for FR2
-*  Generation of NR-PSS/NR-SSS
+*  Reception of NR-PSS/NR-SSS
 *  NR-PBCH supports multiple SSBs and flexible periodicity
-*  Generation of NR-PDCCH for SIB1 (including generation of DCI, polar encoding, scrambling, modulation, RB mapping, etc)
+*  Reception of NR-PDCCH for SIB1 (including reception of DCI, polar decoding, de-scrambling, de-modulation, RB de-mapping, etc)
    - common search space configured by MIB
    - user-specific search space configured by RRC
    - DCI formats: 00, 10 (01 and 11 **under integration**)
-*  Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
-   - Single symbol DMRS, DMRS-TypeA-Position Pos2,  DMRS configuration type 1
-   - PDSCH mapping type A
+*  Reception of NR-PDSCH (including Segmentation, LDPC decoding, rate de-matching, de-scrambling, de-modulation, RB de-mapping, etc).
+   - PDSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1, 2 and 4 RX antennas
+   - Support for up to 2 layers (currently limited to DMRS configuration type 2)
 *  NR-CSI Generation of sequence at PHY (**under integration**)
 *  NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
+   - PUSCH mapping type A and B
+   - DMRS configuration type 1 and 2
+   - Single and multiple DMRS symbols
+   - PTRS support
+   - Support for 1 TX antenna
+   - Support for 1 layer
 *  NR-PUCCH 
    - Format 0 (2 bits, mainly for ACK/NACK)
    - Format 2 (up to 64 bits, mainly for CSI feedback)
@@ -351,7 +367,7 @@ The following features are valid for the gNB and the 5G-NR UE.
 *  Encoder and decoder for short block
 
 
-## UE Higher Layers ##
+## NR UE Higher Layers ##
 
 **UE MAC**
 *  Minimum system information (MSI)
diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h
index 813ffcf8fac29f3060f72dbe74057fb8cb03755a..00f786dfdcfd6d0459a47357431a1595bc4c7e59 100644
--- a/executables/nr-softmodem-common.h
+++ b/executables/nr-softmodem-common.h
@@ -69,6 +69,7 @@
 #define CONFIG_HLP_EXMCAL        "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
 #define CONFIG_HLP_ITTIL         "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
 #define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n"
+#define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n"
 #define CONFIG_HLP_STMON         "Enable processing timing measurement of lte softmodem on per subframe basis \n"
 #define CONFIG_HLP_PRB           "Set the PRB, valid values: 6, 25, 50, 100  \n"
 #define CONFIG_HLP_MSLOTS        "Skip the missed slots/subframes \n"
diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h
index 928558013c8e6bd3dbc6bbfc4fdecbdadb5b7a43..896c363cbf15ed17d06d6ea242d8c912f9e9b4a1 100644
--- a/executables/nr-softmodem.h
+++ b/executables/nr-softmodem.h
@@ -22,6 +22,7 @@
     {"A" ,                    CONFIG_HLP_TADV,        0,                uptr:&timing_advance,               defintval:0,                   TYPE_UINT,   0},        \
     {"E" ,                    CONFIG_HLP_TQFS,        PARAMFLAG_BOOL,   i8ptr:&threequarter_fs,             defintval:0,                   TYPE_INT8,   0},        \
     {"m" ,                    CONFIG_HLP_DLMCS_PHYTEST,0,               uptr:&target_dl_mcs,                defintval:0,                   TYPE_UINT,   0},        \
+    {"l" ,                    CONFIG_HLP_DLNL_PHYTEST,0,                uptr:&target_dl_Nl,                 defintval:0,                   TYPE_UINT,   0},        \
     {"t" ,                    CONFIG_HLP_ULMCS_PHYTEST,0,               uptr:&target_ul_mcs,                defintval:0,                   TYPE_UINT,   0},        \
     {"M" ,                    CONFIG_HLP_DLBW_PHYTEST,0,                uptr:&target_dl_bw,                 defintval:0,                   TYPE_UINT,   0},        \
     {"T" ,                    CONFIG_HLP_ULBW_PHYTEST,0,                uptr:&target_ul_bw,                 defintval:0,                   TYPE_UINT,   0},        \
@@ -34,6 +35,7 @@
 #include "threads_t.h"
 extern threads_t threads;
 extern uint32_t target_dl_mcs;
+extern uint32_t target_dl_Nl;
 extern uint32_t target_ul_mcs;
 extern uint32_t target_dl_bw;
 extern uint32_t target_ul_bw;
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index cba06490fb73cafdc6d6c2dd9121175153c04e10..23982c6bc33ffc579b4cf589a00cafc8a5fea007 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -360,8 +360,8 @@ void init_openair0(void) {
     openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL;
     openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
     openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
-    openair0_cfg[card].tx_num_channels = min(2, frame_parms->nb_antennas_tx);
-    openair0_cfg[card].rx_num_channels = min(2, frame_parms->nb_antennas_rx);
+    openair0_cfg[card].tx_num_channels = min(4, frame_parms->nb_antennas_tx);
+    openair0_cfg[card].rx_num_channels = min(4, frame_parms->nb_antennas_rx);
 
     LOG_I(PHY, "HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
       card,
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index f9be62797472f1f3cc7b96977bc1bc08ab4b755e..dcff18f02580f14aefc17d649c798ab1b6b23e42 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -595,27 +595,6 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
         exit(-1);
       }
 
-      /*
-      LOG_I(PHY,"Initializing nFAPI for ULSCH, UE %d\n",i);
-      // [hna] added here for RT implementation
-      uint8_t harq_pid = 0;
-      nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[i+1][j]->harq_processes[harq_pid]->ulsch_pdu;
-  
-      // --------- setting rel15_ul parameters ----------
-      rel15_ul->rnti                           = 0x1234;
-      rel15_ul->ulsch_pdu_rel15.start_rb       = 0;
-      rel15_ul->ulsch_pdu_rel15.number_rbs     = 50;
-      rel15_ul->ulsch_pdu_rel15.start_symbol   = 2;
-      rel15_ul->ulsch_pdu_rel15.number_symbols = 12;
-      rel15_ul->ulsch_pdu_rel15.length_dmrs    = gNB->dmrs_UplinkConfig.pusch_maxLength;
-      rel15_ul->ulsch_pdu_rel15.Qm             = 2;
-      rel15_ul->ulsch_pdu_rel15.R              = 679;
-      rel15_ul->ulsch_pdu_rel15.mcs            = 9;
-      rel15_ul->ulsch_pdu_rel15.rv             = 0;
-      rel15_ul->ulsch_pdu_rel15.n_layers       = 1;
-      ///////////////////////////////////////////////////
-      */
-
     }
 
   }
diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c
index b2abf27d00107b7789bd98abc24562f143162e05..e04197d48a36fc11d94ed3820fed253f1d3680e5 100644
--- a/openair1/PHY/INIT/nr_init_ru.c
+++ b/openair1/PHY/INIT/nr_init_ru.c
@@ -132,22 +132,22 @@ int nr_phy_init_RU(RU_t *ru) {
         }
         AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
     
+      for (i=0; i<ru->num_gNB; i++) {
         int l_ind = 0;
-        for (i=0; i<ru->num_gNB; i++) {
-          for (p=0;p<ru->nb_log_antennas;p++) {
+        for (p=0;p<ru->nb_log_antennas;p++) {
           //if ((fp->L_ssb >> (63-p)) & 0x01)  {
-	      ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
-	      for (j=0; j<ru->nb_tx; j++) {
-	        ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
-                AssertFatal(ru->bw_list[i],"ru->bw_list[%d] is null\n",i);
-                for (re=0; re<fp->ofdm_symbol_size; re++)
-		  ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
+          ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
+          for (j=0; j<ru->nb_tx; j++) {
+            ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
+            AssertFatal(ru->bw_list[i],"ru->bw_list[%d] is null\n",i);
+            for (re=0; re<fp->ofdm_symbol_size; re++)
+              ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
               //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
-                l_ind++;
-  	      } // for j
-	    //}
-          } // for p
-        } //for i
+              l_ind++;
+          } // for j
+          //}
+        } // for p
+      } //for i
       }
 
       ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*));
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index a9c71d158256b3cbfdb5631977958fb34f19c6a5..68947b0c6bdf4b09b58c878500035c299172e245 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -143,8 +143,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig
   int n_scid;
   abstraction_flag = 0;
-  // dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig;
-  // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
   LOG_I(PHY, "Initializing UE vars (abstraction %u) for gNB TXant %u, UE RXant %u\n", abstraction_flag, fp->nb_antennas_tx, fp->nb_antennas_rx);
   //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_gNB_INST);
   phy_init_nr_top(ue);
@@ -188,29 +186,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
 
   /////////////////////////PUSCH DMRS init/////////////////////////
   ///////////
-
-  // default values until overwritten by RRCConnectionReconfiguration
-
-  for (i=0; i<MAX_NR_OF_UL_ALLOCATIONS; i++) {
-    ue->pusch_config.pusch_TimeDomainResourceAllocation[i] = (PUSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PUSCH_TimeDomainResourceAllocation_t));
-    ue->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB;
-  }
-
-  for (i=0;i<MAX_NR_OF_DL_ALLOCATIONS;i++){
-    ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i] = (PDSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PDSCH_TimeDomainResourceAllocation_t));
-    ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = typeA;
-  }
-
-  //------------- config DMRS parameters--------------//
-  // dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1;
-  // dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0;
-  // dmrs_Uplink_Config->pusch_maxLength = pusch_len1;
-  //-------------------------------------------------//
-  ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type1;
-  ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = pdsch_dmrs_pos0;
-  ue->dmrs_DownlinkConfig.pdsch_maxLength = pdsch_len1;
-  //-------------------------------------------------//
-
   ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
   pusch_dmrs             = ue->nr_gold_pusch_dmrs;
   n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization
diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
index 5a4b1adbb84ff7dc7a273f223606d058e7ce615d..920b78eac2b0880311bbac733c9b4fcbcd84ca76 100644
--- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
+++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -111,9 +111,10 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
                      int32_t *output,
                      unsigned short p,
                      unsigned char lp,
-                     unsigned short nb_pdsch_rb)
+                     unsigned short nb_pdsch_rb,
+                     uint8_t config_type)
 {
-  int8_t w,config_type;
+  int8_t w;
   short *mod_table;
   unsigned char idx=0;
 
@@ -121,18 +122,16 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
   array_of_w *wf;
   array_of_w *wt;
 
-  config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
-
-  wf = (config_type==pdsch_dmrs_type1) ? wf1 : wf2;
-  wt = (config_type==pdsch_dmrs_type1) ? wt1 : wt2;
+  wf = (config_type==NFAPI_NR_DMRS_TYPE1) ? wf1 : wf2;
+  wt = (config_type==NFAPI_NR_DMRS_TYPE1) ? wt1 : wt2;
 
   if (config_type > 1)
     LOG_E(PHY,"Bad PDSCH DMRS config type %d\n", config_type);
 
-  if ((p>=1000) && (p<((config_type==pdsch_dmrs_type1) ? 1008 : 1012))) {
+  if ((p>=1000) && (p<((config_type==NFAPI_NR_DMRS_TYPE1) ? 1008 : 1012))) {
       if (ue->frame_parms.Ncp == NORMAL) {
 
-        for (int i=0; i<nb_pdsch_rb*((config_type==pdsch_dmrs_type1) ? 6:4); i++) {
+        for (int i=0; i<nb_pdsch_rb*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4); i++) {
 
         	w = (wf[p-1000][i&1])*(wt[p-1000][lp]);
         	mod_table = (w==1) ? nr_rx_mod_table : nr_rx_nmod_table;
diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
index 54279a8ad5faf85ace67cc4d4a477db15ce151af..1fca2be2a187dd7643d7898ccfba7bd71b09e94c 100644
--- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
+++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
@@ -52,7 +52,8 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
                      int32_t *output,
                      unsigned short p,
                      unsigned char lp,
-                     unsigned short nb_pdsch_rb);
+                     unsigned short nb_pdsch_rb,
+                     uint8_t config_type);
 
 void nr_gold_pbch(PHY_VARS_NR_UE* ue);
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index d208167855444d42fb61372c07787763cde0d888..54e6b2ac79a497a7660061e738ecea606dba99db 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -70,7 +70,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
                         uint32_t **gold_pdcch_dmrs,
                         int32_t *txdataF,
                         int16_t amp,
-                        NR_DL_FRAME_PARMS frame_parms) {
+                        NR_DL_FRAME_PARMS *frame_parms) {
 
   int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1] __attribute__((aligned(16))); // 3 for the max coreset duration
   uint16_t cset_start_sc;
@@ -85,7 +85,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
   // compute rb_offset and n_prb based on frequency allocation
   nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
   get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
-  cset_start_sc = frame_parms.first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
+  cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
 
   for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
     /*The coreset is initialised
@@ -164,8 +164,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
 
     /// Resource mapping
 
-    if (cset_start_sc >= frame_parms.ofdm_symbol_size)
-      cset_start_sc -= frame_parms.ofdm_symbol_size;
+    if (cset_start_sc >= frame_parms->ofdm_symbol_size)
+      cset_start_sc -= frame_parms->ofdm_symbol_size;
 
     // Get cce_list indices by reg_idx in ascending order
     int reg_list_index = 0;
@@ -190,8 +190,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
 
           k = cset_start_sc + gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].start_sc_idx;
 
-          if (k >= frame_parms.ofdm_symbol_size)
-            k -= frame_parms.ofdm_symbol_size;
+          if (k >= frame_parms->ofdm_symbol_size)
+            k -= frame_parms->ofdm_symbol_size;
 
           l = cset_start_symb + symbol_idx;
 
@@ -205,26 +205,26 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
 
           for (int m = 0; m < NR_NB_SC_PER_RB; m++) {
             if (m == (k_prime << 2) + 1) { // DMRS if not already mapped
-              ((int16_t *) txdataF)[(l * frame_parms.ofdm_symbol_size + k) << 1] =
+              ((int16_t *) txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] =
                   (amp * mod_dmrs[l][dmrs_idx << 1]) >> 15;
-              ((int16_t *) txdataF)[((l * frame_parms.ofdm_symbol_size + k) << 1) + 1] =
+              ((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] =
                   (amp * mod_dmrs[l][(dmrs_idx << 1) + 1]) >> 15;
 
 #ifdef DEBUG_PDCCH_DMRS
-              printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
-               ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
+              printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
+               ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
 #endif
 
               dmrs_idx++;
               k_prime++;
 
             } else { // DCI payload
-              ((int16_t *) txdataF)[(l * frame_parms.ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15;
-              ((int16_t *) txdataF)[((l * frame_parms.ofdm_symbol_size + k) << 1) + 1] =
+              ((int16_t *) txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15;
+              ((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] =
                   (amp * mod_dci[(dci_idx << 1) + 1]) >> 15;
 #ifdef DEBUG_DCI
-              printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
-               ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
+              printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
+               ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
 #endif
 
               dci_idx++;
@@ -232,8 +232,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
 
             k++;
 
-            if (k >= frame_parms.ofdm_symbol_size)
-              k -= frame_parms.ofdm_symbol_size;
+            if (k >= frame_parms->ofdm_symbol_size)
+              k -= frame_parms->ofdm_symbol_size;
 
           } // m
         } // reg_in_cce_idx
@@ -253,17 +253,15 @@ void nr_generate_dci_top(PHY_VARS_gNB *gNB,
                             uint32_t **gold_pdcch_dmrs,
                             int32_t *txdataF,
                             int16_t amp,
-                            NR_DL_FRAME_PARMS frame_parms) {
+                            NR_DL_FRAME_PARMS *frame_parms) {
 
   AssertFatal(pdcch_pdu!=NULL || ul_dci_pdu!=NULL,"At least one pointer has to be !NULL\n");
 
-  if (pdcch_pdu && ul_dci_pdu) {
+  if (pdcch_pdu) {
     nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
-    nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
   }
-  else if (pdcch_pdu)
-    nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
-  else
+  if (ul_dci_pdu) {
     nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
+  }
 }
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h
index 1b57acc6f40ff7edb2352486a827b9d446d6e55f..e3b53f9cf9658656cb5bb5132b1f3a65b2ad98bc 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h
@@ -35,7 +35,7 @@ void nr_generate_dci_top(PHY_VARS_gNB *gNB,
 			    uint32_t **gold_pdcch_dmrs,
                             int32_t *txdataF,
                             int16_t amp,
-                            NR_DL_FRAME_PARMS frame_parms);
+                            NR_DL_FRAME_PARMS *frame_parms);
 
 void nr_pdcch_scrambling(uint32_t *in,
                          uint32_t size,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index b1dbc7c7d94fe8a879150098c67fac07acdb8205..03bd0ddf6cffc715982fe69d38e95d597442b437 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -448,7 +448,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
                      (void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + txdataF_offset+ k)],
                      NR_NB_SC_PER_RB*sizeof(int32_t));
             else
-              memset((void*)&txdataF[ap][rel15->StartSymbolIndex*frame_parms->ofdm_symbol_size + txdataF_offset +k],
+              memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
                      0,
                      NR_NB_SC_PER_RB*sizeof(int32_t));
             k += NR_NB_SC_PER_RB;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index 2a3c16938a1be7cc9abe5e207db078b99a04802c..2ae2549df31743e6d7263e1087c8d0714bf34091 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -192,14 +192,15 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
     AssertFatal(harq->d[r], "cannot allocate harq->d[%d]\n", r); // max size for coded output
     bzero(harq->c[r], 8448);
     bzero(harq->d[r], (3 * 8448));
-    harq->e = malloc16(14 * N_RB * 12 * 8);
-    AssertFatal(harq->e, "cannot allocate harq->e\n");
-    bzero(harq->e, 14 * N_RB * 12 * 8);
-    harq->f = malloc16(14 * N_RB * 12 * 8);
-    AssertFatal(harq->f, "cannot allocate harq->f\n");
-    bzero(harq->f, 14 * N_RB * 12 * 8);
   }
 
+  harq->e = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+  AssertFatal(harq->e, "cannot allocate harq->e\n");
+  bzero(harq->e, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+  harq->f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+  AssertFatal(harq->f, "cannot allocate harq->f\n");
+  bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
+
   return(dlsch);
 }
 
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index 909d0b8954036a72584605e3a996733972b40e4d..8c4394e6e9e933b1a7e17d0290671965fd64897d 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -36,7 +36,7 @@
 
 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
                              UE_nr_rxtx_proc_t *proc,
-                             uint8_t eNB_offset,
+                             uint8_t gNB_id,
                              unsigned char Ns,
                              unsigned char symbol,
                              int dmrss,
@@ -70,7 +70,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
   k = nushift;
 
 #ifdef DEBUG_CH
-  printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PBCH DMRS Correlation : ThreadId %d, gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
@@ -198,7 +198,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
 
 int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
                                UE_nr_rxtx_proc_t *proc,
-                               uint8_t eNB_offset,
+                               uint8_t gNB_id,
                                unsigned char Ns,
                                unsigned char symbol,
                                int dmrss,
@@ -213,10 +213,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
   int ch_offset,symbol_offset;
   //int slot_pbch;
 
-  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
-
   uint8_t nushift;
-  int **dl_ch_estimates  =ue->pbch_vars[eNB_offset]->dl_ch_estimates;
+  int **dl_ch_estimates  =ue->pbch_vars[gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
   nushift =  ue->frame_parms.Nid_cell%4;
@@ -239,7 +237,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
   k = nushift;
 
 #ifdef DEBUG_CH
-  printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PBCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
@@ -456,12 +454,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
       // do ifft of channel estimate
       for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
         for (p=0; p<ue->frame_parms.nb_antenna_ports_gNB; p++) {
-          if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx])
+          if (ue->pbch_vars[gNB_id]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx])
           {
             LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, proc->thread_id, symbol, ch_offset);
             idft(idftsizeidx,
-                 (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx][ch_offset],
-                 (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p*ue->frame_parms.nb_antennas_rx)+aarx],1);
+                 (int16_t*) &ue->pbch_vars[gNB_id]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx][ch_offset],
+                 (int16_t*) ue->pbch_vars[gNB_id]->dl_ch_estimates_time[(p*ue->frame_parms.nb_antennas_rx)+aarx],1);
           }
         }
     }
@@ -474,7 +472,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
                                 unsigned char Ns,
                                 unsigned char symbol,
                                 unsigned short coreset_start_subcarrier,
@@ -487,9 +485,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
   int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
   int ch_offset,symbol_offset;
 
-  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
-
-  int **dl_ch_estimates  =ue->pdcch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates;
+  int **dl_ch_estimates  =ue->pdcch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
 
@@ -500,10 +496,9 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
   symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
 
-  k = coreset_start_subcarrier;
 
 #ifdef DEBUG_PDCCH
-  printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PDCCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
@@ -521,11 +516,12 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
   // generate pilot
   int pilot[nb_rb_coreset * 3] __attribute__((aligned(16))); 
-  nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
+  nr_pdcch_dmrs_rx(ue,gNB_id,Ns,ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
 
 
   for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
 
+    k = coreset_start_subcarrier;
     pil   = (int16_t *)&pilot[0];
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
     dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
@@ -656,7 +652,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
                                 bool is_SI,
                                 unsigned char Ns,
                                 unsigned short p,
@@ -673,10 +669,12 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh, *frl, *frr;
   int ch_offset,symbol_offset;
 
-  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
+  NR_UE_DLSCH_t  **dlsch = ue->dlsch[proc->thread_id][gNB_id];
+  const unsigned char harq_pid = dlsch[0]->current_harq_pid;
+  NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
 
   uint8_t nushift;
-  int **dl_ch_estimates  =ue->pdsch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates;
+  int **dl_ch_estimates  =ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
   if (ue->high_speed_flag == 0)
@@ -690,7 +688,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int re_offset = k;
 
 #ifdef DEBUG_CH
-  printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("PDSCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,Ns,k, symbol);
 #endif
 
@@ -699,19 +697,19 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   if (is_SI) {
     rb_offset -= BWPStart;
   }
-  uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
+  uint8_t config_type = dlsch0_harq->dmrsConfigType;
   int8_t delta = get_delta(p, config_type);
 
   // checking if re-initialization of scrambling IDs is needed
-  if ((ue->dmrs_DownlinkConfig.scramblingID0 != ue->scramblingID[0]) || (ue->dmrs_DownlinkConfig.scramblingID1 != ue->scramblingID[1])){
-    ue->scramblingID[0]=ue->dmrs_DownlinkConfig.scramblingID0;
-    ue->scramblingID[1]=ue->dmrs_DownlinkConfig.scramblingID1;
+  /*if ((XXX.scramblingID0 != ue->scramblingID[0]) || (XXX.scramblingID1 != ue->scramblingID[1])){
+    ue->scramblingID[0] = XXX.scramblingID0;
+    ue->scramblingID[1] = XXX.scramblingID1;
     nr_gold_pdsch(ue,ue->scramblingID);
-  }
+  }*/
 
-  nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000+p,0,nb_rb_pdsch+rb_offset);
+  nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][0], &pilot[0], 1000+p, 0, nb_rb_pdsch+rb_offset, config_type);
 
-  if (config_type == pdsch_dmrs_type1){
+  if (config_type == NFAPI_NR_DMRS_TYPE1){
     nushift = (p>>1)&1;
     if (p<4) ue->frame_parms.nushift = nushift;
     switch (delta) {
@@ -751,7 +749,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
         return -1;
         break;
     }
-  } else {//pdsch_dmrs_type2
+  } else {//NFAPI_NR_DMRS_TYPE2
     nushift = delta;
     if (p<6) ue->frame_parms.nushift = nushift;
     switch (delta) {
@@ -793,7 +791,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   }
 
   for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
-    pil   = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)];
+    pil   = (int16_t *)&pilot[rb_offset*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4)];
     k     = k % ue->frame_parms.ofdm_symbol_size;
     re_offset = k;
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+re_offset+nushift)];
@@ -811,7 +809,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
     printf("dl_ch addr %p nushift %d\n",dl_ch,nushift);
 #endif
 
-    if (config_type == pdsch_dmrs_type1) {
+    if (config_type == NFAPI_NR_DMRS_TYPE1) {
 
       // Treat first 2 pilots specially (left edge)
       ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -944,11 +942,11 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
     
     // check if PRB crosses DC and improve estimates around DC
     if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) {
-      dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
+      dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset];
       uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
       uint16_t idxPil = idxDC/2;
       re_offset = k;
-      pil = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)];
+      pil = (int16_t *)&pilot[rb_offset*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4)];
       pil += (idxPil-2);
       dl_ch += (idxDC-4);
       dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10);
@@ -994,7 +992,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                            8);
       }
     }
-    } else { //pdsch_dmrs_type2  |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0|
+    } else { //NFAPI_NR_DMRS_TYPE2  |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0|
 
       // Treat first 4 pilots specially (left edge)
       ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -1224,16 +1222,15 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
  *
  * NAME :         nr_pdsch_ptrs_processing
  *
- * PARAMETERS :   ue                : ue data structure
+ * PARAMETERS :   PHY_VARS_NR_UE    : ue data structure
  *                NR_UE_PDSCH       : pdsch_vars pointer
  *                NR_DL_FRAME_PARMS : frame_parms pointer
  *                NR_DL_UE_HARQ_t   : dlsch0_harq pointer
  *                NR_DL_UE_HARQ_t   : dlsch1_harq pointer
- *                uint8_t           : eNB_id,
+ *                uint8_t           : gNB_id,
  *                uint8_t           : nr_slot_rx,
  *                unsigned char     : symbol,
  *                uint32_t          : nb_re_pdsch,
- *                unsigned char     : harq_pid
  *                uint16_t          : rnti
  *                RX_type_t         : rx_type
  * RETURN : Nothing
@@ -1249,11 +1246,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
                               NR_DL_FRAME_PARMS *frame_parms,
                               NR_DL_UE_HARQ_t *dlsch0_harq,
                               NR_DL_UE_HARQ_t *dlsch1_harq,
-                              uint8_t eNB_id,
+                              uint8_t gNB_id,
                               uint8_t nr_slot_rx,
                               unsigned char symbol,
                               uint32_t nb_re_pdsch,
-                              unsigned char harq_pid,
                               uint16_t rnti,
                               RX_type_t rx_type)
 {
@@ -1284,7 +1280,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
     ptrsSymbPos     = &dlsch0_harq->ptrs_symbols;
     ptrsSymbIdx     = &dlsch0_harq->ptrs_symbol_index;
     ptrsReOffset    = &dlsch0_harq->PTRSReOffset;
-    dmrsConfigType  = &dlsch0_harq->ptrs_symbol_index;
+    dmrsConfigType  = &dlsch0_harq->dmrsConfigType;
     nb_rb           = &dlsch0_harq->nb_rb;
   }
   if(dlsch1_harq) {
@@ -1297,13 +1293,13 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
     ptrsSymbPos     = &dlsch1_harq->ptrs_symbols;
     ptrsSymbIdx     = &dlsch1_harq->ptrs_symbol_index;
     ptrsReOffset    = &dlsch1_harq->PTRSReOffset;
-    dmrsConfigType  = &dlsch1_harq->ptrs_symbol_index;
+    dmrsConfigType  = &dlsch1_harq->dmrsConfigType;
     nb_rb           = &dlsch1_harq->nb_rb;
   }
   /* loop over antennas */
   for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-    phase_per_symbol = (int16_t*)pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx];
-    ptrs_re_symbol = (int32_t*)pdsch_vars[eNB_id]->ptrs_re_per_slot[aarx];
+    phase_per_symbol = (int16_t*)pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx];
+    ptrs_re_symbol = (int32_t*)pdsch_vars[gNB_id]->ptrs_re_per_slot[aarx];
     ptrs_re_symbol[symbol] = 0;
     phase_per_symbol[(2*symbol)+1] = 0; // Imag
     /* set DMRS estimates to 0 angle with magnitude 1 */
@@ -1337,11 +1333,11 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
         /*------------------------------------------------------------------------------------------------------- */
         nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb,
                                rnti,
-                               (int16_t *)&pdsch_vars[eNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch],
+                               (int16_t *)&pdsch_vars[gNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch],
                                nr_slot_rx,
                                symbol,frame_parms->ofdm_symbol_size,
-                               (int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)],
-                               ue->nr_gold_pdsch[eNB_id][nr_slot_rx][symbol][0],
+                               (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)],
+                               ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][0],
                                &phase_per_symbol[2* symbol],
                                &ptrs_re_symbol[symbol]);
       }
@@ -1360,9 +1356,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
         }
       }
 #ifdef DEBUG_DL_PTRS
-      LOG_M("ptrsEst.m","est",pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
+      LOG_M("ptrsEst.m","est",pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
       LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp",
-            &pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ],
+            &pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ],
             (*nb_rb) * NR_NB_SC_PER_RB * (*nbSymb),1,1);
 #endif
       /*------------------------------------------------------------------------------------------------------- */
@@ -1375,9 +1371,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
 #ifdef DEBUG_DL_PTRS
           printf("[PHY][DL][PTRS]: Rotate Symbol %2d with  %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]);
 #endif
-          rotate_cpx_vector((int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
+          rotate_cpx_vector((int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
                             &phase_per_symbol[2* i],
-                            (int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
+                            (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
                             ((*nb_rb) * NR_NB_SC_PER_RB), 15);
         }// if not DMRS Symbol
       }// symbol loop
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index 1466fabe5d5f1a549922e5729d250d2d22075267..c5330ce2f2e7e2a98f3d77591046f4ea8bb6cc84 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -34,17 +34,14 @@
 
 /*!
 \brief This function performs channel estimation including frequency and temporal interpolation
-\param phy_vars_ue Pointer to UE PHY variables
-\param eNB_id Index of target eNB
-\param eNB_offset Offset for interfering eNB (in terms cell ID mod 3)
+\param ue Pointer to UE PHY variables
+\param gNB_id Index of target gNB
 \param Ns slot number (0..19)
-\param p antenna port
-\param l symbol within slot
-\param symbol symbol within frame
+\param symbol symbol within slot
 */
 int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
                                 unsigned char Ns,
                                 unsigned char symbol,
                                 unsigned short coreset_start_subcarrier,
@@ -52,7 +49,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
                              UE_nr_rxtx_proc_t *proc,
-                             uint8_t eNB_offset,
+                             uint8_t gNB_id,
                              unsigned char Ns,
                              unsigned char symbol,
                              int dmrss,
@@ -60,7 +57,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
 
 int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
                                UE_nr_rxtx_proc_t *proc,
-                               uint8_t eNB_offset,
+                               uint8_t gNB_id,
                                unsigned char Ns,
                                unsigned char symbol,
                                int dmrss,
@@ -69,7 +66,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t eNB_offset,
+                                uint8_t gNB_id,
                                 bool is_SI,
                                 unsigned char Ns,
                                 unsigned short p,
@@ -80,7 +77,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
                         PHY_VARS_NR_UE *ue,
-                        module_id_t eNB_id,
+                        module_id_t gNB_id,
                         uint8_t frame,
                         uint8_t subframe,
                         unsigned char clear,
@@ -102,7 +99,7 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
 
 void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
                         uint32_t rx_power_fil_dB,
-                        uint8_t eNB_id);
+                        uint8_t gNB_id);
 
 int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
 
@@ -111,11 +108,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
                               NR_DL_FRAME_PARMS *frame_parms,
                               NR_DL_UE_HARQ_t *dlsch0_harq,
                               NR_DL_UE_HARQ_t *dlsch1_harq,
-                              uint8_t eNB_id,
+                              uint8_t gNB_id,
                               uint8_t nr_slot_rx,
                               unsigned char symbol,
                               uint32_t nb_re_pdsch,
-                              unsigned char harq_pid,
                               uint16_t rnti,
                               RX_type_t rx_type);
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index 5d4d9df47e26782831a77b9e741d5684497396cc..cffdf5092d90e796dce3efb9164796d6e965ea33 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -761,7 +761,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
       for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
         avgs = cmax(avgs, avgP[aarx]);
 
-      log2_maxh = (log2_approx(avgs) / 2) + 5;  //+frame_parms->nb_antennas_rx;
+      log2_maxh = (log2_approx(avgs) / 2) + 1;  //+frame_parms->nb_antennas_rx;
 #ifdef UE_DEBUG_TRACE
       LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs);
 #endif
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 2046c13eaa626f1caa7c2bf8d801023d00a1a625..2174f569da290c93a1d0887d6782758ea36003ac 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -84,8 +84,8 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{
  */
 //unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};
 
-#define print_ints(s,x) printf("%s %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3])
-#define print_shorts(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
+#define print_ints(s,x) printf("%s = %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3])
+#define print_shorts(s,x) printf("%s = [%d+j*%d, %d+j*%d, %d+j*%d, %d+j*%d]\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
 
 static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
 						  int **dl_ch_estimates_ext_i,
@@ -99,17 +99,21 @@ static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
 uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
                                    int **dl_ch_mag,
                                    int **dl_ch_magb,
+                                   int **dl_ch_magr,
                                    int **dl_ch_estimates_ext,
                                    unsigned short nb_rb,
                                    unsigned char n_rx,
                                    unsigned char mod_order,
                                    int shift,
-                                   unsigned char symbol);
+                                   unsigned char symbol,
+                                   int length);
 
 static void nr_dlsch_layer_demapping(int16_t **llr_cw,
 				     uint8_t Nl,
 				     uint8_t mod_order,
-				     uint16_t length,
+				     uint32_t length,
+				     int32_t codeword_TB0,
+				     int32_t codeword_TB1,
 				     int16_t **llr_layers);
 
 
@@ -182,8 +186,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   //int16_t  *pllr_symbol_cw0_deint;
   //int16_t  *pllr_symbol_cw1_deint;
   //uint16_t bundle_L = 2;
-  uint8_t pilots=0;
-  uint8_t config_type;// We should not use ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
   uint16_t n_tx=1, n_rx=1;
   int32_t median[16];
   uint32_t len;
@@ -340,8 +342,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   printf("Demod  dlsch0_harq->pmi_alloc %d\n",  dlsch0_harq->pmi_alloc);
 #endif
 
-  pilots = ((1<<symbol)&dlsch0_harq->dlDmrsSymbPos)>0 ? 1 : 0;
-  config_type = dlsch0_harq->dmrsConfigType;
+  uint8_t pilots = (dlsch0_harq->dlDmrsSymbPos >> symbol) & 1;
+  uint8_t config_type = dlsch0_harq->dmrsConfigType;
 
   if (beamforming_mode==0) {//No beamforming
 #if UE_TIMING_TRACE
@@ -385,7 +387,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     return(-1);
   }
 
-  len = (pilots==1)? ((config_type==pdsch_dmrs_type1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12);
+  len = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12);
 
 #if UE_TIMING_TRACE
   stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
@@ -412,7 +414,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                          symbol,
                          pilots,
                          len,
-                         nb_rb);
+                         nb_rb_pdsch);
 
 #if UE_TIMING_TRACE
     stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
@@ -434,7 +436,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                              avg,
                              symbol,
                              len,
-                             nb_rb);
+                             nb_rb_pdsch);
       avgs = 0;
       for (aatx=0;aatx<n_tx;aatx++)
         for (aarx=0;aarx<n_rx;aarx++) {
@@ -443,7 +445,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
           //LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
           median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx];
         }
-      pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2)+3;
+      pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
       //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs,  pdsch_vars[gNB_id]->log2_maxh);
 
       if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
@@ -505,10 +507,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                   frame_parms,
                                   n_tx,
                                   symbol,
-                                  pilots,
+                                  len,
                                   first_symbol_flag,
                                   dlsch0_harq->Qm,
-                                  nb_rb,
+                                  nb_rb_pdsch,
                                   pdsch_vars[gNB_id]->log2_maxh,
                                   measurements); // log2_maxh+I0_shift
     }
@@ -556,20 +558,24 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                              (n_tx>1)? pdsch_vars[gNB_id]->rho : NULL,
                              pdsch_vars[gNB_id]->dl_ch_mag0,
                              pdsch_vars[gNB_id]->dl_ch_magb0,
+                             pdsch_vars[gNB_id]->dl_ch_magr0,
                              n_tx,
                              n_rx,
                              symbol,
-                             nb_rb);
+                             nb_rb_pdsch,
+                             len);
       if (n_tx == 2)//Apply zero forcing for 2 Tx layers
         nr_zero_forcing_rx_2layers(pdsch_vars[gNB_id]->rxdataF_comp0,
                                    pdsch_vars[gNB_id]->dl_ch_mag0,
                                    pdsch_vars[gNB_id]->dl_ch_magb0,
+                                   pdsch_vars[gNB_id]->dl_ch_magr0,
                                    pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                   nb_rb,
+                                   nb_rb_pdsch,
                                    n_rx,
                                    dlsch0_harq->Qm,
                                    pdsch_vars[gNB_id]->log2_maxh,
-                                   symbol);
+                                   symbol,
+                                   len);
     }
     else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
       nr_dlsch_detection_mrc_core(pdsch_vars[gNB_id]->rxdataF_comp0,
@@ -635,14 +641,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                nr_slot_rx,
                                symbol,
                                (nb_rb*12),
-                               harq_pid,
                                dlsch[0]->rnti,rx_type);
       pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
     }
 
     /* at last symbol in a slot calculate LLR's for whole slot */
     if(symbol == (startSymbIdx + nbSymb -1)) {
-      for(uint8_t i =startSymbIdx; i <= nbSymb;i++) {
+      for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) {
         /* re evaluating the first symbol flag as LLR's are done in symbol loop  */
         if(i == startSymbIdx && i < 3) {
           first_symbol_flag =1;
@@ -662,16 +667,29 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                      pdsch_vars[gNB_id]->dl_valid_re[i-1],
                      nr_slot_rx, beamforming_mode);
       }
-    }
-
-  //nr_dlsch_deinterleaving(symbol,bundle_L,(int16_t*)pllr_symbol_cw0,(int16_t*)pllr_symbol_cw0_deint, nb_rb_pdsch);
 
-    if (rx_type==rx_IC_dual_stream) {
+      int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType;
+      uint8_t nb_re_dmrs;
+      uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos);
+      if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
+        nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
+      } else {
+        nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
+      }
+      dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb,
+                                                       dlsch[0]->harq_processes[harq_pid]->nb_symbols,
+                                                       nb_re_dmrs,
+                                                       dmrs_len,
+                                                       dlsch[0]->harq_processes[harq_pid]->Qm,
+                                                       dlsch[0]->harq_processes[harq_pid]->Nl);
       nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr,
                                dlsch[0]->harq_processes[harq_pid]->Nl,
                                dlsch[0]->harq_processes[harq_pid]->Qm,
                                dlsch[0]->harq_processes[harq_pid]->G,
+                               codeword_TB0,
+                               codeword_TB1,
                                pdsch_vars[gNB_id]->layer_llr);
+
     }
 
 #if UE_TIMING_TRACE
@@ -780,7 +798,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
                                 NR_DL_FRAME_PARMS *frame_parms,
                                 uint8_t nb_aatx,
                                 unsigned char symbol,
-                                uint8_t pilots,
+                                int length,
                                 uint8_t first_symbol_flag,
                                 unsigned char mod_order,
                                 unsigned short nb_rb,
@@ -794,8 +812,8 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
   unsigned char aatx,aarx,atx;
   __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*dl_ch_mag128r,*rxdataF128,*rxdataF_comp128,*rho128;
   __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b,QAM_amp128r;
-  QAM_amp128b = _mm_setzero_si128();
 
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
   for (aatx=0; aatx<nb_aatx; aatx++) {
     if (mod_order == 4) {
       QAM_amp128 = _mm_set1_epi16(QAM16_n1);  // 2/sqrt(10)
@@ -822,7 +840,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
       rxdataF128        = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12];
       rxdataF_comp128   = (__m128i *)&rxdataF_comp[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
 
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
         if (mod_order>2) {
           // get channel amplitude if not QPSK
 
@@ -832,7 +850,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]);
           mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
 
-          mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
+          mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); //|H[0]|^2 |H[1]|^2 |H[2]|^2 |H[3]|^2 |H[4]|^2 |H[5]|^2 |H[6]|^2 |H[7]|^2
 
           // store channel magnitude here in a new field of dlsch
 
@@ -841,6 +859,13 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           dl_ch_mag128r[0] = dl_ch_mag128[0];
           dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128);
           dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1);
+
+          dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b);
+          dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1);
+
+          dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r);
+          dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1);
+
     //print_ints("Re(ch):",(int16_t*)&mmtmpD0);
     //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128);
     //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]);
@@ -850,39 +875,28 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128);
           dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1);
 
-          if (pilots==0) {
-            mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]);
-            mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-            mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
-
-            dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
-            dl_ch_mag128b[2] = dl_ch_mag128[2];
-            dl_ch_mag128r[2] = dl_ch_mag128[2];
-
-            dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128);
-            dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1);
-          }
-
-          dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b);
-          dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1);
-
-
           dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b);
           dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1);
 
-          dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r);
-          dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1);
-
           dl_ch_mag128r[1] = _mm_mulhi_epi16(dl_ch_mag128r[1],QAM_amp128r);
           dl_ch_mag128r[1] = _mm_slli_epi16(dl_ch_mag128r[1],1);
 
-          if (pilots==0) {
-            dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b);
-            dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1);
+          mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]);//[H_I(0)^2+H_Q(0)^2 H_I(1)^2+H_Q(1)^2 H_I(2)^2+H_Q(2)^2 H_I(3)^2+H_Q(3)^2]
+          mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+          mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);//[|H(0)|^2 |H(1)|^2 |H(2)|^2 |H(3)|^2 |H(0)|^2 |H(1)|^2 |H(2)|^2 |H(3)|^2]
 
-            dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r);
-            dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1);
-          }
+          dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);//[|H(0)|^2 |H(0)|^2 |H(1)|^2 |H(1)|^2 |H(2)|^2 |H(2)|^2 |H(3)|^2 |H(3)|^2]
+          dl_ch_mag128b[2] = dl_ch_mag128[2];
+          dl_ch_mag128r[2] = dl_ch_mag128[2];
+
+          dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128);
+          dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1);
+
+          dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b);
+          dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1);
+
+          dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r);
+          dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1);
         }
 
         // multiply by conjugated channel
@@ -905,15 +919,17 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
         //        print_ints("c0",&mmtmpD2);
         //  print_ints("c1",&mmtmpD3);
         rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-        //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol);
-        //  print_shorts("rx:",rxdataF128);
-        //  print_shorts("ch:",dl_ch128);
-        //  print_shorts("pack:",rxdataF_comp128);
-
-        //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol);
-        //print_shorts("rx:",(int16_t*)&rxdataF128[0]);
-        //print_shorts("ch:",(int16_t*)&dl_ch128[0]);
-        //print_shorts("pack:",(int16_t*)&rxdataF_comp128[0]);
+
+#ifdef DEBUG_DLSCH_DEMOD
+        printf("%%arx%d atx%d rb_index %d symbol %d shift %d\n",aarx,aatx,rb,symbol,output_shift);
+        printf("rx_%d(%d,:)",aarx+1,rb+1);
+        print_shorts("  ",(int16_t *)&rxdataF128[0]);
+        printf("ch_%d%d(%d,:)",aarx+1,aatx+1,rb+1);
+        print_shorts("  ",(int16_t *)&dl_ch128[0]);
+        printf("rx_comp_%d%d(%d,:)",aarx+1,aatx+1,rb+1);
+        print_shorts("  ",(int16_t *)&rxdataF_comp128[0]);
+#endif
+
         // multiply by conjugated channel
         mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
         // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
@@ -932,40 +948,30 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
         //print_shorts("ch:",(int16_t*)&dl_ch128[1]);
         //print_shorts("pack:",(int16_t*)&rxdataF_comp128[1]);
 
-        if (pilots==0) {
-          // multiply by conjugated channel
-          mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
-          // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
-          mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
-          mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
-          mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
-          mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
-          // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
-          mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-          mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
-          mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
-          mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
+        // multiply by conjugated channel
+        mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
+        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
+        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
+        mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
+        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
+        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
 
-          rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-          //print_shorts("rx:",(int16_t*)&rxdataF128[2]);
-          //print_shorts("ch:",(int16_t*)&dl_ch128[2]);
-          //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]);
-
-          dl_ch128+=3;
-          dl_ch_mag128+=3;
-          dl_ch_mag128b+=3;
-          dl_ch_mag128r+=3;
-          rxdataF128+=3;
-          rxdataF_comp128+=3;
-        }
-        else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
-          dl_ch128+=2;
-	      dl_ch_mag128+=2;
-	      dl_ch_mag128b+=2;
-	      dl_ch_mag128r+=2;
-	      rxdataF128+=2;
-	      rxdataF_comp128+=2;
-	    }
+        rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+        //print_shorts("rx:",(int16_t*)&rxdataF128[2]);
+        //print_shorts("ch:",(int16_t*)&dl_ch128[2]);
+        //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]);
+
+        dl_ch128+=3;
+        dl_ch_mag128+=3;
+        dl_ch_mag128b+=3;
+        dl_ch_mag128r+=3;
+        rxdataF128+=3;
+        rxdataF_comp128+=3;
       }
     }
   }
@@ -989,7 +995,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
           rho128        = (__m128i *)&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12];
           dl_ch128_2    = (__m128i *)&dl_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
 
-          for (rb=0; rb<nb_rb; rb++) {
+          for (rb=0; rb<nb_rb_0; rb++) {
             // multiply by conjugated channel
             mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]);
             //  print_ints("re",&mmtmpD0);
@@ -1085,7 +1091,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
             //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],rb*12);
             avg_rho_re[aarx][aatx*nb_aatx+atx] = 16*avg_rho_re[aarx][aatx*nb_aatx+atx]/(nb_rb*12);
             avg_rho_im[aarx][aatx*nb_aatx+atx] = 16*avg_rho_im[aarx][aatx*nb_aatx+atx]/(nb_rb*12);
-            printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]);
+            //printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]);
           }
         }
       }
@@ -1097,7 +1103,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
 #elif defined(__arm__)
 
   unsigned short rb;
-  unsigned char aatx,aarx,symbol_mod,pilots=0;
+  unsigned char aatx,aarx,symbol_mod;
 
   int16x4_t *dl_ch128,*dl_ch128_2,*rxdataF128;
   int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b;
@@ -1110,14 +1116,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
 
   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->nb_antenna_ports_gNB==1) { // 10 out of 12 so don't reduce size
-      nb_rb=1+(5*nb_rb/6);
-    }
-    else {
-      pilots=1;
-    }
-  }
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
 
   for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) {
     if (mod_order == 4) {
@@ -1136,7 +1135,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
       rxdataF128        = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
       rxdataF_comp128   = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
 
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
   if (mod_order>2) {
     // get channel amplitude if not QPSK
     mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128[0]);
@@ -1152,23 +1151,20 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
     mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128[3]);
     mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
     mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-    if (pilots==0) {
-      mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]);
-      mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
-      mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]);
-      mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
-      mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-    }
+
+    mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]);
+    mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+    mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]);
+    mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+    mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
 
     dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
     dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
     dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
     dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);
 
-    if (pilots==0) {
-      dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
-      dl_ch_mag128[2]  = vqdmulhq_s16(mmtmpD4,QAM_amp128);
-    }
+    dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
+    dl_ch_mag128[2]  = vqdmulhq_s16(mmtmpD4,QAM_amp128);
   }
 
   mmtmpD0 = vmull_s16(dl_ch128[0], rxdataF128[0]);
@@ -1202,36 +1198,29 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
   mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
   rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
 
-  if (pilots==0) {
-    mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]);
-    mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]);
-    mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
-         vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
 
-    mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
-    mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
-    mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
-         vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+  mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]);
+  mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]);
+  mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+                         vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+
+  mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
+  mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
+  mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+                         vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
 
 
-    mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
-    mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
-    rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+  mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+  mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+  rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
 
 
-    dl_ch128+=6;
-    dl_ch_mag128+=3;
-    dl_ch_mag128b+=3;
-    rxdataF128+=6;
-    rxdataF_comp128+=3;
+  dl_ch128+=6;
+  dl_ch_mag128+=3;
+  dl_ch_mag128b+=3;
+  rxdataF128+=6;
+  rxdataF_comp128+=3;
 
-  } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
-    dl_ch128+=4;
-    dl_ch_mag128+=2;
-    dl_ch_mag128b+=2;
-    rxdataF128+=4;
-    rxdataF_comp128+=2;
-  }
       }
     }
   }
@@ -1241,7 +1230,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
       rho128        = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
       dl_ch128      = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
       dl_ch128_2    = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
   mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128_2[0]);
   mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128_2[1]);
   mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
@@ -1540,14 +1529,10 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
         dl_ch128[1] = _mm_mulhi_epi16(dl_ch128[1],ch_amp128);
         dl_ch128[1] = _mm_slli_epi16(dl_ch128[1],3);
 
-        if (pilots) {
-          dl_ch128+=2;
-        } else {
-          dl_ch128[2] = _mm_mulhi_epi16(dl_ch128[2],ch_amp128);
-          dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3);
-          dl_ch128+=3;
+        dl_ch128[2] = _mm_mulhi_epi16(dl_ch128[2],ch_amp128);
+        dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3);
+        dl_ch128+=3;
 
-        }
       }
     }
   }
@@ -1579,6 +1564,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
   //x = (x>4) ? 4 : x;
   int16_t y = (len)>>x;
   //printf("len = %d = %d * 2^(%d)\n",len,y,x);
+  uint32_t nb_rb_0 = len/12 + ((len%12)?1:0);
 
   AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__);
 
@@ -1589,7 +1575,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
 
       dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12];
 
-      for (rb=0;rb<nb_rb;rb++) {
+      for (rb=0;rb<nb_rb_0;rb++) {
         avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x));
         avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x));
         avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
@@ -1614,7 +1600,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
   int16x4_t *dl_ch128;
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
-
+  uint32_t nb_rb_0 = len/12 + ((len%12)?1:0);
   for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       //clear average level
@@ -1623,7 +1609,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
 
       dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
 
-      for (rb=0; rb<nb_rb; rb++) {
+      for (rb=0; rb<nb_rb_0; rb++) {
         //  printf("rb %d : ",rb);
         //  print_shorts("ch",&dl_ch128[0]);
         avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[0],dl_ch128[0]));
@@ -2072,7 +2058,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
 
   unsigned char j=0;
 
-  if (config_type==pdsch_dmrs_type1) {
+  if (config_type==NFAPI_NR_DMRS_TYPE1) {
     AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2,
                 "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
     nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1
@@ -2097,7 +2083,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
     rxF       = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))];
     
     for (rb = 0; rb < nb_rb_pdsch; rb++) {
-      if (k>frame_parms->ofdm_symbol_size) {
+      if (k>=frame_parms->ofdm_symbol_size) {
         k = k-frame_parms->ofdm_symbol_size;
         rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))];
       }
@@ -2108,7 +2094,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
         rxF_ext+=12;
       } else {//the symbol contains DMRS
         j=0;
-        if (config_type==pdsch_dmrs_type1){
+        if (config_type==NFAPI_NR_DMRS_TYPE1){
           if (nushift == 0) {//data is multiplexed
             for (i = (1-nushift); i<12; i+=2) {
               rxF_ext[j]=rxF[i];
@@ -2118,7 +2104,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
             dl_ch0_ext+=6;
             rxF_ext+=6;
           }
-        } else {//pdsch_dmrs_type2
+        } else {//NFAPI_NR_DMRS_TYPE2
           for (i = (2+nushift); i<6; i++) {
             rxF_ext[j]=rxF[i];
             dl_ch0_ext[j]=dl_ch0[i];
@@ -2166,7 +2152,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
   int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
   int8_t validDmrsEst = 0; //store last DMRS Symbol index
 
-  if (config_type==pdsch_dmrs_type1) {
+  if (config_type==NFAPI_NR_DMRS_TYPE1) {
     AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2,
                 "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
     nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1
@@ -2181,7 +2167,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
     k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb;
-    if (k>frame_parms->ofdm_symbol_size)
+    if (k>=frame_parms->ofdm_symbol_size)
       k = k-frame_parms->ofdm_symbol_size;
 
     rxF_ext   = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)];
@@ -2204,7 +2190,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
         }
         else {//the symbol contains DMRS
           j=0;
-          if (config_type==pdsch_dmrs_type1) {
+          if (config_type==NFAPI_NR_DMRS_TYPE1) {
             if (nushift == 0) {//data is multiplexed
               for (i = (1-nushift); i<12; i+=2) {
                 if (aatx==0) rxF_ext[j]=rxF[i];
@@ -2215,7 +2201,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
               if (aatx==0) rxF_ext+=6;
             }
           }
-          else {//pdsch_dmrs_type2
+          else {//NFAPI_NR_DMRS_TYPE2
             for (i = (2+nushift); i<6; i++) {
               if (aatx==0) rxF_ext[j]=rxF[i];
               dl_ch0_ext[j]=dl_ch0[i];
@@ -2250,43 +2236,55 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp,
                             int ***rho,
                             int **dl_ch_mag,
                             int **dl_ch_magb,
+                            int **dl_ch_magr,
                             short n_tx,
                             short n_rx,
                             unsigned char symbol,
-                            unsigned short nb_rb) {
+                            unsigned short nb_rb,
+                            int length) {
 #if defined(__x86_64__)||defined(__i386__)
   unsigned char aatx, aarx;
   int i;
-  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b;
+  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*dl_ch_mag128_0r,*dl_ch_mag128_1r;
+
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
 
   if (n_rx>1) {
     for (aatx=0; aatx<n_tx; aatx++) {
       rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx*n_rx)][symbol*nb_rb*12];//aarx=0
       dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[(aatx*n_rx)][symbol*nb_rb*12];//aarx=0
       dl_ch_mag128_0b     = (__m128i *)&dl_ch_magb[(aatx*n_rx)][symbol*nb_rb*12];
+      dl_ch_mag128_0r     = (__m128i *)&dl_ch_magr[(aatx*n_rx)][symbol*nb_rb*12];
       for (aarx=1; aarx<n_rx; aarx++) {
         rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx*n_rx)+aarx][symbol*nb_rb*12];// aarx=1,..., n_rx-1
         dl_ch_mag128_1      = (__m128i *)&dl_ch_mag[(aatx*n_rx)+aarx][symbol*nb_rb*12];
         dl_ch_mag128_1b     = (__m128i *)&dl_ch_magb[(aatx*n_rx)+aarx][symbol*nb_rb*12];
+        dl_ch_mag128_1r     = (__m128i *)&dl_ch_magr[(aatx*n_rx)+aarx][symbol*nb_rb*12];
 
-        // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
-        for (i=0; i<nb_rb*3; i++) {
+        // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM/256 llr computation)
+        for (i=0; i<nb_rb_0*3; i++) {
           rxdataF_comp128_0[i] = _mm_adds_epi16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
           dl_ch_mag128_0[i]    = _mm_adds_epi16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]);
           dl_ch_mag128_0b[i]   = _mm_adds_epi16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]);
-          /*if (i==0) {
-           * printf("atx%d symbol%d\n",aatx,symbol);
-           * printf("mrc comp0 re: %d mrc comp0 im: %d \n",((int16_t*)&rxdataF_comp128_0[0])[0],((int16_t*)&rxdataF_comp128_0[0])[1]);
-           * printf("mrc mag0 = %d = %d \n",((int16_t*)&dl_ch_mag128_0[0])[0],((int16_t*)&dl_ch_mag128_0[0])[1]);
-           * printf("mrc mag0b = %d = %d \n",((int16_t*)&dl_ch_mag128_0b[0])[0],((int16_t*)&dl_ch_mag128_0b[0])[1]);
-           * }*/
+          dl_ch_mag128_0r[i]   = _mm_adds_epi16(dl_ch_mag128_0r[i],dl_ch_mag128_1r[i]);
         }
       }
     }
+#ifdef DEBUG_DLSCH_DEMOD
+    for (i=0; i<nb_rb_0*3; i++) {
+    printf("symbol%d RB %d\n",symbol,i/3);
+    rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12];
+    rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12];
+    print_shorts("tx 1 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_0[i]);
+    print_shorts("tx 2 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_1[i]);
+    // printf("mrc mag0 = %d = %d \n",((int16_t*)&dl_ch_mag128_0[0])[0],((int16_t*)&dl_ch_mag128_0[0])[1]);
+    // printf("mrc mag0b = %d = %d \n",((int16_t*)&dl_ch_mag128_0b[0])[0],((int16_t*)&dl_ch_mag128_0b[0])[1]);
+    }
+#endif
     if (rho) {
       /*rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
       rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
-      for (i=0; i<nb_rb*3; i++) {
+      for (i=0; i<nb_rb_0*3; i++) {
         //      print_shorts("mrc rho0:",&rho128_0[i]);
         //      print_shorts("mrc rho1:",&rho128_1[i]);
         rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
@@ -2308,7 +2306,8 @@ void nr_det_HhH(int32_t *after_mf_00,//a
                 int32_t *after_mf_11,//d
                 int32_t *det_fin,//1/ad-bc
                 unsigned short nb_rb,
-                unsigned char symbol)
+                unsigned char symbol,
+                int32_t shift)
 {
   int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
   unsigned short rb;
@@ -2343,24 +2342,16 @@ void nr_det_HhH(int32_t *after_mf_00,//a
     det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128);
     //det_im_128 = _mm_sub_epi32(ad_im_128, bc_im_128);
 
-    //convert back to Q15 before packing
-    det_re_128 = _mm_srai_epi32(det_re_128,8);//(2^15/64*2)
-    //det_im_128 = _mm_srai_epi32(det_im_128,8);
-
-    //tmp_det0  = _mm_unpacklo_epi32(det_re_128,det_im_128);
-    ////print_ints("unpack lo:",&tmp_det0[rb]);
-    //tmp_det1  = _mm_unpackhi_epi32(det_re_128,det_im_128);
-    ////print_ints("unpack hi:",&tmp_det1[rb]);
-    //det_matrix_128[0] = _mm_packs_epi32(tmp_det0,tmp_det1);
+    //det in Q30 format
     det_fin_128[0] = _mm_abs_epi32(det_re_128);
 
-    /*if ((rb==0)&&(symbol==1)) {
-     * printf("\n Computing det_HhH_inv \n");
-     * print_ints("det_re_128:",(int32_t*)&det_re_128);
-     * print_ints("det_im_128:",(int32_t*)&det_im_128);
-     * print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]);
-     * }*/
 
+#ifdef DEBUG_DLSCH_DEMOD
+     printf("\n Computing det_HhH_inv \n");
+     //print_ints("det_re_128:",(int32_t*)&det_re_128);
+     //print_ints("det_im_128:",(int32_t*)&det_im_128);
+     print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]);
+#endif
     det_fin_128+=1;
     after_mf_00_128+=1;
     after_mf_01_128+=1;
@@ -2455,7 +2446,67 @@ void nr_conjch0_mult_ch1(int *ch0,
   _mm_empty();
   _m_empty();
 }
+__m128i nr_comp_muli_sum(__m128i input_x,
+                         __m128i input_y,
+                         __m128i input_w,
+                         __m128i input_z,
+                         __m128i det)
+{
+  int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
+
+  __m128i xy_re_128, xy_im_128, wz_re_128, wz_im_128;
+  __m128i output, tmp_z0, tmp_z1;
+
+  // complex multiplication (x_re + jx_im)*(y_re + jy_im) = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im)
+  // the real part
+  xy_re_128 = _mm_sign_epi16(input_x,*(__m128i*)&nr_conjug2[0]);
+  xy_re_128 = _mm_madd_epi16(xy_re_128,input_y); //Re: (x_re*y_re - x_im*y_im)
+
+  // the imag part
+  xy_im_128 = _mm_shufflelo_epi16(input_x,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+  xy_im_128 = _mm_shufflehi_epi16(xy_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+  xy_im_128 = _mm_madd_epi16(xy_im_128,input_y);//Im: (x_im*y_re + x_re*y_im)
+
+  // complex multiplication (w_re + jw_im)*(z_re + jz_im) = (w_re*z_re - w_im*z_im) + j(w_im*z_re + w_re*z_im)
+  // the real part
+  wz_re_128 = _mm_sign_epi16(input_w,*(__m128i*)&nr_conjug2[0]);
+  wz_re_128 = _mm_madd_epi16(wz_re_128,input_z); //Re: (w_re*z_re - w_im*z_im)
+
+  // the imag part
+  wz_im_128 = _mm_shufflelo_epi16(input_w,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+  wz_im_128 = _mm_shufflehi_epi16(wz_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
+  wz_im_128 = _mm_madd_epi16(wz_im_128,input_z);//Im: (w_im*z_re + w_re*z_im)
+
+
+  xy_re_128 = _mm_sub_epi32(xy_re_128, wz_re_128);
+  xy_im_128 = _mm_sub_epi32(xy_im_128, wz_im_128);
+  //print_ints("rx_re:",(int32_t*)&xy_re_128[0]);
+  //print_ints("rx_Img:",(int32_t*)&xy_im_128[0]);
+  //divide by matrix det and convert back to Q15 before packing
+  int sum_det =0;
+  for (int k=0; k<4;k++) {
+    sum_det += ((((int *)&det[0])[k])>>2);
+    //printf("det_%d = %d log2 =%d \n",k,(((int *)&det[0])[k]),log2_approx(((int *)&det[0])[k]));
+    }
+
+  xy_re_128 = _mm_slli_epi32(xy_re_128,5);
+  xy_re_128 = _mm_srai_epi32(xy_re_128,log2_approx(sum_det));
+  xy_re_128 = _mm_slli_epi32(xy_re_128,5);
+
+  xy_im_128 = _mm_slli_epi32(xy_im_128,5);
+  xy_im_128 = _mm_srai_epi32(xy_im_128,log2_approx(sum_det));
+  xy_im_128 = _mm_slli_epi32(xy_im_128,5);
 
+  tmp_z0  = _mm_unpacklo_epi32(xy_re_128,xy_im_128);
+  //print_ints("unpack lo:",&tmp_z0[0]);
+  tmp_z1  = _mm_unpackhi_epi32(xy_re_128,xy_im_128);
+  //print_ints("unpack hi:",&tmp_z1[0]);
+  output = _mm_packs_epi32(tmp_z0,tmp_z1);
+
+  _mm_empty();
+  _m_empty();
+  return(output);
+}
 /* Zero Forcing Rx function: nr_construct_HhH_elements()
  *
  *
@@ -2534,15 +2585,16 @@ void nr_construct_HhH_elements(int *conjch00_ch00,
     if (conjch21_ch20 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch21_ch20_128[0]);
     if (conjch31_ch30 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch31_ch30_128[0]);
 
-    /*if ((rb==0)&&(symbol==1))
+#ifdef DEBUG_DLSCH_DEMOD
+    if ((rb<=30))
     {
       printf(" \n construct_HhH_elements \n");
       print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]);
       print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]);
       print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]);
       print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]);
-    }*/
-
+    }
+#endif
     conjch00_ch00_128+=1;
     conjch10_ch10_128+=1;
     conjch01_ch01_128+=1;
@@ -2579,16 +2631,18 @@ void nr_construct_HhH_elements(int *conjch00_ch00,
 uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
                                    int **dl_ch_mag,
                                    int **dl_ch_magb,
+                                   int **dl_ch_magr,
                                    int **dl_ch_estimates_ext,
                                    unsigned short nb_rb,
                                    unsigned char n_rx,
                                    unsigned char mod_order,
                                    int shift,
-                                   unsigned char symbol)
+                                   unsigned char symbol,
+                                   int length)
 {
   int *ch00, *ch01, *ch10, *ch11;
   int *ch20, *ch30, *ch21, *ch31;
-
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
   /* we need at least alignment to 16 bytes, let's put 32 to be sure
    * (maybe not necessary but doesn't hurt)
    */
@@ -2656,49 +2710,49 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
     nr_conjch0_mult_ch1(ch00,
                         ch00,
                         conjch00_ch00,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
     // (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15
     nr_conjch0_mult_ch1(ch10,
                         ch10,
                         conjch10_ch10,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
     // conj_H_00xH_01
     nr_conjch0_mult_ch1(ch00,
                         ch01,
                         conjch00_ch01,
-                        nb_rb,
+                        nb_rb_0,
                         shift); // this shift is equal to the channel level log2_maxh
     // conj_H_10xH_11
     nr_conjch0_mult_ch1(ch10,
                         ch11,
                         conjch10_ch11,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
     // conj_H_01xH_01
     nr_conjch0_mult_ch1(ch01,
                         ch01,
                         conjch01_ch01,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
     // conj_H_11xH_11
     nr_conjch0_mult_ch1(ch11,
                         ch11,
                         conjch11_ch11,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
     // conj_H_01xH_00
     nr_conjch0_mult_ch1(ch01,
                         ch00,
                         conjch01_ch00,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
     // conj_H_11xH_10
     nr_conjch0_mult_ch1(ch11,
                         ch10,
                         conjch11_ch10,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
   }
   if (n_rx==4){
@@ -2706,52 +2760,52 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
     nr_conjch0_mult_ch1(ch20,
                         ch20,
                         conjch20_ch20,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     // (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15
     nr_conjch0_mult_ch1(ch30,
                         ch30,
                         conjch30_ch30,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15
     nr_conjch0_mult_ch1(ch20,
                         ch21,
                         conjch20_ch21,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     nr_conjch0_mult_ch1(ch30,
                         ch31,
                         conjch30_ch31,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     nr_conjch0_mult_ch1(ch21,
                         ch21,
                         conjch21_ch21,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     nr_conjch0_mult_ch1(ch31,
                         ch31,
                         conjch31_ch31,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15
     nr_conjch0_mult_ch1(ch21,
                         ch20,
                         conjch21_ch20,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     nr_conjch0_mult_ch1(ch31,
                         ch30,
                         conjch31_ch30,
-                        nb_rb,
+                        nb_rb_0,
                         shift);
 
     nr_construct_HhH_elements(conjch00_ch00,
@@ -2774,7 +2828,7 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
                               af_mf_01,
                               af_mf_10,
                               af_mf_11,
-                              nb_rb,
+                              nb_rb_0,
                               symbol);
   }
   if (n_rx==2){
@@ -2798,7 +2852,7 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
                               af_mf_01,
                               af_mf_10,
                               af_mf_11,
-                              nb_rb,
+                              nb_rb_0,
                               symbol);
   }
   //det_HhH = ad -bc
@@ -2807,8 +2861,9 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
              af_mf_10,//c
              af_mf_11,//d
              determ_fin,
-             nb_rb,
-             symbol);
+             nb_rb_0,
+             symbol,
+             shift);
   /* 2- Compute the channel matrix inversion **********************************
    *
      *    |(conj_H_00xH_00+conj_H_10xH_10)   (conj_H_00xH_01+conj_H_10xH_11)|
@@ -2822,92 +2877,106 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
      *
      *
      **************************************************************************/
-  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128b_0,*dl_ch_mag128_1,*dl_ch_mag128b_1,*determ_fin_128;
-  __m128i mmtmpD2,mmtmpD3,mmtmpD0,mmtmpD1,QAM_amp128,QAM_amp128b;
+  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128b_0,*dl_ch_mag128r_0,*determ_fin_128;//*dl_ch_mag128_1,*dl_ch_mag128b_1,*dl_ch_mag128r_1
+  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
   __m128i *after_mf_a_128,*after_mf_b_128, *after_mf_c_128, *after_mf_d_128;
+  __m128i QAM_amp128,QAM_amp128b,QAM_amp128r;
 
   determ_fin_128      = (__m128i *)&determ_fin[0];
 
   rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12];//aatx=0 @ aarx =0
   rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12];//aatx=1 @ aarx =0
 
-  dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[0][symbol*nb_rb*12];
-  dl_ch_mag128_1      = (__m128i *)&dl_ch_mag[n_rx][symbol*nb_rb*12];
-  dl_ch_mag128b_0     = (__m128i *)&dl_ch_magb[0][symbol*nb_rb*12];
-  dl_ch_mag128b_1     = (__m128i *)&dl_ch_magb[n_rx][symbol*nb_rb*12];
-
   after_mf_a_128 = (__m128i *)af_mf_00;
   after_mf_b_128 = (__m128i *)af_mf_01;
   after_mf_c_128 = (__m128i *)af_mf_10;
   after_mf_d_128 = (__m128i *)af_mf_11;
 
-  QAM_amp128b = _mm_setzero_si128();
-
-  if (mod_order == 4) {
-    QAM_amp128 = _mm_set1_epi16(QAM16_n1);  // 2/sqrt(10)
-    QAM_amp128b = _mm_setzero_si128();
-  } else if (mod_order == 6) {
-    QAM_amp128  = _mm_set1_epi16(QAM64_n1); //
-    QAM_amp128b = _mm_set1_epi16(QAM64_n2);
+  if (mod_order>2) {
+    if (mod_order == 4) {
+      QAM_amp128 = _mm_set1_epi16(QAM16_n1);  //2/sqrt(10)
+      QAM_amp128b = _mm_setzero_si128();
+      QAM_amp128r = _mm_setzero_si128();
+    } else if (mod_order == 6) {
+      QAM_amp128  = _mm_set1_epi16(QAM64_n1); //4/sqrt{42}
+      QAM_amp128b = _mm_set1_epi16(QAM64_n2); //2/sqrt{42}
+      QAM_amp128r = _mm_setzero_si128();
+    } else if (mod_order == 8) {
+      QAM_amp128 = _mm_set1_epi16(QAM256_n1); //8/sqrt{170}
+      QAM_amp128b = _mm_set1_epi16(QAM256_n2);//4/sqrt{170}
+      QAM_amp128r = _mm_set1_epi16(QAM256_n3);//2/sqrt{170}
+      }
+    dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[0][symbol*nb_rb*12];
+    dl_ch_mag128b_0     = (__m128i *)&dl_ch_magb[0][symbol*nb_rb*12];
+    dl_ch_mag128r_0     = (__m128i *)&dl_ch_magr[0][symbol*nb_rb*12];
   }
 
-  for (int rb=0; rb<3*nb_rb; rb++) {
+  for (int rb=0; rb<3*nb_rb_0; rb++) {
     if (mod_order>2) {
-      // get channel determ (da -bc) if not QPSK
-      mmtmpD0 = _mm_packs_epi32(determ_fin_128[0],determ_fin_128[0]);//convert 32 bits to 16 bits
+      int sum_det =0;
+      for (int k=0; k<4;k++) {
+        sum_det += ((((int *)&determ_fin_128[0])[k])>>2);
+        //printf("det_%d = %d\n",k,sum_det);
+        }
+
+      mmtmpD2 = _mm_slli_epi32(determ_fin_128[0],5);
+      mmtmpD2 = _mm_srai_epi32(mmtmpD2,log2_approx(sum_det));
+      mmtmpD2 = _mm_slli_epi32(mmtmpD2,5);
+
+      mmtmpD3 = _mm_unpacklo_epi32(mmtmpD2,mmtmpD2);
+
+      mmtmpD2 = _mm_unpackhi_epi32(mmtmpD2,mmtmpD2);
 
-      dl_ch_mag128_0[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0);
-      dl_ch_mag128b_0[0] = dl_ch_mag128_0[0];
+      mmtmpD2 = _mm_packs_epi32(mmtmpD3,mmtmpD2);
+
+      dl_ch_mag128_0[0] = mmtmpD2;
+      dl_ch_mag128b_0[0] = mmtmpD2;
+      dl_ch_mag128r_0[0] = mmtmpD2;
 
       dl_ch_mag128_0[0] = _mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128);
-      dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);//aatx=0 @ aarx =0
-      dl_ch_mag128_1[0] = dl_ch_mag128_0[0];//aatx=1 @ aarx =0
+      dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);
 
       dl_ch_mag128b_0[0] = _mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b);
-      dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1);//aatx=0 @ aarx =
-      dl_ch_mag128b_1[0] = dl_ch_mag128b_0[0];//aatx=1 @ aarx =0
-
-      if ((rb==0)&&(symbol==1)) {
-        printf("\n Signal mag after ZF \n");
-        print_shorts("mag layer 1:",(int16_t*)&dl_ch_mag128_0[0]);
-        print_shorts("mag layer 2:",(int16_t*)&dl_ch_mag128_1[0]);
-        print_shorts("magb layer 1:",(int16_t*)&dl_ch_mag128b_0[0]);
-        print_shorts("magb layer 2:",(int16_t*)&dl_ch_mag128b_1[0]);
-       }
+      dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1);
+
+      dl_ch_mag128r_0[0] = _mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r);
+      dl_ch_mag128r_0[0] = _mm_slli_epi16(dl_ch_mag128r_0[0],1);
+
+      //print_shorts("mag layer 1:",(int16_t*)&dl_ch_mag128_0[0]);
+      //print_shorts("mag layer 2:",(int16_t*)&dl_ch_mag128_1[0]);
+      //print_shorts("magb layer 1:",(int16_t*)&dl_ch_mag128b_0[0]);
+      //print_shorts("magb layer 2:",(int16_t*)&dl_ch_mag128b_1[0]);
+      //print_shorts("magr layer 1:",(int16_t*)&dl_ch_mag128r_0[0]);
+      //print_shorts("magr layer 2:",(int16_t*)&dl_ch_mag128r_1[0]);
     }
     // multiply by channel Inv
     //rxdataF_zf128_0 = rxdataF_comp128_0*d - b*rxdataF_comp128_1
     //rxdataF_zf128_1 = rxdataF_comp128_1*a - c*rxdataF_comp128_0
-    mmtmpD2 = nr_inv_comp_muli(rxdataF_comp128_0[0],//x
-                               after_mf_d_128[0]);//y
-    mmtmpD3 = nr_inv_comp_muli(rxdataF_comp128_1[0],//x
-                               after_mf_b_128[0]);//y
-    //mmtmpD2[0] - mmtmpD3[0]
-    //rxdataF_zf128_0
-    mmtmpD0 = _mm_sub_epi16(mmtmpD2, mmtmpD3);
-
-    mmtmpD2 = nr_inv_comp_muli(rxdataF_comp128_1[0],//x
-                               after_mf_a_128[0]);//y
-    mmtmpD3 = nr_inv_comp_muli(rxdataF_comp128_0[0],//x
-                               after_mf_c_128[0]);//y
-    //mmtmpD2[0] - mmtmpD3[0]
-    //rxdataF_zf128_1
-    mmtmpD1 = _mm_sub_epi16(mmtmpD2, mmtmpD3);
+    //printf("layer_1 \n");
+    mmtmpD0 = nr_comp_muli_sum(rxdataF_comp128_0[0],
+                               after_mf_d_128[0],
+                               rxdataF_comp128_1[0],
+                               after_mf_b_128[0],
+                               determ_fin_128[0]);
+
+    //printf("layer_2 \n");
+    mmtmpD1 = nr_comp_muli_sum(rxdataF_comp128_1[0],
+                               after_mf_a_128[0],
+                               rxdataF_comp128_0[0],
+                               after_mf_c_128[0],
+                               determ_fin_128[0]);
 
     rxdataF_comp128_0[0] = mmtmpD0;
     rxdataF_comp128_1[0] = mmtmpD1;
-
-    /*if ((rb==0)&&(symbol==1)) {
-      printf("\n Rx signal after ZF \n");
-      print_shorts("Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]);
-      print_shorts("Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]);
-    }*/
-
+#ifdef DEBUG_DLSCH_DEMOD
+    printf("\n Rx signal after ZF l%d rb%d\n",symbol,rb);
+    print_shorts(" Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]);
+    print_shorts(" Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]);
+#endif
     determ_fin_128 += 1;
     dl_ch_mag128_0 += 1;
     dl_ch_mag128b_0 += 1;
-    dl_ch_mag128_1 += 1;
-    dl_ch_mag128b_1 += 1;
+    dl_ch_mag128r_0 += 1;
     rxdataF_comp128_0 += 1;
     rxdataF_comp128_1 += 1;
     after_mf_a_128 += 1;
@@ -2923,13 +2992,18 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
 static void nr_dlsch_layer_demapping(int16_t **llr_cw,
 				     uint8_t Nl,
 				     uint8_t mod_order,
-				     uint16_t length,
+				     uint32_t length,
+				     int32_t codeword_TB0,
+				     int32_t codeword_TB1,
 				     int16_t **llr_layers) {
 
   switch (Nl) {
-
     case 1:
-      memcpy((void*)llr_layers[0], (void*)llr_cw[0], (length)*sizeof(int16_t));
+      if (codeword_TB1 == -1)
+        memcpy((void*)llr_cw[0], (void*)llr_layers[0], (length)*sizeof(int16_t));
+      else if (codeword_TB0 == -1)
+        memcpy((void*)llr_cw[1], (void*)llr_layers[0], (length)*sizeof(int16_t));
+
     break;
 
     case 2:
@@ -2937,11 +3011,15 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw,
     case 4:
       for (int i=0; i<(length/Nl/mod_order); i++){
         for (int l=0; l<Nl; l++) {
-        	for (int m=0; m<mod_order; m++){
-        		llr_cw[0][Nl*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];
-        	}
+          for (int m=0; m<mod_order; m++){
+            if (codeword_TB1 == -1)
+              llr_cw[0][Nl*mod_order*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];//i:0 -->0 1 2 3
+            else if (codeword_TB0 == -1)
+              llr_cw[1][Nl*mod_order*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];//i:0 -->0 1 2 3
+            //if (i<4) printf("length%d: llr_layers[l%d][m%d]=%d: \n",length,l,m,llr_layers[l][i*mod_order+m]);
+            }
+          }
         }
-  	  }
     break;
 
   default:
@@ -3009,299 +3087,110 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
 
   switch (dlsch0_harq->Qm) {
   case 2 :
-    if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
-      nr_dlsch_qpsk_llr(frame_parms,
-                        pdsch_vars[gNB_id]->rxdataF_comp0,
-                        pllr_symbol_cw0,
-                        symbol,
-                        len,
-                        first_symbol_flag,
-                        nb_rb,
-                        beamforming_mode);
-
-    } else if (codeword_TB0 == -1){
-
-      nr_dlsch_qpsk_llr(frame_parms,
-                        pdsch_vars[gNB_id]->rxdataF_comp0,
-                        pllr_symbol_cw1,
-                        symbol,
-                        len,
-                        first_symbol_flag,
-                        nb_rb,
-                        beamforming_mode);
-    }
-    else if (rx_type >= rx_IC_single_stream) {
-      if (dlsch1_harq->Qm == 2) {
-        nr_dlsch_qpsk_qpsk_llr(frame_parms,
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_qpsk_llr(frame_parms,
+                            pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                            pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                            symbol,
+                            len,
+                            first_symbol_flag,
+                            nb_rb,
+                            beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        /*nr_dlsch_qpsk_qpsk_llr(frame_parms,
                                pdsch_vars[gNB_id]->rxdataF_comp0,
                                rxdataF_comp_ptr,
                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
                                pdsch_vars[gNB_id]->layer_llr[0],
                                symbol,len,first_symbol_flag,nb_rb,
                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                               pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_qpsk_qpsk_llr(frame_parms,
-                                 rxdataF_comp_ptr,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                 pdsch_vars[gNB_id]->layer_llr[1],
-                                 symbol,len,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else if (dlsch1_harq->Qm == 4) {
-        nr_dlsch_qpsk_16qam_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                dl_ch_mag_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_16qam_qpsk_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  dl_ch_mag_ptr,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,first_symbol_flag,nb_rb,
-                                  adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                  pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else {
-        nr_dlsch_qpsk_64qam_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                dl_ch_mag_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_64qam_qpsk_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  dl_ch_mag_ptr,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,first_symbol_flag,nb_rb,
-                                  adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                  pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
+                               pdsch_vars[gNB_id]->llr128);*/
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        /*nr_dlsch_qpsk_qpsk_llr(frame_parms,
+                               rxdataF_comp_ptr,
+                               pdsch_vars[gNB_id]->rxdataF_comp0,
+                               pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
+                               pdsch_vars[gNB_id]->layer_llr[1],
+                               symbol,len,first_symbol_flag,nb_rb,
+                               adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
+                               pdsch_vars[gNB_id]->llr128_2ndstream);*/
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
     break;
   case 4 :
-    if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) {
-      nr_dlsch_16qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         pdsch_vars[gNB_id]->llr[0],
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr128,
-                         beamforming_mode);
-    } else if (codeword_TB0 == -1){
-      nr_dlsch_16qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         pdsch_vars[gNB_id]->llr[1],
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr128_2ndstream,
-                         beamforming_mode);
-    }
-    else if (rx_type >= rx_IC_single_stream) {
-      if (dlsch1_harq->Qm == 2) {
-        nr_dlsch_16qam_qpsk_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_mag0,
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_qpsk_16qam_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,first_symbol_flag,nb_rb,
-                                  adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                  pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else if (dlsch1_harq->Qm == 4) {
-        nr_dlsch_16qam_16qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 pdsch_vars[gNB_id]->layer_llr[0],
-                                 symbol,len,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_16qam_16qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pdsch_vars[gNB_id]->layer_llr[1],
-                                   symbol,len,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else {
-        nr_dlsch_16qam_64qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 pdsch_vars[gNB_id]->layer_llr[0],
-                                 symbol,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_64qam_16qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pdsch_vars[gNB_id]->layer_llr[1],
-                                   symbol,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_16qam_llr(frame_parms,
+                             pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                             pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                             pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                             symbol,
+                             len,
+                             first_symbol_flag,
+                             nb_rb,
+                             beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
     break;
   case 6 :
-    if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
-      nr_dlsch_64qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         (int16_t*)pllr_symbol_cw0,
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         pdsch_vars[gNB_id]->dl_ch_magb0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr_offset[symbol],
-                         beamforming_mode);
-    } else if (codeword_TB0 == -1){
-      nr_dlsch_64qam_llr(frame_parms,
-                         pdsch_vars[gNB_id]->rxdataF_comp0,
-                         pllr_symbol_cw1,
-                         pdsch_vars[gNB_id]->dl_ch_mag0,
-                         pdsch_vars[gNB_id]->dl_ch_magb0,
-                         symbol,len,first_symbol_flag,nb_rb,
-                         pdsch_vars[gNB_id]->llr_offset[symbol],
-                         beamforming_mode);
-    }
-    else if (rx_type >= rx_IC_single_stream) {
-      if (dlsch1_harq->Qm == 2) {
-        nr_dlsch_64qam_qpsk_llr(frame_parms,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                rxdataF_comp_ptr,//i
-                                pdsch_vars[gNB_id]->dl_ch_mag0,
-                                pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                pdsch_vars[gNB_id]->layer_llr[0],
-                                symbol,first_symbol_flag,nb_rb,
-                                adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_qpsk_64qam_llr(frame_parms,
-                                  rxdataF_comp_ptr,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                  pdsch_vars[gNB_id]->dl_ch_mag0,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->layer_llr[1],
-                                  symbol,first_symbol_flag,nb_rb,
-                                  adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                                  pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else if (dlsch1_harq->Qm == 4) {
-        nr_dlsch_64qam_16qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 pdsch_vars[gNB_id]->layer_llr[0],
-                                 symbol,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr128);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_16qam_64qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pdsch_vars[gNB_id]->layer_llr[1],
-                                   symbol,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr128_2ndstream);
-        }
-      }
-      else {
-        nr_dlsch_64qam_64qam_llr(frame_parms,
-                                 pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 rxdataF_comp_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 dl_ch_mag_ptr,//i
-                                 pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                 (int16_t*)pllr_symbol_layer0,
-                                 symbol,len,first_symbol_flag,nb_rb,
-                                 adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                 pdsch_vars[gNB_id]->llr_offset[symbol]);
-        if (rx_type==rx_IC_dual_stream) {
-          nr_dlsch_64qam_64qam_llr(frame_parms,
-                                   rxdataF_comp_ptr,
-                                   pdsch_vars[gNB_id]->rxdataF_comp0,//i
-                                   dl_ch_mag_ptr,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,//i
-                                   pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                   pllr_symbol_layer1,
-                                   symbol,len,first_symbol_flag,nb_rb,
-                                   adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
-                                   pdsch_vars[gNB_id]->llr_offset[symbol]);
-        }
-      }
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_64qam_llr(frame_parms,
+                             pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                             pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                             pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                             pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                             symbol,
+                             len,
+                             first_symbol_flag,
+                             nb_rb,
+                             beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
+
     break;
   case 8:
-    if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
-      nr_dlsch_256qam_llr(frame_parms,
-                      pdsch_vars[gNB_id]->rxdataF_comp0,
-                      (int16_t*)pllr_symbol_cw0,
-                      pdsch_vars[gNB_id]->dl_ch_mag0,
-                      pdsch_vars[gNB_id]->dl_ch_magb0,
-                      pdsch_vars[gNB_id]->dl_ch_magr0,
-                      symbol,len,first_symbol_flag,nb_rb,
-                      pdsch_vars[gNB_id]->llr_offset[symbol],
-                      beamforming_mode);
-    } else if (codeword_TB0 == -1){
-      nr_dlsch_256qam_llr(frame_parms,
-                      pdsch_vars[gNB_id]->rxdataF_comp0,
-                      pllr_symbol_cw1,
-                      pdsch_vars[gNB_id]->dl_ch_mag0,
-                      pdsch_vars[gNB_id]->dl_ch_magb0,
-                      pdsch_vars[gNB_id]->dl_ch_magr0,
-                      symbol,len,first_symbol_flag,nb_rb,
-                      pdsch_vars[gNB_id]->llr_offset[symbol],
-                      beamforming_mode);
+    switch (rx_type) {
+      case rx_standard :
+        for(int l =0; l<dlsch0_harq->Nl; l++)
+          nr_dlsch_256qam_llr(frame_parms,
+                              pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
+                              pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                              pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                              pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                              pdsch_vars[gNB_id]->dl_ch_magr0[0],
+                              symbol,
+                              len,
+                              first_symbol_flag,
+                              nb_rb,
+                              beamforming_mode);
+        break;
+      case rx_IC_single_stream ://not implemented yet
+        break;
+      case rx_IC_dual_stream ://not implemented yet
+        break;
+      case rx_SIC_dual_stream ://not implemented yet
+        break;
     }
     break;
   default:
@@ -3315,45 +3204,54 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
     case 2 :
       if (rx_type==rx_standard) {
         nr_dlsch_qpsk_llr(frame_parms,
-                          pdsch_vars[gNB_id]->rxdataF_comp0,
-                          pllr_symbol_cw0,
-                          symbol,len,first_symbol_flag,nb_rb,
+                          pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                          pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                          symbol,
+                          len,
+                          first_symbol_flag,
+                          nb_rb,
                           beamforming_mode);
       }
       break;
     case 4:
       if (rx_type==rx_standard) {
         nr_dlsch_16qam_llr(frame_parms,
-                           pdsch_vars[gNB_id]->rxdataF_comp0,
-                           pdsch_vars[gNB_id]->llr[0],
-                           pdsch_vars[gNB_id]->dl_ch_mag0,
-                           symbol,len,first_symbol_flag,nb_rb,
-                           pdsch_vars[gNB_id]->llr128,
+                           pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                           pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                           pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                           symbol,
+                           len,
+                           first_symbol_flag,
+                           nb_rb,
                            beamforming_mode);
       }
       break;
     case 6 :
       if (rx_type==rx_standard) {
         nr_dlsch_64qam_llr(frame_parms,
-                           pdsch_vars[gNB_id]->rxdataF_comp0,
-                           pllr_symbol_cw0,
-                             pdsch_vars[gNB_id]->dl_ch_mag0,
-                             pdsch_vars[gNB_id]->dl_ch_magb0,
-                             symbol,len,first_symbol_flag,nb_rb,
-                             pdsch_vars[gNB_id]->llr_offset[symbol],
-                             beamforming_mode);
+                           pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                           pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                           pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                           pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                           symbol,
+                           len,
+                           first_symbol_flag,
+                           nb_rb,
+                           beamforming_mode);
         }
         break;
     case 8 :
       if (rx_type==rx_standard) {
         nr_dlsch_256qam_llr(frame_parms,
-                            pdsch_vars[gNB_id]->rxdataF_comp0,
-                            pllr_symbol_cw0,
-                            pdsch_vars[gNB_id]->dl_ch_mag0,
-                            pdsch_vars[gNB_id]->dl_ch_magb0,
-                            pdsch_vars[gNB_id]->dl_ch_magr0,
-                            symbol,len,first_symbol_flag,nb_rb,
-                            pdsch_vars[gNB_id]->llr_offset[symbol],
+                            pdsch_vars[gNB_id]->rxdataF_comp0[0],
+                            pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                            pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                            pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                            pdsch_vars[gNB_id]->dl_ch_magr0[0],
+                            symbol,
+                            len,
+                            first_symbol_flag,
+                            nb_rb,
                             beamforming_mode);
       }
         break;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
index 68a206e7c746ec709312e4cb29bee5e7824ff4c3..a064a91d87eaee53622854dbecb986eadcd69ccb 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
@@ -629,16 +629,16 @@ __m128i tmp_result4 __attribute__ ((aligned(16)));
 //----------------------------------------------------------------------------------------------
 
 int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
-                   int32_t **rxdataF_comp,
+                   int32_t *rxdataF_comp,
                    int16_t *dlsch_llr,
                    uint8_t symbol,
-				   uint32_t len,
-				   uint8_t first_symbol_flag,
+                   uint32_t len,
+                   uint8_t first_symbol_flag,
                    uint16_t nb_rb,
                    uint8_t beamforming_mode)
 {
 
-  uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*nb_rb*12)];
+  uint32_t *rxF = (uint32_t *)&rxdataF_comp[((int32_t)symbol*nb_rb*12)];
   uint32_t *llr32;
   int i;
 
@@ -670,24 +670,23 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
 //----------------------------------------------------------------------------------------------
 
 void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
+                     int32_t *dl_ch_mag,
                      uint8_t symbol,
-					 uint32_t len,
+                     uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     int16_t **llr32p,
                      uint8_t beamforming_mode)
 {
 
 #if defined(__x86_64__) || defined(__i386__)
-  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
   __m128i *ch_mag;
   __m128i llr128[2];
   uint32_t *llr32;
 #elif defined(__arm__)
-  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[(symbol*nb_rb*12)];
   int16x8_t *ch_mag;
   int16x8_t xmm0;
   int16_t *llr16;
@@ -699,30 +698,17 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
 
 
 #if defined(__x86_64__) || defined(__i386__)
-  if (first_symbol_flag==1) {
     llr32 = (uint32_t*)dlsch_llr;
-  } else {
-    llr32 = (uint32_t*)*llr32p;
-  }
 #elif defined(__arm__)
-  if (first_symbol_flag==1) {
     llr16 = (int16_t*)dlsch_llr;
-  } else {
-    llr16 = (int16_t*)*llr32p;
-  }
 #endif
 
 #if defined(__x86_64__) || defined(__i386__)
-  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)];
+  ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)];
 #elif defined(__arm__)
-  ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
+  ch_mag = (int16x8_t*)&dl_ch_mag[(symbol*nb_rb*12)];
 #endif
 
-  // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE)
-  if (first_symbol_flag == 1)
-    *llr32p = dlsch_llr + (len<<2);
-  else
-    *llr32p += (len<<2);
 
  // printf("len=%d\n", len);
   len_mod4 = len&3;
@@ -786,47 +772,35 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
 //----------------------------------------------------------------------------------------------
 
 void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-			int32_t **rxdataF_comp,
+			int32_t *rxdataF_comp,
 			int16_t *dlsch_llr,
-			int32_t **dl_ch_mag,
-			int32_t **dl_ch_magb,
+			int32_t *dl_ch_mag,
+			int32_t *dl_ch_magb,
 			uint8_t symbol,
 			uint32_t len,
 			uint8_t first_symbol_flag,
 			uint16_t nb_rb,
-			uint32_t llr_offset,
 			uint8_t beamforming_mode)
 {
 #if defined(__x86_64__) || defined(__i386__)
-  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
   __m128i *ch_mag,*ch_magb;
 #elif defined(__arm__)
-  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[(symbol*nb_rb*12)];
   int16x8_t *ch_mag,*ch_magb,xmm1,xmm2;
 #endif
   int i,len2;
   unsigned char len_mod4;
-  short *llr;
   int16_t *llr2;
-  int8_t *pllr_symbol;
-
-  /*
-  if (first_symbol_flag==1)
-    llr = dlsch_llr;
-  else
-    llr = *llr_save;
-  */
-  llr = dlsch_llr;
 
-  pllr_symbol = (int8_t*)dlsch_llr;
-  pllr_symbol += llr_offset;
+  llr2 = dlsch_llr;
 
 #if defined(__x86_64__) || defined(__i386__)
-  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)];
-  ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*nb_rb*12)];
+  ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)];
+  ch_magb = (__m128i*)&dl_ch_magb[(symbol*nb_rb*12)];
 #elif defined(__arm__)
-  ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
-  ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*nb_rb*12)];
+  ch_mag = (int16x8_t*)&dl_ch_mag[(symbol*nb_rb*12)];
+  ch_magb = (int16x8_t*)&dl_ch_magb[(symbol*nb_rb*12)];
 #endif
 
 //  printf("nr_dlsch_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
@@ -838,9 +812,6 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
              dlsch_llr,
              pllr_symbol);*/
 
-  llr2 = llr;
-  llr += (len*6);
-
   len_mod4 =len&3;
   len2=len>>2;  // length in quad words (4 REs)
   len2+=((len_mod4==0)?0:1);
@@ -1095,43 +1066,29 @@ void nr_dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
 //----------------------------------------------------------------------------------------------
 
 void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
-                     int32_t **dl_ch_magb,
-                     int32_t **dl_ch_magr,
+                     int32_t *dl_ch_mag,
+                     int32_t *dl_ch_magb,
+                     int32_t *dl_ch_magr,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     uint32_t llr_offset,
                      uint8_t beamforming_mode)
 {
-  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)];
+  __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
   __m128i *ch_mag,*ch_magb,*ch_magr;
 
   int i,len2;
   unsigned char len_mod4;
-  short *llr;
   int16_t *llr2;
-  int8_t *pllr_symbol;
-
-  /*
-  if (first_symbol_flag==1)
-    llr = dlsch_llr;
-  else
-    llr = *llr_save;
-  */
-  llr = dlsch_llr;
 
-  pllr_symbol = (int8_t*)dlsch_llr;
-  pllr_symbol += llr_offset;
+  llr2 = dlsch_llr;
 
-  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)];
-  ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*nb_rb*12)];
-  ch_magr = (__m128i*)&dl_ch_magr[0][(symbol*nb_rb*12)];
-  llr2 = llr;
-  llr += (len*8);
+  ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)];
+  ch_magb = (__m128i*)&dl_ch_magb[(symbol*nb_rb*12)];
+  ch_magr = (__m128i*)&dl_ch_magr[(symbol*nb_rb*12)];
 
   len_mod4 =len&3;
   len2=len>>2;  // length in quad words (4 REs)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
index 1e7e10def70891889b033605743d55b403711e95..eb56c76366b1a855affd2d438bca4666b81a2349 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -471,7 +471,7 @@ int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
     @param beamforming_mode beamforming mode
 */
 int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
-                   int32_t **rxdataF_comp,
+                   int32_t *rxdataF_comp,
                    int16_t *dlsch_llr,
                    uint8_t symbol,
 				   uint32_t len,
@@ -505,14 +505,13 @@ int32_t nr_dlsch_qpsk_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
                            uint32_t rb_alloc);
 
 void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
+                     int32_t *dl_ch_mag,
                      uint8_t symbol,
-					 uint32_t len,
+                     uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     int16_t **llr32p,
                      uint8_t beamforming_mode);
 /**
    \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
@@ -553,28 +552,26 @@ void dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
                          uint32_t rb_alloc);
 
 void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
-                     int32_t **dl_ch_magb,
+                     int32_t *dl_ch_mag,
+                     int32_t *dl_ch_magb,
                      uint8_t symbol,
-					 uint32_t len,
+                     uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     uint32_t llr_offset,
                      uint8_t beamforming_mode);
 
 void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
-                     int32_t **rxdataF_comp,
+                     int32_t *rxdataF_comp,
                      int16_t *dlsch_llr,
-                     int32_t **dl_ch_mag,
-                     int32_t **dl_ch_magb,
-                     int32_t **dl_ch_magr,
+                     int32_t *dl_ch_mag,
+                     int32_t *dl_ch_magb,
+                     int32_t *dl_ch_magr,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
-                     uint32_t llr_offset,
                      uint8_t beamforming_mode);
 
 /** \fn dlsch_siso(NR_DL_FRAME_PARMS *frame_parms,
@@ -807,7 +804,7 @@ void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
                                 NR_DL_FRAME_PARMS *frame_parms,
                                 uint8_t nb_aatx,
                                 uint8_t symbol,
-								uint8_t start_symbol,
+                                int length,
                                 uint8_t first_symbol_flag,
                                 uint8_t mod_order,
                                 uint16_t nb_rb,
@@ -891,13 +888,15 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
                                 int start_point);
 
 void nr_dlsch_detection_mrc(int **rxdataF_comp,
-        int ***rho,
-        int **dl_ch_mag,
-        int **dl_ch_magb,
-        short n_tx,
-        short n_rx,
-        unsigned char symbol,
-        unsigned short nb_rb);
+                            int ***rho,
+                            int **dl_ch_mag,
+                            int **dl_ch_magb,
+                            int **dl_ch_magr,
+                            short n_tx,
+                            short n_rx,
+                            unsigned char symbol,
+                            unsigned short nb_rb,
+                            int length);
 
 void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
                               int **rxdataF_comp_i,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index fae6b5b2e79c4c3570d27420d414fc469b66d40b..bab801e0e36c3aad81b9309e050354b839effb06 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -114,7 +114,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
   NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
   NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
-  // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
 
   uint8_t  num_of_codewords = 1; // tmp assumption
   int      Nid_cell = 0;
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index e3c0737838005c222b833a0d4b6e8d8aa3f56633..0625c6b05022c86a959818b797ebdb0db8b8a73f 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -963,25 +963,9 @@ typedef struct {
 
   //#if defined(UPGRADE_RAT_NR)
 #if 1
-
   SystemInformationBlockType1_nr_t systemInformationBlockType1_nr;
-
-  CellGroupConfig_t          cell_group_config;
-  PDSCH_ServingCellConfig_t  PDSCH_ServingCellConfig;
-  PDSCH_Config_t             PDSCH_Config;
-
   PUCCH_ConfigCommon_nr_t    pucch_config_common_nr[NUMBER_OF_CONNECTED_gNB_MAX];
   PUCCH_Config_t             pucch_config_dedicated_nr[NUMBER_OF_CONNECTED_gNB_MAX];
-
-  PUSCH_Config_t             pusch_config;
-  SRS_NR                     srs;
-
-  crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig;
-  supplementaryUplink_t supplementaryUplink;
-  dmrs_DownlinkConfig_t dmrs_DownlinkConfig;
-  csi_MeasConfig_t csi_MeasConfig;
-  PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig;
-
 #endif
 
   uint8_t ncs_cell[20][7];
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index d1d69ecabe8c9682c4fd453af587a4ebcfe40b4c..d333732d1fdbadb64e0a491e88177c493277e855 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -93,18 +93,18 @@
 #define NR_MAX_CSET_DURATION 3
 
 #define NR_MAX_NB_RBG 18
-#define NR_MAX_NB_LAYERS 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3)
+#define NR_MAX_NB_LAYERS 2 // 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3)
 #define NR_MAX_NB_CODEWORDS 2
 #define NR_MAX_NB_HARQ_PROCESSES 16
-#define NR_MAX_PDSCH_ENCODED_LENGTH NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS // 8 is the maximum modulation order (it was 950984 before !!) 
+#define NR_MAX_PDSCH_ENCODED_LENGTH (NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS) // 8 is the maximum modulation order (it was 950984 before !!)
 #define NR_MAX_PUSCH_ENCODED_LENGTH NR_MAX_PDSCH_ENCODED_LENGTH
 #define NR_MAX_PDSCH_TBS 3824
 #define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.
 
-#define MAX_NUM_NR_DLSCH_SEGMENTS 34
+#define MAX_NUM_NR_DLSCH_SEGMENTS (NR_MAX_NB_LAYERS*34)
 #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
 
-#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS
+#define MAX_NUM_NR_ULSCH_SEGMENTS 34
 #define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056)
 
 #define MAX_NUM_NR_CHANNEL_BITS (14*273*12*8)  // 14 symbols, 273 RB
diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h
index a74c3675a445a65da95b4d5287e4ca5df23fe6b7..93dbf513e85e0c1a944df3e3de4d8a1bbc5ed1f0 100644
--- a/openair1/PHY/impl_defs_nr.h
+++ b/openair1/PHY/impl_defs_nr.h
@@ -339,124 +339,22 @@ typedef struct {
 *
 ************************************************************************/
 
-/* FFS TODO_NR partial structure that should be complete */
-
-typedef enum {
-  semiStatic = 0,
-  dynamic =    1
-} pdsch_HARQ_ACK_Codebook_t;
-
-
-////////////////////////////////////////////////////////////////////////////////################################
 #define MAX_NR_RATE_MATCH_PATTERNS            4
 #define MAX_NR_ZP_CSI_RS_RESOURCES           32
 #define MAX_NR_OF_DL_ALLOCATIONS             16
 #define MAX_NR_OF_UL_ALLOCATIONS            (16)
 
-typedef enum{
-  dl_resourceAllocationType0 = 1,
-  dl_resourceAllocationType1 = 2,
-  dl_dynamicSwitch = 3
-} dl_resourceAllocation_t;
-typedef enum{
-  dl_rgb_config1 = 1,
-  dl_rgb_config2 = 2
-} dl_rgb_Size_t;
-typedef enum {
-  st_n4       = 1,
-  st_wideband = 2
-} static_bundleSize_t;
-typedef enum {
-  dy_1_n4       = 1,
-  dy_1_wideband = 2,
-  dy_1_n2_wideband = 3,
-  dy_1_n4_wideband = 4
-} bundleSizeSet1_t;
-typedef enum {
-  dy_2_n4       = 1,
-  dy_2_wideband = 2,
-} bundleSizeSet2_t;
-typedef struct{
-  bundleSizeSet1_t bundleSizeSet1;
-  bundleSizeSet2_t bundleSizeSet2;
-} dynamic_bundleSize_t;
-typedef struct {
-  static_bundleSize_t staticBundling;
-  dynamic_bundleSize_t dynamicBundlig;
-} prb_bundleType_t;
 typedef enum {
-  nb_code_n1 = 1,
-  nb_code_n2 = 2
-} maxNrofCodeWordsScheduledByDCI_t;
-typedef struct{
-// to be defined FIXME!!!
-}rateMatchPattern_t;
-typedef struct{
-// to be defined FIXME!!!
-}zp_CSI_RS_Resource_t;
-
-typedef struct{
-        int   k0;    
-        int     mappingType;
-        int     startSymbolAndLength;
-
-}PDSCH_TimeDomainResourceAllocation_t;
-typedef struct {
-/*
- * resourceAllocation
- */
-  dl_resourceAllocation_t dl_resourceAllocation;
-/*
- * corresponds to I, where I the number of entries in the higher layer parameter pdsch-AllocationList
- */
-  uint8_t n_pdsh_alloc_list;
-/*
- * rateMatchPatternToAddModList
- */
-  rateMatchPattern_t rateMatchPatternToAddModList[MAX_NR_RATE_MATCH_PATTERNS];
-/*
- * rateMatchPatternToReleaseList
- */
-  uint8_t rateMatchPatternToReleaseList[MAX_NR_RATE_MATCH_PATTERNS];
-  /*
-   * n_rateMatchPatterns indicates the number of rateMatchPatterns defined currently
-   */
-  uint8_t n_rateMatchPatterns;
-  /*
-   * zp-CSI-RS-ResourceToAddModList
-   */
-  zp_CSI_RS_Resource_t zp_CSI_RS_Resource[MAX_NR_ZP_CSI_RS_RESOURCES];
-  /*
-   * zp-CSI-RS-ResourceToReleaseList
-   */
-  uint8_t zp_CSI_RS_ResourceId[MAX_NR_ZP_CSI_RS_RESOURCES];
-  /*
-   * n_zp-CSI-RS-Resource
-   */
-  uint8_t n_zp_CSI_RS_ResourceId;
-/*
- * rgb_Size
- */
-  dl_rgb_Size_t dl_rgbSize;
-/*
- * prb-BundlingType
- */
-  prb_bundleType_t prbBundleType;
-/*
- * pdsch-HARQ-ACK-Codebook: this is part of the IE PhysicalCellGroupConfig which is used to configure cell-group specific L1 parameters (TS 38.331)
- */
-  pdsch_HARQ_ACK_Codebook_t pdsch_HARQ_ACK_Codebook;
-  ////////////////////////////////////////////////////////////////////////////////################################
-
-/*
-  Maximum number of code words that a single DCI may schedule. This changes the number of MCS/RV/NDI bits in the DCI message from 1 to 2.
-*/
-  maxNrofCodeWordsScheduledByDCI_t maxNrofCodeWordsScheduledByDCI;
-
-
-  PDSCH_TimeDomainResourceAllocation_t *pdsch_TimeDomainResourceAllocation[MAX_NR_OF_DL_ALLOCATIONS];
+  typeA = 0,
+  typeB = 1
+} mappingType_t;
 
-} PDSCH_Config_t;
+typedef enum {
+  pdsch_dmrs_pos0 = 0,
+  pdsch_dmrs_pos1 = 1,
+  pdsch_dmrs_pos2 = 2,
+  pdsch_dmrs_pos3 = 3,
+} pdsch_dmrs_AdditionalPosition_t;
 
 /***********************************************************************
 *
@@ -466,128 +364,20 @@ typedef struct {
 *
 ************************************************************************/
 
-
-typedef enum {
-  enable_tpc_accumulation = 0,  /* by default it is enable */
-  disable_tpc_accumulation = 1
-} tpc_Accumulation_t;
-
-typedef enum {
-  typeA = 0,
-  typeB = 1
-} mappingType_t;
-
-typedef struct {
-  tpc_Accumulation_t tpc_Accumulation;
-} PUSCH_PowerControl_t;
-
-typedef struct {
-
-  uint8_t         k2;
-  mappingType_t   mappingType;
-  uint8_t         startSymbolAndLength;
-} PUSCH_TimeDomainResourceAllocation_t;
-////////////////////////////////////////////////////////////////////////////////################################
-typedef enum{
-  maxCodeBlockGroupsPerTransportBlock_n2 = 2,
-  maxCodeBlockGroupsPerTransportBlock_n4 = 4,
-  maxCodeBlockGroupsPerTransportBlock_n6 = 6,
-  maxCodeBlockGroupsPerTransportBlock_n8 = 8
-} maxCodeBlockGroupsPerTransportBlock_t;
-typedef struct{ // The IE PUSCH-ServingCellConfig is used to configure UE specific PUSCH parameters that are common across the UE's BWPs of one serving cell
-	  maxCodeBlockGroupsPerTransportBlock_t maxCodeBlockGroupsPerTransportBlock;
-} PUSCH_ServingCellConfig_t;
-typedef struct{ // CSI-MeasConfig IE is used to configure CSI-RS (reference signals)
-  uint8_t reportTriggerSize;
-} csi_MeasConfig_t;
-typedef enum {
-  pdsch_dmrs_type1 = 0,
-  pdsch_dmrs_type2 = 1
-} pdsch_dmrs_type_t;
 typedef enum {
   pusch_dmrs_type1 = 0,
   pusch_dmrs_type2 = 1
 } pusch_dmrs_type_t;
-typedef enum {
-  pdsch_dmrs_pos0 = 0,
-  pdsch_dmrs_pos1 = 1,
-  pdsch_dmrs_pos3 = 3,
-} pdsch_dmrs_AdditionalPosition_t;
 typedef enum {
   pusch_dmrs_pos0 = 0,
   pusch_dmrs_pos1 = 1,
   pusch_dmrs_pos2 = 2,
   pusch_dmrs_pos3 = 3,
 } pusch_dmrs_AdditionalPosition_t;
-typedef enum {
-  offset00 = 0,
-  offset01 = 1,
-  offset10 = 2,
-  offset11 = 3,
-} ptrs_resource_elementoffset_t;
-typedef enum {
-  pdsch_len1 = 1,
-  pdsch_len2 = 2
-} pdsch_maxLength_t;
 typedef enum {
   pusch_len1 = 1,
   pusch_len2 = 2
 } pusch_maxLength_t;
-typedef struct {
-  uint8_t ptrs_mcs1;
-  uint8_t ptrs_mcs2;
-  uint8_t ptrs_mcs3;
-} ptrs_time_density_t;
-typedef struct {
-  uint16_t n_rb0;
-  uint16_t n_rb1;
-} ptrs_frequency_density_t;
-typedef struct { // The IE PTRS-UplinkConfig is used to configure uplink Phase-Tracking-Reference-Signals (PTRS)
-  uint8_t  num_ptrs_ports;
-  ptrs_resource_elementoffset_t resourceElementOffset;
-  ptrs_time_density_t  timeDensity;
-  ptrs_frequency_density_t  frequencyDensity;
-  uint32_t  ul_ptrs_power;
-} ptrs_UplinkConfig_t;
-typedef struct { // The IE DMRS-DownlinkConfig is used to configure downlink demodulation reference signals for PDSCH
-  pdsch_dmrs_type_t pdsch_dmrs_type;
-  pdsch_dmrs_AdditionalPosition_t pdsch_dmrs_AdditionalPosition;
-  pdsch_maxLength_t pdsch_maxLength;
-  uint16_t scramblingID0;
-  uint16_t scramblingID1;
-} dmrs_DownlinkConfig_t;
-typedef struct { // The IE DMRS-UplinkConfig is used to configure uplink demodulation reference signals for PUSCH
-  pusch_dmrs_type_t pusch_dmrs_type;
-  pusch_dmrs_AdditionalPosition_t pusch_dmrs_AdditionalPosition;
-  pusch_maxLength_t pusch_maxLength;
-  ptrs_UplinkConfig_t ptrs_UplinkConfig;
-  uint16_t scramblingID0;
-  uint16_t scramblingID1;
-} dmrs_UplinkConfig_t;
-typedef struct {
-/*
- * Serving cell ID of a PSCell. The PCell of the Master Cell Group uses ID = 0
- */
-  uint8_t servCellIndex;
-}servCellIndex_t;
-typedef struct{
-  uint8_t cif_presence;
-}own_t;
-typedef struct{
-  servCellIndex_t scheduling_cell_id;
-  uint8_t cif_InSchedulingCell;
-}other_t;
-typedef struct{
- own_t own;
- other_t other;
-}schedulingCellInfo_t;
-typedef struct{
- schedulingCellInfo_t schedulingCellInfo;
-} crossCarrierSchedulingConfig_t;
-typedef struct{
-  // this variable will be filled with '1' if SUL is supported and '0' if SUL is not supported
-  uint8_t supplementaryUplink;
-}supplementaryUplink_t;
 
 typedef enum {
   txConfig_codebook = 1,
@@ -628,57 +418,6 @@ typedef struct {
   betaOffset_type_t betaOffset_type;
   betaOffset_t betaOffset;
 } uci_onPusch_t;
-typedef struct {
-/*
- * txConfig
- */
-  txConfig_t txConfig;
-/*
- * frequencyHopping
- */
-	frequencyHopping_t frequencyHopping;
-/*
- * frequencyHoppingOffsetLists
- */
-  uint16_t frequencyHoppingOffsetLists[4];
-  // n_frequencyHoppingOffsetLists contains the number of offsets listed. We can list up to 4 offsets
-  uint8_t n_frequencyHoppingOffsetLists;
-/*
- * resourceAllocation
- */
-  ul_resourceAllocation_t ul_resourceAllocation;
-/*
- * DMRS-Uplinkconfig
- */
-  dmrs_UplinkConfig_t dmrs_UplinkConfig;
-/*
- * rgb_Size
- */
-  ul_rgb_Size_t ul_rgbSize;
-/*
- * corresponds to I, where I the number of entries in the higher layer parameter pusch-AllocationList
- */
-  uint8_t n_push_alloc_list;
-/*
- * transformPrecoder
- */
-transformPrecoder_t transformPrecoder;
-/*
- * codebookSubset
- */
-codebookSubset_t codebookSubset;
-/*
- * maxRank
- */
-uint8_t maxRank;
-/*
- * uci_onPusch
- */
-uci_onPusch_t uci_onPusch;
-////////////////////////////////////////////////////////////////////////////////################################
-  PUSCH_PowerControl_t                    pusch_PowerControl;
-  PUSCH_TimeDomainResourceAllocation_t    *pusch_TimeDomainResourceAllocation[MAX_NR_OF_UL_ALLOCATIONS];
-} PUSCH_Config_t;
 
 /***********************************************************************
 *
@@ -897,150 +636,6 @@ typedef struct {
   PUCCH_PowerControl_t   pucch_PowerControl;
 } PUCCH_Config_t;
 
-/***********************************************************************
-*
-* FUNCTIONALITY    :  PhysicalCellGroupConfig
-*
-* DESCRIPTION      :  Physical cell group configuration
-*
-************************************************************************/
-
-typedef uint16_t RNTI_value_t;
-
-typedef struct {
-/*
-  -- Enables spatial bundling of HARQ ACKs. It is configured per cell group (i.e. for all the cells within the cell group) for PUCCH
-  -- reporting of HARQ-ACK. It is only applicable when more than 4 layers are possible to schedule.
-  -- Corresponds to L1 parameter 'HARQ-ACK-spatial-bundling' (see 38.213, section FFS_Section)
-  -- Absence indicates that spatial bundling is disabled.
-*/
-  bool                          harq_ACK_SpatialBundlingPUCCH;
-/*
-  -- Enables spatial bundling of HARQ ACKs. It is configured per cell group (i.e. for all the cells within the cell group) for PUSCH
-  -- reporting of HARQ-ACK. It is only applicable when more than 4 layers are possible to schedule.
-  -- Corresponds to L1 parameter 'HARQ-ACK-spatial-bundling' (see 38.213, section FFS_Section)
-  -- Absence indicates that spatial bundling is disabled.
-*/
-  bool                          harq_ACK_SpatialBundlingPUSCH;
-/*
-  -- The maximum transmit power to be used by the UE in this NR cell group.
-*/
-  uint8_t                       p_NR;
-/*
-  -- The PDSCH HARQ-ACK codebook is either semi-static of dynamic. This is applicable to both CA and none CA operation.
-  -- Corresponds to L1 parameter 'HARQ-ACK-codebook' (see 38.213, section FFS_Section)
-*/
-  pdsch_HARQ_ACK_Codebook_t     pdsch_HARQ_ACK_Codebook;
-/*
-  -- RNTI used for SRS TPC commands on DCI. Corresponds to L1 parameter 'TPC-SRS-RNTI' (see 38.213, section 10)
-*/
-  RNTI_value_t                  tpc_SRS_RNTI;
-/*
-  -- RNTI used for PUCCH TPC commands on DCI. Corresponds to L1 parameter 'TPC-PUCCH-RNTI' (see 38.213, section 10).
-*/
-  RNTI_value_t                  tpc_PUCCH_RNTI;
-/*
-  -- RNTI used for PUSCH TPC commands on DCI. Corresponds to L1 parameter 'TPC-PUSCH-RNTI' (see 38.213, section 10)
-*/
-  RNTI_value_t                  tpc_PUSCH_RNTI;
-} PhysicalCellGroupConfig_t;
-
-/***********************************************************************
-*
-* FUNCTIONALITY    :  CellGroupConfig
-*
-* DESCRIPTION      :  Cell Group configuration
-*
-************************************************************************/
-
-/* FFS TODO_NR partial structure that should be complete */
-
-typedef struct {
-/*
-  cellGroupId                 CellGroupId,
-
-  -- Logical Channel configuration and association with radio bearers:
-  rlc-BearerToAddModList            SEQUENCE (SIZE(1..maxLC-ID)) OF RLC-Bearer-Config       OPTIONAL,   -- Need N
-  rlc-BearerToReleaseList           SEQUENCE (SIZE(1..maxLC-ID)) OF LogicalChannelIdentity      OPTIONAL,   -- Need N
-
-  -- Parameters applicable for the entire cell group:
-  mac-CellGroupConfig             MAC-CellGroupConfig                       OPTIONAL, -- Need M
-*/
-  PhysicalCellGroupConfig_t  physicalCellGroupConfig;
-/*
-  -- Serving Cell specific parameters (SpCell and SCells)
-  spCellConfig                SpCellConfig                          OPTIONAL,   -- Need M
-  sCellToAddModList             SEQUENCE (SIZE (1..maxNrofSCells)) OF SCellConfig       OPTIONAL, -- Need N
-  -- List of seconary serving cells to be released (not applicable for SpCells)
-  sCellToReleaseList              SEQUENCE (SIZE (1..maxNrofSCells)) OF SCellIndex        OPTIONAL, -- Need N
-  ...
-  */
-} CellGroupConfig_t;
-
-/***********************************************************************
-*
-* FUNCTIONALITY    :  PDSCH_ServingCellConfig
-*
-* DESCRIPTION      :  pdsch serving cell configuration
-*
-************************************************************************/
-
-/* FFS TODO_NR partial structure that should be complete */
-
-typedef int PDSCH_CodeBlockGroupTransmission_t;  /* dummy struct which should be change by correct structure */
-
-typedef enum {
-  xOh6  = 0,
-  xOh12 = 1,
-  xOh18 = 2
-} xOverhead_t;
-
-typedef enum {
-  n2_dl_harq  = 2,
-  n4_dl_harq  = 4,
-  n6_dl_harq  = 6,
-  n10_dl_harq = 10,
-  n12_dl_harq = 12,
-  n16_dl_harq = 16
-} nrofHARQ_ProcessesForPDSCH_t;
-typedef enum{
-  maxCodeBlockGroupsPerTransportBlock_dl_n2 = 2,
-  maxCodeBlockGroupsPerTransportBlock_dl_n4 = 4,
-  maxCodeBlockGroupsPerTransportBlock_dl_n6 = 6,
-  maxCodeBlockGroupsPerTransportBlock_dl_n8 = 8
-} maxCodeBlockGroupsPerTransportBlock_dl_t;
-
-typedef struct {
-/*
-  -- Enables and configures code-block-group (CBG) based transmission (see 38.213, section 9.1.1)
-*/
-  PDSCH_CodeBlockGroupTransmission_t  *codeBlockGroupTransmission;
-/*
-  -- Accounts for overhead from CSI-RS, CORESET, etc. If the field is absent, the UE applies value xOh0.
-  -- Corresponds to L1 parameter 'Xoh-PDSCH' (see 38.214, section 5.1.3.2)
-*/
-  xOverhead_t                         xOverhead;
-/*
-  -- The number of HARQ processes to be used on the PDSCH of a serving cell. n2 corresponds to 2 HARQ processes, n4 to 4 HARQ processes
-  -- and so on. If the field is absent, the UE uses 8 HARQ processes.
-  -- Corresponds to L1 parameter 'number-HARQ-process-PDSCH' (see 38.214, section REF)
-*/
-  nrofHARQ_ProcessesForPDSCH_t        nrofHARQ_ProcessesForPDSCH;
-/*
-  -- The ID of the serving cell (of the same cell group) to use for PUCCH.
-  -- If the field is absent, the UE sends the HARQ feedback on the PUCCH of the SpCell of this cell group.
-*/
-  uint8_t                            pucch_Cell;
-/*
- * maxCodeBlockGroupsPerTransportBlock_dl_t
- */
-  maxCodeBlockGroupsPerTransportBlock_dl_t maxCodeBlockGroupsPerTransportBlock_dl;
-/*
- * codeBlockGroupFlushIndicator (boolean)
- */
-  uint8_t codeBlockGroupFlushIndicator;
-} PDSCH_ServingCellConfig_t;
-
 /***********************************************************************
 *
 * FUNCTIONALITY    :  Scheduling Request Configuration (SR)
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index dfe47d75f1a6ce0f9cb5983abe894c63d5bbf7c3..550d4c8e31d18bc14d8fcac687f4421097d96c65 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -176,7 +176,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
 			ul_pdcch_pdu_id>=0 ? &gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu : NULL,
 			gNB->nr_gold_pdcch_dmrs[slot],
 			&gNB->common_vars.txdataF[0][txdataF_offset],
-			AMP, *fp);
+			AMP, fp);
 
     // free up entry in pdcch tables
     if (pdcch_pdu_id>=0) gNB->pdcch_pdu[pdcch_pdu_id].frame = -1;
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index c276de847d1c1e677c56f64f863b3233e0935608..99edbf9a40d0f7907cd531e886734b08284d313c 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -80,31 +80,30 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
         } else {
 
+          fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
+          uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
+
           if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DLSCH){
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
           }
           else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0];
             dlsch0->rnti_type = _RA_RNTI_;
-            dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE;
+            dlsch0->harq_processes[current_harq_pid]->status = ACTIVE;
           }
           else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH){
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0];
             dlsch0->rnti_type = _SI_RNTI_;
-            dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE;
+            dlsch0->harq_processes[current_harq_pid]->status = ACTIVE;
           }
 
-          fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
-          uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
-          NR_DL_UE_HARQ_t *dlsch0_harq;
-
           dlsch0->current_harq_pid = current_harq_pid;
           dlsch0->active = 1;
           dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
-          dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
 
           LOG_D(PHY,"current_harq_pid = %d\n", current_harq_pid);
 
+          NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
           if (dlsch0_harq){
 
             dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
@@ -121,7 +120,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
             dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
             dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
             dlsch0_harq->harq_ack.slot_for_feedback_ack = (slot+dlsch_config_pdu->pdsch_to_harq_feedback_time_ind)%frame_parms.slots_per_frame;
-            dlsch0_harq->Nl=1;
+
+            //get nrOfLayers from DCI info
+            uint8_t Nl = 0;
+            for (i = 0; i < 4; i++) {
+              if (dlsch_config_pdu->dmrs_ports[i] >= i) Nl += 1;
+            }
+            dlsch0_harq->Nl = Nl;
+
             dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
             dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type);
             if (dlsch0_harq->status != ACTIVE) {
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index e3d4c54f5aaa809c8de5985bf87131c8b3e38ba8..18ef2f66f46f5e261a9601cf00d691df77f9896e 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -288,7 +288,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
 void nr_ue_measurement_procedures(uint16_t l,
                                   PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
-                                  uint8_t eNB_id,
+                                  uint8_t gNB_id,
                                   uint16_t slot){
 
   NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
@@ -308,7 +308,7 @@ void nr_ue_measurement_procedures(uint16_t l,
 
 #if T_TRACER
     if(slot == 0)
-      T(T_UE_PHY_MEAS, T_INT(eNB_id),  T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx),
+      T(T_UE_PHY_MEAS, T_INT(gNB_id),  T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_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)),
@@ -327,8 +327,8 @@ void nr_ue_measurement_procedures(uint16_t l,
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
 
 
-    //printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[eNB_id]);
-    phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[eNB_id],eNB_id);
+    //printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[gNB_id]);
+    phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[gNB_id],gNB_id);
     
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
 
@@ -738,12 +738,12 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
 }
 #endif // NR_PDCCH_SCHED
 
-int nr_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 nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) {
 
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
   int m;
-  int i_mod,eNB_id_i,dual_stream_UE;
+  int i_mod,gNB_id_i,dual_stream_UE;
   int first_symbol_flag=0;
 
   if (!dlsch0)
@@ -761,14 +761,14 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
     uint16_t s1             = dlsch0_harq->nb_symbols;
     bool is_SI              = dlsch0->rnti_type == _SI_RNTI_;
 
-    LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
+    LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0_harq->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0_harq->dlDmrsSymbPos);
 
     for (m = s0; m < (s0 +s1); m++) {
-      if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) > 0) {
-        for (uint8_t aatx=0; aatx<dlsch0->harq_processes[harq_pid]->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers
+      if (dlsch0_harq->dlDmrsSymbPos & (1 << m)) {
+        for (uint8_t aatx=0; aatx<dlsch0_harq->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers
           nr_pdsch_channel_estimation(ue,
                                       proc,
-                                      0 /*eNB_id*/,
+                                      gNB_id,
                                       is_SI,
                                       nr_slot_rx,
                                       aatx /*p*/,
@@ -783,7 +783,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
           char filename[100];
           for (uint8_t aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
             sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", nr_frame_rx, nr_slot_rx, m, aatx,aarx);
-            int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates;
+            int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
             LOG_M(filename,"channel_F",&dl_ch_estimates[aatx*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1);
           }
 #endif
@@ -796,7 +796,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
     uint16_t first_symbol_with_data = s0;
     uint32_t dmrs_data_re;
 
-    if (ue->dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1)
+    if (dlsch0_harq->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)
       dmrs_data_re = 12 - 6 * dlsch0_harq->n_dmrs_cdm_groups;
     else
       dmrs_data_re = 12 - 4 * dlsch0_harq->n_dmrs_cdm_groups;
@@ -808,7 +808,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
     for (m = s0; m < (s1 + s0); m++) {
  
       dual_stream_UE = 0;
-      eNB_id_i = eNB_id+1;
+      gNB_id_i = gNB_id+1;
       i_mod = 0;
       if (( m==first_symbol_with_data ) && (m<4))
         first_symbol_flag = 1;
@@ -827,15 +827,15 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
         if (nr_rx_pdsch(ue,
                         proc,
                         pdsch,
-                        eNB_id,
-                        eNB_id_i,
+                        gNB_id,
+                        gNB_id_i,
                         frame_rx,
                         nr_slot_rx,
                         m,
                         first_symbol_flag,
                         dual_stream_UE,
                         i_mod,
-                        dlsch0->current_harq_pid) < 0)
+                        harq_pid) < 0)
           return -1;
       } else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n");
 
@@ -858,7 +858,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
 
 void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
        UE_nr_rxtx_proc_t *proc,
-       int eNB_id,
+       int gNB_id,
        PDSCH_t pdsch,
        NR_UE_DLSCH_t *dlsch0,
        NR_UE_DLSCH_t *dlsch1,
@@ -878,7 +878,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
   fapi_nr_rx_indication_t rx_ind;
   uint16_t number_pdus = 1;
   // params for UL time alignment procedure
-  NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id];
+  NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id];
 
   uint8_t is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
   uint16_t nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
@@ -915,7 +915,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     case RA_PDSCH:
     case P_PDSCH:
     case PDSCH:
-      pdsch_vars = ue->pdsch_vars[proc->thread_id][eNB_id];
+      pdsch_vars = ue->pdsch_vars[proc->thread_id][gNB_id];
       break;
     case PMCH:
     case PDSCH1:
@@ -933,8 +933,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
       *dlsch_errors=0;
 
     if (pdsch == RA_PDSCH) {
-      if (ue->prach_resources[eNB_id]!=NULL)
-	      dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+      if (ue->prach_resources[gNB_id]!=NULL)
+	      dlsch0->rnti = ue->prach_resources[gNB_id]->ra_RNTI;
       else {
 	      LOG_E(PHY,"[UE %d] Frame %d, nr_slot_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_slot_rx);
 	      //mac_xface->macphy_exit("prach_resources is NULL");
@@ -975,7 +975,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
       LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
       LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
       LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->Kmimo);
-      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols);
+      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][gNB_id]->num_pdcch_symbols);
 #endif
 
 #if UE_TIMING_TRACE
@@ -986,7 +986,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     {
     ret = nr_dlsch_decoding_mthread(ue,
 			   proc,
-			   eNB_id,
+			   gNB_id,
 			   pdsch_vars->llr[0],
 			   &ue->frame_parms,
 			   dlsch0,
@@ -1003,7 +1003,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     {
     ret = nr_dlsch_decoding(ue,
 			   proc,
-			   eNB_id,
+			   gNB_id,
 			   pdsch_vars->llr[0],
 			   &ue->frame_parms,
 			   dlsch0,
@@ -1061,7 +1061,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
           LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl);
           LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G);
           LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->Kmimo);
-          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols);
+          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][gNB_id]->num_pdcch_symbols);
 #endif
 
 #if UE_TIMING_TRACE
@@ -1072,7 +1072,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     {
     ret1 = nr_dlsch_decoding_mthread(ue,
                                      proc,
-                                     eNB_id,
+                                     gNB_id,
                                      pdsch_vars->llr[1],
                                      &ue->frame_parms,
                                      dlsch1,
@@ -1089,7 +1089,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     {
     ret1 = nr_dlsch_decoding(ue,
 			     proc,
-			     eNB_id,
+			     gNB_id,
                              pdsch_vars->llr[1],
                              &ue->frame_parms,
                              dlsch1,
@@ -1131,18 +1131,18 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 
         switch (pdsch) {
           case RA_PDSCH:
-            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
-            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, eNB_id, ue, dlsch0, number_pdus);
+            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
+            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, number_pdus);
 
-            ue->UE_mode[eNB_id] = RA_RESPONSE;
+            ue->UE_mode[gNB_id] = RA_RESPONSE;
             break;
           case PDSCH:
-            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
-            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, eNB_id, ue, dlsch0, number_pdus);
+            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
+            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, number_pdus);
             break;
           case SI_PDSCH:
-            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
-            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, eNB_id, ue, dlsch0, number_pdus);
+            nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id);
+            nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, number_pdus);
             break;
           default:
             break;
@@ -1156,7 +1156,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
         }
       }
 
-      if (ue->mac_enabled == 1) {
+      if (ue->mac_enabled == 1) { // TODO: move this from PHY to MAC layer!
 
         /* Time Alignment procedure
         // - UE processing capability 1
@@ -1177,11 +1177,60 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
         const int Ta_max = 3846; // Max value of 12 bits TA Command
         const double N_TA_max = Ta_max * bw_scaling * tc_factor;
 
+        NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+
+        NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
+        if (mac->ULbwp[0] &&
+            mac->ULbwp[0]->bwp_Dedicated &&
+            mac->ULbwp[0]->bwp_Dedicated->pusch_Config &&
+            mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup &&
+            mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
+          pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
+        }
+        else if (mac->ULbwp[0] &&
+                 mac->ULbwp[0]->bwp_Common &&
+                 mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon &&
+                 mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup &&
+                 mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+          pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+        }
+        else if (mac->scc_SIB &&
+                 mac->scc_SIB->uplinkConfigCommon &&
+                 mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon &&
+                 mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup &&
+                 mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+          pusch_TimeDomainAllocationList = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+        }
+        long mapping_type_ul = pusch_TimeDomainAllocationList ? pusch_TimeDomainAllocationList->list.array[0]->mappingType : NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA;
+
+        NR_PDSCH_Config_t *pdsch_Config = (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup) ? mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup : NULL;
+        NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL;
+        if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
+          pdsch_TimeDomainAllocationList = pdsch_Config->pdsch_TimeDomainAllocationList->choice.setup;
+        else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
+          pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+        else if (mac->scc_SIB && mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup)
+          pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+        long mapping_type_dl = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[0]->mappingType : NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA;
+
+        NR_DMRS_DownlinkConfig_t *NR_DMRS_dlconfig = NULL;
+        if (pdsch_Config) {
+          if (mapping_type_dl == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA)
+            NR_DMRS_dlconfig = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup;
+          else
+            NR_DMRS_dlconfig = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup;
+        }
+
+        pdsch_dmrs_AdditionalPosition_t add_pos_dl = pdsch_dmrs_pos2;
+        if (NR_DMRS_dlconfig && NR_DMRS_dlconfig->dmrs_AdditionalPosition)
+          add_pos_dl = *NR_DMRS_dlconfig->dmrs_AdditionalPosition;
+
         /* PDSCH decoding time N_1 for processing capability 1 */
         int N_1;
-        if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0)
+
+        if (add_pos_dl == pdsch_dmrs_pos0)
           N_1 = pdsch_N_1_capability_1[numerology][1];
-        else if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos1 || ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == 2) // TODO set to pdsch_dmrs_pos2 when available
+        else if (add_pos_dl == pdsch_dmrs_pos1 || add_pos_dl == pdsch_dmrs_pos2)
           N_1 = pdsch_N_1_capability_1[numerology][2];
         else
           N_1 = pdsch_N_1_capability_1[numerology][3];
@@ -1192,8 +1241,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
         /* d_1_1 depending on the number of PDSCH symbols allocated */
         const int d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH
         int d_1_1 = 0;
-        mappingType_t mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType;
-        if (mapping_type_dl == typeA)
+        if (mapping_type_dl == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA)
          if (nb_symb_sch + start_symbol < 7)
           d_1_1 = 7 - (nb_symb_sch + start_symbol);
          else
@@ -1208,8 +1256,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 
         /* d_2_1 */
         int d_2_1;
-        mappingType_t mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
-        if (mapping_type_ul == typeB && start_symbol != 0)
+        if (mapping_type_ul == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB && start_symbol != 0)
           d_2_1 = 0;
         else
           d_2_1 = 1;
@@ -1433,9 +1480,9 @@ void *UE_thread_slot1_dl_processing(void *arg) {
 #endif
     // start slave thread for Pdsch Procedure (slot1)
     // do procedures for C-RNTI
-    uint8_t eNB_id = 0;
+    uint8_t gNB_id = 0;
 
-    if (ue->dlsch[proc->thread_id][eNB_id][0]->active == 1) {
+    if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) {
       //wait until first ofdm symbol is processed
       //wait = 0;
       //while(proc->first_symbol_available == 0)
@@ -1448,9 +1495,9 @@ void *UE_thread_slot1_dl_processing(void *arg) {
       //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  PDSCH,
-			  ue->dlsch[proc->thread_id][eNB_id][0],
+			  ue->dlsch[proc->thread_id][gNB_id][0],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
@@ -1460,12 +1507,12 @@ void *UE_thread_slot1_dl_processing(void *arg) {
     }
 
     // do procedures for SI-RNTI
-    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+    if ((ue->dlsch_SI[gNB_id]) && (ue->dlsch_SI[gNB_id]->active == 1)) {
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  SI_PDSCH,
-			  ue->dlsch_SI[eNB_id],
+			  ue->dlsch_SI[gNB_id],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
@@ -1473,24 +1520,24 @@ void *UE_thread_slot1_dl_processing(void *arg) {
     }
 
     // do procedures for P-RNTI
-    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+    if ((ue->dlsch_p[gNB_id]) && (ue->dlsch_p[gNB_id]->active == 1)) {
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  P_PDSCH,
-			  ue->dlsch_p[eNB_id],
+			  ue->dlsch_p[gNB_id],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
 			  abstraction_flag);
     }
     // do procedures for RA-RNTI
-    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1) && (UE_mode != PUSCH)) {
+    if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1) && (UE_mode != PUSCH)) {
       ue_pdsch_procedures(ue,
 			  proc,
-			  eNB_id,
+			  gNB_id,
 			  RA_PDSCH,
-			  ue->dlsch_ra[eNB_id],
+			  ue->dlsch_ra[gNB_id],
 			  NULL,
 			  (ue->frame_parms.symbols_per_slot>>1),
 			  ue->frame_parms.symbols_per_slot-1,
@@ -1650,7 +1697,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
 #if UE_TIMING_TRACE
       start_meas(&ue->dlsch_channel_estimation_stats);
 #endif
-      nr_pbch_channel_estimation(ue,proc,0,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit);
+      nr_pbch_channel_estimation(ue,proc,gNB_id,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit);
 #if UE_TIMING_TRACE
       stop_meas(&ue->dlsch_channel_estimation_stats);
 #endif
@@ -1710,7 +1757,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
     if (coreset_nb_rb > 0)
       nr_pdcch_channel_estimation(ue,
                                   proc,
-                                  0,
+                                  gNB_id,
                                   nr_slot_rx,
                                   l,
                                   fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
index f43f4d98c99f9c33bd8504b3acd11face872df20..fadfba6bce576d71d1665b930a14095f7da63741 100644
--- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
@@ -158,13 +158,14 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue,
     }
   }
 
-  int k2;
-
   if (power_config->twoPUCCH_PC_AdjustmentStates > 1) {
     LOG_E(PHY,"PUCCH power control adjustment states with 2 states not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__);
     return (PUCCH_POWER_DEFAULT);
   }
 
+#if 0
+  int k2;
+
   /* response to a detection by the UE of a DCI format 1_0 or DCI format 1_1 */
   //int K_PUCCH = 0;
   if (O_ACK != 0) {
@@ -201,6 +202,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue,
     }
     //K_PUCCH = N_SYMB_SLOT * k2; /* the product of a number of symbols per slot and the minimum of the values provided by higher layer parameter k2 */
   }
+#endif
 
   int contributor = (10 * log10((double)(pow(2,(ue->frame_parms.numerology_index)) * nb_of_prbs)));
 
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 11f5d439ea380282dd8046d3fa244f711e9f9901..b597425ddf6d9a210ce59c74ff639114ddd0caac 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -237,12 +237,12 @@ int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0);  }
 // needed for some functions
 openair0_config_t openair0_cfg[MAX_CARDS];
 void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex,int8_t *ptrs_arg);
-void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg);
+void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg);
 extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
 
-/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of
+/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of
    dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */
-int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1;
+int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1;
 void nr_dlsim_preprocessor(module_id_t module_id,
                            frame_t frame,
                            sub_frame_t slot) {
@@ -278,6 +278,7 @@ void nr_dlsim_preprocessor(module_id_t module_id,
    * configuration */
   ps->mcsTableIdx = g_mcsTableIdx;
 
+  sched_pdsch->nrOfLayers = g_nrOfLayers;
   sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
   sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
   sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm,
@@ -287,7 +288,7 @@ void nr_dlsim_preprocessor(module_id_t module_id,
                                         ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
                                         0 /* N_PRB_oh, 0 for initialBWP */,
                                         0 /* tb_scaling */,
-                                        1 /* nrOfLayers */)
+                                        sched_pdsch->nrOfLayers)
                          >> 3;
 
   /* the simulator assumes the HARQ PID is equal to the slot number */
@@ -355,7 +356,7 @@ int main(int argc, char **argv)
   //  char fname[40], vname[40];
   int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
   //int n_errors2, n_alamouti;
-  uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
+  uint8_t n_tx=1,n_rx=1;
   uint8_t round;
   uint8_t num_rounds = 4;
 
@@ -397,7 +398,7 @@ int main(int argc, char **argv)
   int8_t enable_ptrs = 0;
   int8_t modify_dmrs = 0;
 
-  int8_t dmrs_arg[2] = {-1,-1};// Invalid values
+  int8_t dmrs_arg[3] = {-1,-1,-1};// Invalid values
   /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
   int8_t ptrs_arg[2] = {-1,-1};// Invalid values
 
@@ -463,6 +464,10 @@ int main(int argc, char **argv)
         channel_model=ETU;
         break;
 
+      case 'R':
+        channel_model=Rayleigh1;
+        break;
+
       default:
         printf("Unsupported channel model!\n");
         exit(-1);
@@ -512,12 +517,11 @@ int main(int argc, char **argv)
       break;
       */
     case 'x':
-      transmission_mode=atoi(optarg);
+      g_nrOfLayers=atoi(optarg);
 
-      if ((transmission_mode!=1) &&
-          (transmission_mode!=2) &&
-          (transmission_mode!=6)) {
-        printf("Unsupported transmission mode %d\n",transmission_mode);
+      if ((g_nrOfLayers!=1) &&
+          (g_nrOfLayers!=2)) {
+        printf("Unsupported nr Of Layers %d\n",g_nrOfLayers);
         exit(-1);
       }
 
@@ -634,7 +638,7 @@ int main(int argc, char **argv)
       printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB.  If n_frames is 1 then just SNR is simulated\n");
       printf("-S Ending SNR, runs from SNR0 to SNR1\n");
       printf("-t Delay spread for multipath channel\n");
-      printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
+      printf("-g [A,B,C,D,E,F,G,R] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models or R for MIMO model (ignores delay spread and Ricean factor)\n");
       printf("-y Number of TX antennas used in gNB\n");
       printf("-z Number of RX antennas used in UE\n");
       //printf("-i Relative strength of first intefering gNB (in dB) - cell_id mod 3 = 1\n");
@@ -655,7 +659,7 @@ int main(int argc, char **argv)
       printf("-q Use 2nd MCS table (256 QAM table) for PDSCH\n");
       printf("-t Acceptable effective throughput (in percentage)\n");
       printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
-      printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2}, e.g. -U 2 0 2 \n");
+      printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n");
       printf("-P Print DLSCH performances\n");
       printf("-w Write txdata to binary file (one frame)\n");
       printf("-d number of dlsch threads, 0: no dlsch parallelization\n");
@@ -760,7 +764,7 @@ int main(int argc, char **argv)
   fix_scd(scd);
   /* -U option modify DMRS */
   if(modify_dmrs) {
-    update_dmrs_config(secondaryCellGroup, NULL,dmrs_arg);
+    update_dmrs_config(secondaryCellGroup, dmrs_arg);
   }
   /* -T option enable PTRS */
   if(enable_ptrs) {
@@ -890,9 +894,6 @@ int main(int argc, char **argv)
     exit(-1);
   }
 
-  if(modify_dmrs) {
-    update_dmrs_config( NULL,UE,dmrs_arg);
-  }
   init_nr_ue_transport(UE,0);
 
   nr_gold_pbch(UE);
@@ -1134,6 +1135,11 @@ int main(int argc, char **argv)
                              frame_length_complex_samples,
                              0);
 
+        double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0
+                                   {0.5, 1.0, 0.5, 0.25},  //rx 1
+                                   {0.25, 0.5, 1.0, 0.5},  //rx 2
+                                   {0.125, 0.25, 0.5, 1.0}};//rx 3
+
         for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); 
              i<frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0);
              i++) {
@@ -1144,9 +1150,9 @@ int main(int argc, char **argv)
               // sum up signals from different Tx antennas
               r_re[aa_rx][i] = 0;
               r_im[aa_rx][i] = 0;
-              for (aa=0; aa<n_tx; aa++) {
-                r_re[aa_rx][i] += s_re[aa][i];
-                r_im[aa_rx][i] += s_im[aa][i];
+             for (aa=0; aa<n_tx; aa++) {
+                r_re[aa_rx][i] += s_re[aa][i]*H_awgn_mimo[aa_rx][aa];
+                r_im[aa_rx][i] += s_im[aa][i]*H_awgn_mimo[aa_rx][aa];
               }
             }
             // Add Gaussian noise
@@ -1413,10 +1419,12 @@ void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSi
   rrc_config_dl_ptrs_params(bwp, ptrsFreqDenst, ptrsTimeDenst, &epre_Ratio, &reOffset);
 }
 
-void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg)
+void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg)
 {
   int8_t  mapping_type = typeA;//default value
   int8_t  add_pos = pdsch_dmrs_pos0;//default value
+  int8_t  dmrs_config_type = NFAPI_NR_DMRS_TYPE1;//default value
+
   if(dmrs_arg[0] == 0) {
     mapping_type = typeA;
   }
@@ -1433,60 +1441,68 @@ void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dm
     AssertFatal(1==0,"Incorrect Additional Position, valid options 0-pos1, 1-pos1, 2-pos2, 3-pos3\n");
   }
 
-  if(scg != NULL) {
-    NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0];
-
-    AssertFatal((bwp->bwp_Dedicated->pdsch_Config != NULL && bwp->bwp_Dedicated->pdsch_Config->choice.setup != NULL), "Base RRC reconfig structures are not allocated.\n");
-
-    if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA == NULL) {
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL;
-      printf("DLSIM: Allocated Mapping TypeA in RRC reconfig message\n");
-    } else if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB == NULL) {
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID0=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID1=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->phaseTrackingRS=NULL;
-      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_AdditionalPosition = NULL;
-      printf("DLSIM: Allocated Mapping TypeB in RRC reconfig message\n");
-    }
+  /* DMRS Conf Type 1 or 2 */
+  if(dmrs_arg[2] == 1) {
+    dmrs_config_type = NFAPI_NR_DMRS_TYPE1;
+  } else if(dmrs_arg[2] == 2) {
+    dmrs_config_type = NFAPI_NR_DMRS_TYPE2;
+  }
 
-    struct NR_SetupRelease_DMRS_DownlinkConfig	*dmrs_MappingtypeA = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA;
-    struct NR_SetupRelease_DMRS_DownlinkConfig	*dmrs_MappingtypeB = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB;
+  NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0];
+
+  AssertFatal((bwp->bwp_Dedicated->pdsch_Config != NULL && bwp->bwp_Dedicated->pdsch_Config->choice.setup != NULL), "Base RRC reconfig structures are not allocated.\n");
+
+  if(mapping_type == typeA) {
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA));
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup));
+    if (dmrs_config_type == NFAPI_NR_DMRS_TYPE2)
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
+    else
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type = NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL;
+    printf("DLSIM: Allocated Mapping TypeA in RRC reconfig message\n");
+  }
 
+  if(mapping_type == typeB) {
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB));
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup));
+    if (dmrs_config_type == NFAPI_NR_DMRS_TYPE2)
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type));
+    else
+      bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type = NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID0=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID1=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->phaseTrackingRS=NULL;
+    bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_AdditionalPosition = NULL;
+    printf("DLSIM: Allocated Mapping TypeB in RRC reconfig message\n");
+  }
 
-    NR_DMRS_DownlinkConfig_t *dmrs_config = (mapping_type == typeA) ? dmrs_MappingtypeA->choice.setup : dmrs_MappingtypeB->choice.setup;
+  struct NR_SetupRelease_DMRS_DownlinkConfig	*dmrs_MappingtypeA = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA;
+  struct NR_SetupRelease_DMRS_DownlinkConfig	*dmrs_MappingtypeB = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB;
 
-    if (add_pos != 2) { // pos0,pos1,pos3
-      if (dmrs_config->dmrs_AdditionalPosition == NULL) {
-        dmrs_config->dmrs_AdditionalPosition = calloc(1,sizeof(*dmrs_MappingtypeA->choice.setup->dmrs_AdditionalPosition));
-      }
-      *dmrs_config->dmrs_AdditionalPosition = add_pos;
-    } else { // if NULL, Value pos2
-      free(dmrs_config->dmrs_AdditionalPosition);
-      dmrs_config->dmrs_AdditionalPosition = NULL;
-    }
 
-    for (int i=0;i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;i++) {
-      bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType = mapping_type; 
+  NR_DMRS_DownlinkConfig_t *dmrs_config = (mapping_type == typeA) ? dmrs_MappingtypeA->choice.setup : dmrs_MappingtypeB->choice.setup;
+
+  if (add_pos != 2) { // pos0,pos1,pos3
+    if (dmrs_config->dmrs_AdditionalPosition == NULL) {
+      dmrs_config->dmrs_AdditionalPosition = calloc(1,sizeof(*dmrs_MappingtypeA->choice.setup->dmrs_AdditionalPosition));
     }
+    *dmrs_config->dmrs_AdditionalPosition = add_pos;
+  } else { // if NULL, Value pos2
+    free(dmrs_config->dmrs_AdditionalPosition);
+    dmrs_config->dmrs_AdditionalPosition = NULL;
   }
-  if(ue != NULL) {
-    for (int i=0;i<MAX_NR_OF_DL_ALLOCATIONS;i++) {
-      ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = mapping_type;
-    }
-    ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = add_pos;
+
+  for (int i=0;i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;i++) {
+    bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType = mapping_type;
   }
-  printf("[DLSIM] DMRS Config is modified with Mapping Type %d, Additional Positions %d \n", dmrs_arg[0], dmrs_arg[1] );
+
+  printf("[DLSIM] DMRS Config is modified with Mapping Type %d, Additional Positions %d Config. Type %d \n", mapping_type, add_pos, dmrs_config_type);
 }
diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
index c68ce737580b6ec7ae36763e6138adebbb3f82ce..ece1f81335f4af9393b4a4df37cf08b10918d618 100644
--- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
+++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
@@ -40,9 +40,9 @@ void multipath_tv_channel(channel_desc_t *desc,
                           uint8_t keep_channel)
 {
 
-  double complex **tx,**rx,***H_t,*rx_temp;//, *tv_H_t;
+  double complex **tx,**rx,***H_t;
   double path_loss = pow(10,desc->path_loss_dB/20);
-  int i,j,k,dd;
+  int i,j,dd;
   dd = abs(desc->channel_offset);
 #ifdef DEBUG_CH
   printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %g\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length,
@@ -51,8 +51,6 @@ void multipath_tv_channel(channel_desc_t *desc,
   tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex *));
   rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex *));
   H_t= (double complex ***) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **));
-  //  tv_H_t = (double complex *) malloc(length*sizeof(double complex));
-  rx_temp= (double complex *) calloc(length,sizeof(double complex));
 
   for(i=0; i<desc->nb_tx; i++) {
     tx[i] = (double complex *)calloc(length,sizeof(double complex));
@@ -84,11 +82,7 @@ void multipath_tv_channel(channel_desc_t *desc,
 
   for(i=0; i<desc->nb_rx; i++) {
     for(j=0; j<desc->nb_tx; j++) {
-      tv_conv(H_t[i+(j*desc->nb_rx)],tx[j],rx_temp,length,desc->nb_taps,dd);
-
-      for(k=0; k<length; k++) {
-        rx[i][k] += rx_temp[k];
-      }
+      tv_conv(H_t[i+(j*desc->nb_rx)],tx[j],rx[i],length,desc->nb_taps,dd);
     }
   }
 
@@ -99,10 +93,6 @@ void multipath_tv_channel(channel_desc_t *desc,
     }
   }
 
-  /*  for(k=0;k<length;k++) {
-      tv_H_t[k] = H_t[0][k][0];
-      }*/
-
   for(i=0; i<desc->nb_tx; i++) {
     free(tx[i]);
   }
@@ -124,7 +114,6 @@ void multipath_tv_channel(channel_desc_t *desc,
   }
 
   free(H_t);
-  free(rx_temp);
 }
 
 //TODO: make phi_rad a parameter of this function
@@ -177,7 +166,7 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){
             H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[k])*alpha[p]*cexp(I*(2*pi*w_Hz[i+(j*desc->nb_rx)][k][p]*l*(1/(desc->sampling_rate*1e6))+phi_rad[i+(j*desc->nb_rx)][k][p]));
           }
         }
-        //printf("H[tx%d][rx%d][k%d] = %f+j%f \n",j,i,k,creal(H[i+(j*desc->nb_rx)][k][0]),cimag(H[i+(j*desc->nb_rx)][k][0]));
+        //printf("H[tx%d][rx%d][k%d][l%d] = %f+j%f \n",j,i,k,0,creal(H[i+(j*desc->nb_rx)][k][0]),cimag(H[i+(j*desc->nb_rx)][k][0]));
       }
     }
   }
@@ -201,14 +190,12 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){
 }
 
 // time varying convolution
-void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd){
-
-  int i,j;
-
-  for(i=0; i<((int)nb_samples-dd); i++) {
-    for(j=0; j<nb_taps; j++) {
-      if(i>j)
-        y[i+dd] += creal(h[j][i])*creal(x[i-j])-cimag(h[j][i])*cimag(x[i-j]) + I*(creal(h[j][i])*cimag(x[i-j])+cimag(h[j][i])*creal(x[i-j]));
+void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd)
+{
+  for(int i = 0; i < ((int)nb_samples-dd); i++) {
+    for(int j = 0; j < nb_taps; j++) {
+      if(i >= j)
+        y[i+dd] += h[j][i] * x[i-j];
     }
   }
 }
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index a5a9aac7ec0e9875f64f502f002275e6a23ee2c0..d21100ae7cfd234f7266ab3bd05bdd1e38c2a8de 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -2502,7 +2502,7 @@ uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint
 *
 * NAME :         get_K_ptrs
 *
-* PARAMETERS :   ptrs_UplinkConfig      PTRS uplink configuration
+* PARAMETERS :   nrb0, nrb1             PTRS uplink configuration
 *                N_RB                   number of RBs scheduled for PUSCH
 *
 * RETURN :       the parameter K_ptrs
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 6a9734dd7508056c313ec6e6bb055d2079806913..a72d7dc23dc12d75c7b16f3fef2dc1904be8d3e0 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -899,7 +899,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 							 dlsch_config_pdu_1_1->number_symbols,
                dlsch_config_pdu_1_1->start_symbol,
                mappingtype);
-    dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
+    dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2;
     /* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214,
              using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */
     dlsch_config_pdu_1_1->n_dmrs_cdm_groups = 1;
@@ -996,7 +996,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->dmrs_ports[3]     = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][4];
 	dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][5];
       }
-      if (n_codewords == 1) {
+      if (n_codewords == 2) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][0];
 	dlsch_config_pdu_1_1->dmrs_ports[0]     = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][1];
 	dlsch_config_pdu_1_1->dmrs_ports[1]     = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][2];
@@ -1018,7 +1018,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->dmrs_ports[2]     = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][3];
 	dlsch_config_pdu_1_1->dmrs_ports[3]     = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][4];
       }
-      if (n_codewords == 1) {
+      if (n_codewords == 2) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][0];
 	dlsch_config_pdu_1_1->dmrs_ports[0]     = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][1];
 	dlsch_config_pdu_1_1->dmrs_ports[1]     = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][2];
@@ -1038,7 +1038,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 	dlsch_config_pdu_1_1->dmrs_ports[3]     = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][4];
 	dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][5];
       }
-      if (n_codewords == 1) {
+      if (n_codewords == 2) {
 	dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][0];
 	dlsch_config_pdu_1_1->dmrs_ports[0]     = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][1];
 	dlsch_config_pdu_1_1->dmrs_ports[1]     = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][2];
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 551a4892c0498328474078d4c92721475ebe8050..bfdb1a01e39183d1e3f05d48ed82ce5d361ea2ad 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -603,6 +603,7 @@ void pf_dl(module_id_t module_id,
 
       /* Calculate coeff */
       sched_pdsch->mcs = 9;
+      sched_pdsch->nrOfLayers = 1;
       uint32_t tbs = pf_tbs[ps->mcsTableIdx][sched_pdsch->mcs];
       coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id];
       LOG_D(NR_MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
@@ -820,7 +821,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
     const rnti_t rnti = UE_info->rnti[UE_id];
 
     /* POST processing */
-    const int nrOfLayers = 1;
+    const uint8_t nrOfLayers = sched_pdsch->nrOfLayers;
     const uint16_t R = sched_pdsch->R;
     const uint8_t Qm = sched_pdsch->Qm;
     const uint32_t TBS = sched_pdsch->tb_size;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 51a01f9302dd3021192c66db15e1a6870f533210..47ccc74612a3a58c5e995e986af8fde5d3d5eeb2 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -262,6 +262,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
 extern int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda);
 extern uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData);
 uint32_t target_dl_mcs = 9;
+uint32_t target_dl_Nl = 1;
 uint32_t target_dl_bw = 50;
 uint64_t dlsch_slot_bitmap = (1<<1);
 /* schedules whole bandwidth for first user, all the time */
@@ -284,6 +285,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
   const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
   int rbStart = 0;
   int rbSize = 0;
+  if (target_dl_bw>bwpSize)
+    target_dl_bw = bwpSize;
   uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
   /* loop ensures that we allocate exactly target_dl_bw, or return */
   while (true) {
@@ -370,6 +373,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
     nr_set_pdsch_semi_static(
         scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
 
+  sched_pdsch->nrOfLayers = target_dl_Nl;
   sched_pdsch->mcs = target_dl_mcs;
   sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
   sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
@@ -380,7 +384,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
                                         ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
                                         0 /* N_PRB_oh, 0 for initialBWP */,
                                         0 /* tb_scaling */,
-                                        1 /* nrOfLayers */)
+                                        sched_pdsch->nrOfLayers)
                          >> 3;
 
   /* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */
@@ -447,7 +451,16 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
     nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
 
   uint16_t rbStart = 0;
-  uint16_t rbSize = target_ul_bw;
+  uint16_t rbSize;
+
+  const int bw = NRRIV2BW(sched_ctrl->active_ubwp ?
+			  sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth :
+			  scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
+  if (target_ul_bw>bw)
+    rbSize = bw;
+  else
+    rbSize = target_ul_bw;
 
   uint16_t *vrb_map_UL =
       &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 64d9b72866889a83ca48d510b9eb5d1b30834739..f030a683ac1e0026ad1c68bed778d91309fb5eb0 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -599,7 +599,7 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
 }
 
 void config_uldci(const NR_BWP_Uplink_t *ubwp,
-		              const NR_ServingCellConfigCommon_t *scc,
+                  const NR_ServingCellConfigCommon_t *scc,
                   const nfapi_nr_pusch_pdu_t *pusch_pdu,
                   dci_pdu_rel15_t *dci_pdu_rel15,
                   int dci_format,
@@ -610,6 +610,7 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
   const int bw = NRRIV2BW(ubwp ?
 			  ubwp->bwp_Common->genericParameters.locationAndBandwidth :
 			  scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
   dci_pdu_rel15->frequency_domain_assignment.val =
       PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw);
   dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
@@ -672,6 +673,7 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) {
 
   return(default_pucch_csset[pucch_ResourceCommon]);
 }
+
 void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
                         NR_SearchSpace_t *ss,
                         NR_ControlResourceSet_t *coreset,
@@ -738,15 +740,15 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
 
 // This function configures pucch pdu fapi structure
 void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
-			                  NR_ServingCellConfigCommon_t *scc,
-			                  NR_CellGroupConfig_t *CellGroup,
-			                  NR_BWP_Uplink_t *bwp,
+                        NR_ServingCellConfigCommon_t *scc,
+                        NR_CellGroupConfig_t *CellGroup,
+                        NR_BWP_Uplink_t *bwp,
                         uint16_t rnti,
                         uint8_t pucch_resource,
                         uint16_t O_csi,
                         uint16_t O_ack,
                         uint8_t O_sr,
-			                  int r_pucch) {
+                        int r_pucch) {
 
   NR_PUCCH_Config_t *pucch_Config;
   NR_PUCCH_Resource_t *pucchres;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index a49b6f58a1bcb7f87a1d13c591dcc8b8528ef376..17c7bb92eba7a683ea431f627a91c3a984809dd0 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -1588,7 +1588,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
       n_ubwp = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
 
     config_uldci(sched_ctrl->active_ubwp,
-		             scc,
+                 scc,
                  pusch_pdu,
                  &uldci_payload,
                  ps->dci_format,
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 86268d9c7935eb3336ad5c54d3135ad7140b3afb..392631690ab642891494d80d7bd6a62f4d615330 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -383,6 +383,7 @@ typedef struct NR_sched_pdsch {
   uint8_t mcs;
 
   /// TBS-related info
+  uint8_t nrOfLayers;
   uint16_t R;
   uint8_t Qm;
   uint32_t tb_size;
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index b7e9c7c467b4aa3474629f088c86fa0894decad0..8d74f01fc241f2bb7327e4e1badfd9c6e1f366ef 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -631,7 +631,10 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  }
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dataScramblingIdentityPDSCH = NULL;
 
- bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
+ if (n_physical_antenna_ports > 1)// for MIMO, we use DMRS Config Type 2
+   bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type));
+ else
+   bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL;
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 3bd4285cffc12f59d8190ccad89d7abf6d26bdc3..354709faa1c3fe87c3f9834bc3ae56ce05722c2a 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -618,8 +618,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
 }
 
 static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
-  if (nbAnt != 1) {
-    LOG_W(HW, "rfsimulator: only 1 antenna tested\n");
+  if (nbAnt > 4) {
+    LOG_W(HW, "rfsimulator: only 4 antenna tested\n");
   }
 
   rfsimulator_state_t *t = device->priv;
@@ -736,14 +736,19 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
                       CirSize
                     );
         else { // no channel modeling
+          double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0
+                                     {0.5, 1.0, 0.5, 0.25},  //rx 1
+                                     {0.25, 0.5, 1.0, 0.5},  //rx 2
+                                     {0.125, 0.25, 0.5, 1.0}};//rx 3
+
           sample_t *out=(sample_t *)samplesVoid[a];
           int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas
 
           //LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx);
           for (int i=0; i < nsamps; i++) {//loop over nsamps
             for (int a_tx=0; a_tx<nbAnt_tx; a_tx++) { //sum up signals from nbAnt_tx antennas
-              out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r;
-              out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i;
+              out[i].r += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r*H_awgn_mimo[a][a_tx]);
+              out[i].i += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i*H_awgn_mimo[a][a_tx]);
             } // end for a_tx
           } // end for i (number of samps)
         } // end of no channel modeling