From ea72306c3855c5a4151fc6fb1d678bcc9c69ebe2 Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani <velumani@eurecom.fr>
Date: Fri, 21 Oct 2022 12:04:07 -0400
Subject: [PATCH] Moved DLSCH PHY structure to stack

---
 executables/nr-ue.c                           |   8 +-
 openair1/PHY/INIT/nr_init_ue.c                |  77 +-
 openair1/PHY/INIT/phy_init.h                  |   2 +
 .../nr_dl_channel_estimation.c                |  46 +-
 openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h |   5 +-
 .../PHY/NR_UE_ESTIMATION/nr_ue_measurements.c |   7 +-
 openair1/PHY/NR_UE_TRANSPORT/dci_nr.c         |   4 +-
 .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c   | 142 +--
 .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c   | 339 +++-----
 .../nr_dlsch_llr_computation.c                |  12 +-
 .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c     |  56 +-
 openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c        |   4 +-
 .../NR_UE_TRANSPORT/nr_transport_proto_ue.h   |  61 +-
 .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h     |  72 +-
 openair1/PHY/defs_nr_UE.h                     |   8 +-
 openair1/SCHED_NR_UE/defs.h                   |  16 +-
 openair1/SCHED_NR_UE/fapi_nr_ue_l1.c          |  64 +-
 openair1/SCHED_NR_UE/phy_procedures_nr_ue.c   | 808 +++++++-----------
 openair1/SIMULATION/NR_PHY/dlschsim.c         |  76 +-
 openair1/SIMULATION/NR_PHY/dlsim.c            |  18 +-
 openair1/SIMULATION/NR_PHY/pbchsim.c          |  14 +-
 openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c   |   7 +-
 22 files changed, 709 insertions(+), 1137 deletions(-)

diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 8b022adc62e..4a24ece1a2b 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -646,7 +646,7 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) {
   UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
   PHY_VARS_NR_UE    *UE   = rxtxD->UE;
   uint8_t gNB_id = 0;
-  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
+  nr_phy_data_t phy_data = {0};
 
   if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
     /* send tick to RLC and PDCP every ms */
@@ -662,7 +662,7 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) {
 
     if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
       nr_downlink_indication_t dl_indication;
-      nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id, &phy_pdcch_config);
+      nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id, &phy_data);
       UE->if_inst->dl_indication(&dl_indication, NULL);
     }
 
@@ -671,7 +671,7 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) {
     phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
 #else
     uint64_t a=rdtsc_oai();
-    phy_procedures_nrUE_RX(UE, proc, gNB_id, &phy_pdcch_config, &rxtxD->txFifo);
+    phy_procedures_nrUE_RX(UE, proc, gNB_id, &phy_data, &rxtxD->txFifo);
     LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
 #endif
 
@@ -889,7 +889,7 @@ void *UE_thread(void *arg) {
       continue;
     }
 
-    if (start_rx_stream==0) {
+    if (start_rx_stream == 0) {
       start_rx_stream=1;
       syncInFrame(UE, &timestamp);
       UE->rx_offset=0;
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 1b6441f922d..a27a4abe17e 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -34,6 +34,7 @@
 #include "PHY/NR_REFSIG/nr_refsig.h"
 #include "PHY/MODULATION/nr_modulation.h"
 #include "openair2/COMMON/prs_nr_paramdef.h"
+#include "SCHED_NR_UE/harq_nr.h"
 
 
 extern uint16_t beta_cqi[16];
@@ -627,21 +628,74 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   }
 }
 
+void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb) {
+
+  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS;
+  if (num_rb != 273) {
+    a_segments = a_segments*num_rb;
+    a_segments = (a_segments/273)+1;
+  }
+
+  for (int i=0; i<number_of_processes; i++) {
+    free_and_zero(harq_list[i].b);
+
+    for (int r=0; r<a_segments; r++) {
+      free_and_zero(harq_list[i].c[r]);
+      free_and_zero(harq_list[i].d[r]);
+    }
+    free_and_zero(harq_list[i].c);
+    free_and_zero(harq_list[i].d);
+  }
+}
+
 void term_nr_ue_transport(PHY_VARS_NR_UE *ue)
 {
   const int N_RB_DL = ue->frame_parms.N_RB_DL;
+  int num_cw = NR_MAX_NB_LAYERS > 4? 2:1;
   for (int i = 0; i < NUMBER_OF_CONNECTED_gNB_MAX; i++) {
-    for (int j = 0; j < 2; j++) {
-      free_nr_ue_dlsch(&ue->dlsch[i][j], N_RB_DL);
-      if (j==0)
-        free_nr_ue_ulsch(&ue->ulsch[i], N_RB_DL, &ue->frame_parms);
+    for (int j = 0; j < num_cw; j++) {
+      free_nr_ue_dl_harq(ue->dl_harq_processes[j], NR_MAX_DLSCH_HARQ_PROCESSES, N_RB_DL);
+      free_nr_ue_ulsch(&ue->ulsch[i], N_RB_DL, &ue->frame_parms);
     }
+  }
+}
+
+void nr_init_harq_processes(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb) {
 
-    free_nr_ue_dlsch(&ue->dlsch_SI[i], N_RB_DL);
-    free_nr_ue_dlsch(&ue->dlsch_ra[i], N_RB_DL);
+  int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS;  //number of segments to be allocated
+  if (num_rb != 273) {
+    a_segments = a_segments*num_rb;
+    a_segments = (a_segments/273)+1;
   }
 
-  free_nr_ue_dlsch(&ue->dlsch_MCH[0], N_RB_DL);
+  uint32_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
+
+  for (int i=0; i<number_of_processes; i++) {
+    memset(harq_list + i, 0, sizeof(NR_DL_UE_HARQ_t));
+    init_downlink_harq_status(harq_list + i);
+    harq_list[i].b = malloc16(dlsch_bytes);
+
+    if (harq_list[i].b)
+      memset(harq_list[i].b, 0, dlsch_bytes);
+    else
+      AssertFatal(true, "Unable to reset harq memory \"b\"\n");
+
+    harq_list[i].c = malloc16(a_segments*sizeof(uint8_t *));
+    harq_list[i].d = malloc16(a_segments*sizeof(int16_t *));
+    for (int r=0; r<a_segments; r++) {
+      harq_list[i].c[r] = malloc16(1056);
+      harq_list[i].d[r] = malloc16(5*8448*sizeof(int16_t));
+      if (harq_list[i].c[r])
+        memset(harq_list[i].c[r],0,1056);
+      else
+        AssertFatal(true, "Unable to reset harq memory \"c\"\n");
+
+      if (harq_list[i].d[r])
+        memset(harq_list[i].d[r],0,5*8448);
+      else
+        AssertFatal(true, "Unable to reset harq memory \"d\"\n");
+    }
+  }
 }
 
 void init_nr_ue_transport(PHY_VARS_NR_UE *ue) {
@@ -650,21 +704,14 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue) {
 
   for (int i = 0; i < NUMBER_OF_CONNECTED_gNB_MAX; i++) {
     for (int j=0; j<num_codeword; j++) {
-      AssertFatal((ue->dlsch[i][j]  = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,ue->max_ldpc_iterations,ue->frame_parms.N_RB_DL))!=NULL,"Can't get ue dlsch structures\n");
-      LOG_D(PHY,"dlsch[%d][%d] => %p\n",i,j,ue->dlsch[i][j]);
+      nr_init_harq_processes(ue->dl_harq_processes[j], NR_MAX_DLSCH_HARQ_PROCESSES, ue->frame_parms.N_RB_DL);
       if (j==0) {
         AssertFatal((ue->ulsch[i] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NR_MAX_ULSCH_HARQ_PROCESSES,&ue->frame_parms))!=NULL,"Can't get ue ulsch structures\n");
         LOG_D(PHY,"ulsch[%d] => %p\n",i,ue->ulsch[i]);
       }
     }
-
-    ue->dlsch_SI[i]  = new_nr_ue_dlsch(1,1,NSOFT,ue->max_ldpc_iterations,ue->frame_parms.N_RB_DL);
-    ue->dlsch_ra[i]  = new_nr_ue_dlsch(1,1,NSOFT,ue->max_ldpc_iterations,ue->frame_parms.N_RB_DL);
   }
 
-  //ue->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1;
-  ue->dlsch_MCH[0]  = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL);
-
   for(int i=0; i<5; i++)
     ue->dl_stats[i] = 0;
 }
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index 2b11371de8f..40d9d12d3ce 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -418,6 +418,8 @@ void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg);
 
 void RCconfig_nrUE_prs(void *cfg);
 void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue);
+void nr_init_harq_processes(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb);
+void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb);
 
 /** @} */
 #endif
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 f15b99fb1c3..d0e2b87b88b 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -2206,7 +2206,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
                               unsigned char symbol,
                               uint32_t nb_re_pdsch,
                               uint16_t rnti,
-                              RX_type_t rx_type)
+                              NR_UE_DLSCH_t dlsch[2])
 {
   //#define DEBUG_DL_PTRS 1
   int32_t *ptrs_re_symbol = NULL;
@@ -2225,30 +2225,30 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
   uint16_t *nb_rb           = NULL;
 
   if(dlsch0_harq->status == ACTIVE) {
-    symbInSlot      = dlsch0_harq->start_symbol + dlsch0_harq->nb_symbols;
-    startSymbIndex  = &dlsch0_harq->start_symbol;
-    nbSymb          = &dlsch0_harq->nb_symbols;
-    L_ptrs          = &dlsch0_harq->PTRSTimeDensity;
-    K_ptrs          = &dlsch0_harq->PTRSFreqDensity;
-    dmrsSymbPos     = &dlsch0_harq->dlDmrsSymbPos;
-    ptrsSymbPos     = &dlsch0_harq->ptrs_symbols;
-    ptrsSymbIdx     = &dlsch0_harq->ptrs_symbol_index;
-    ptrsReOffset    = &dlsch0_harq->PTRSReOffset;
-    dmrsConfigType  = &dlsch0_harq->dmrsConfigType;
-    nb_rb           = &dlsch0_harq->nb_rb;
+    symbInSlot      = dlsch[0].dlsch_config.start_symbol + dlsch[0].dlsch_config.number_symbols;
+    startSymbIndex  = &dlsch[0].dlsch_config.start_symbol;
+    nbSymb          = &dlsch[0].dlsch_config.number_symbols;
+    L_ptrs          = &dlsch[0].dlsch_config.PTRSTimeDensity;
+    K_ptrs          = &dlsch[0].dlsch_config.PTRSFreqDensity;
+    dmrsSymbPos     = &dlsch[0].dlsch_config.dlDmrsSymbPos;
+    ptrsReOffset    = &dlsch[0].dlsch_config.PTRSReOffset;
+    dmrsConfigType  = &dlsch[0].dlsch_config.dmrsConfigType;
+    nb_rb           = &dlsch[0].dlsch_config.number_rbs;
+    ptrsSymbPos     = &dlsch[0].ptrs_symbols;
+    ptrsSymbIdx     = &dlsch[0].ptrs_symbol_index;
   }
   if(dlsch1_harq) {
-    symbInSlot      = dlsch1_harq->start_symbol + dlsch0_harq->nb_symbols;
-    startSymbIndex  = &dlsch1_harq->start_symbol;
-    nbSymb          = &dlsch1_harq->nb_symbols;
-    L_ptrs          = &dlsch1_harq->PTRSTimeDensity;
-    K_ptrs          = &dlsch1_harq->PTRSFreqDensity;
-    dmrsSymbPos     = &dlsch1_harq->dlDmrsSymbPos;
-    ptrsSymbPos     = &dlsch1_harq->ptrs_symbols;
-    ptrsSymbIdx     = &dlsch1_harq->ptrs_symbol_index;
-    ptrsReOffset    = &dlsch1_harq->PTRSReOffset;
-    dmrsConfigType  = &dlsch1_harq->dmrsConfigType;
-    nb_rb           = &dlsch1_harq->nb_rb;
+    symbInSlot      = dlsch[1].dlsch_config.start_symbol + dlsch[1].dlsch_config.number_symbols;
+    startSymbIndex  = &dlsch[1].dlsch_config.start_symbol;
+    nbSymb          = &dlsch[1].dlsch_config.number_symbols;
+    L_ptrs          = &dlsch[1].dlsch_config.PTRSTimeDensity;
+    K_ptrs          = &dlsch[1].dlsch_config.PTRSFreqDensity;
+    dmrsSymbPos     = &dlsch[1].dlsch_config.dlDmrsSymbPos;
+    ptrsReOffset    = &dlsch[1].dlsch_config.PTRSReOffset;
+    dmrsConfigType  = &dlsch[1].dlsch_config.dmrsConfigType;
+    nb_rb           = &dlsch[1].dlsch_config.number_rbs;
+    ptrsSymbPos     = &dlsch[1].ptrs_symbols;
+    ptrsSymbIdx     = &dlsch[1].ptrs_symbol_index;
   }
   /* loop over antennas */
   for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index f01a2af6061..d1cab858c72 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -107,7 +107,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
                       
 void nr_ue_measurements(PHY_VARS_NR_UE *ue,
                         UE_nr_rxtx_proc_t *proc,
-                        uint8_t slot);
+                        uint8_t slot,
+                        NR_UE_DLSCH_t *dlsch);
 
 void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
                                  uint8_t gNB_index,
@@ -134,7 +135,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
                               unsigned char symbol,
                               uint32_t nb_re_pdsch,
                               uint16_t rnti,
-                              RX_type_t rx_type);
+                              NR_UE_DLSCH_t dlsch[2]);
 
 float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
 
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
index b0756282a3d..69a1a88916e 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
@@ -112,14 +112,13 @@ float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index)
 
 void nr_ue_measurements(PHY_VARS_NR_UE *ue,
                         UE_nr_rxtx_proc_t *proc,
-                        uint8_t slot)
+                        uint8_t slot,
+                        NR_UE_DLSCH_t *dlsch)
 {
   int aarx, aatx, gNB_id = 0;
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   int ch_offset = frame_parms->ofdm_symbol_size*2;
-  NR_UE_DLSCH_t *dlsch = ue->dlsch[gNB_id][0];
-  uint8_t harq_pid = dlsch->current_harq_pid;
-  int N_RB_DL = dlsch->harq_processes[harq_pid]->nb_rb;
+  int N_RB_DL = dlsch->dlsch_config.number_rbs;
 
   ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx;
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index cf237ef1fe4..4d3d874a325 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -863,8 +863,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
                                   int16_t *pdcch_e_rx,
                                   fapi_nr_dci_indication_t *dci_ind,
-                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
-                                  NR_UE_PDCCH_CONFIG *phy_pdcch_config) {
+                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
 
   //int gNB_id = 0;
   int16_t tmp_e[16*108];
@@ -941,7 +940,6 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
     }
     e_rx_cand_idx += 9*L*6*2; //e_rx index for next candidate (L CCEs, 6 REGs per CCE and 9 REs per REG and 2 uint16_t per RE)
   }
-  phy_pdcch_config->nb_search_space = 0;
   return(dci_ind->number_of_dcis);
 }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index e858e8d5644..dc4a28aff26 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -57,107 +57,12 @@ notifiedFIFO_t freeBlocks_dl;
 notifiedFIFO_elt_t *msgToPush_dl;
 int nbDlProcessing =0;
 
-void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr, uint16_t N_RB_DL) {
-
-  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS;
-
-  NR_UE_DLSCH_t *dlsch=*dlschptr;
-
-  if (dlsch) {
-    if (N_RB_DL != 273) {
-      a_segments = a_segments*N_RB_DL;
-      a_segments = a_segments/273 +1;
-    }
-
-    for (int i=0; i<dlsch->Mdlharq; i++) {
-      if (dlsch->harq_processes[i]) {
-        if (dlsch->harq_processes[i]->b) {
-          free16(dlsch->harq_processes[i]->b,a_segments*1056);
-          dlsch->harq_processes[i]->b = NULL;
-        }
-
-        for (int r=0; r<a_segments; r++) {
-          free16(dlsch->harq_processes[i]->c[r],1056);
-          dlsch->harq_processes[i]->c[r] = NULL;
-          free16(dlsch->harq_processes[i]->d[r],5*8448);
-          dlsch->harq_processes[i]->d[r] = NULL;
-        }
-        free16(dlsch->harq_processes[i]->c,a_segments);
-        free16(dlsch->harq_processes[i]->d,a_segments);
-
-        free16(dlsch->harq_processes[i],sizeof(NR_DL_UE_HARQ_t));
-        dlsch->harq_processes[i] = NULL;
-      }
-    }
-
-    free16(dlsch,sizeof(NR_UE_DLSCH_t));
-    dlsch = NULL;
-  }
-}
-
-
-NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_ldpc_iterations,uint16_t N_RB_DL) {
-
-  NR_UE_DLSCH_t *dlsch;
-  uint8_t exit_flag = 0;
-
-  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS;  //number of segments to be allocated
-
-  if (N_RB_DL != 273) {
-    a_segments = a_segments*N_RB_DL;
-    a_segments = (a_segments/273)+1;
-  }
-
-  uint32_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
-  dlsch = (NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));
-
-  if (dlsch) {
-    memset(dlsch,0,sizeof(NR_UE_DLSCH_t));
-    dlsch->Kmimo = Kmimo;
-    dlsch->Mdlharq = Mdlharq;
-    dlsch->number_harq_processes_for_pdsch = Mdlharq;
-    dlsch->Nsoft = Nsoft;
+void nr_ue_dlsch_init(NR_UE_DLSCH_t *dlsch_list, int num_dlsch, uint8_t max_ldpc_iterations) {
+  for (int i=0; i < num_dlsch; i++) {
+    NR_UE_DLSCH_t *dlsch = dlsch_list + i;
+    memset(dlsch, 0, sizeof(NR_UE_DLSCH_t));
     dlsch->max_ldpc_iterations = max_ldpc_iterations;
-
-    for (int i=0; i<Mdlharq; i++) {
-      dlsch->harq_processes[i] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t));
-
-      if (dlsch->harq_processes[i]) {
-        memset(dlsch->harq_processes[i],0,sizeof(NR_DL_UE_HARQ_t));
-        init_downlink_harq_status(dlsch->harq_processes[i]);
-        dlsch->harq_processes[i]->first_rx=1;
-        dlsch->harq_processes[i]->b = (uint8_t *)malloc16(dlsch_bytes);
-
-        if (dlsch->harq_processes[i]->b)
-          memset(dlsch->harq_processes[i]->b,0,dlsch_bytes);
-        else
-          exit_flag=3;
-
-        dlsch->harq_processes[i]->c = (uint8_t **)malloc16(a_segments*sizeof(uint8_t *));
-        dlsch->harq_processes[i]->d = (int16_t **)malloc16(a_segments*sizeof(int16_t *));
-        for (int r=0; r<a_segments; r++) {
-          dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(1056);
-          dlsch->harq_processes[i]->d[r] = (int16_t *)malloc16(5*8448*sizeof(int16_t));
-          if (dlsch->harq_processes[i]->c[r])
-            memset(dlsch->harq_processes[i]->c[r],0,1056);
-          if (dlsch->harq_processes[i]->d[r])
-            memset(dlsch->harq_processes[i]->d[r],0,5*8448);
-          else
-            exit_flag=2;
-
-        }
-      } else {
-        exit_flag=1;
-      }
-    }
-
-    if (exit_flag==0)
-      return(dlsch);
   }
-
-  LOG_D(PHY,"new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
-  free_nr_ue_dlsch(&dlsch,N_RB_DL);
-  return(NULL);
 }
 
 void nr_dlsch_unscrambling(int16_t *llr, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI)
@@ -300,7 +205,7 @@ void nr_processDLSegment(void* arg) {
                                harq_process->d[r],
                                w,
                                harq_process->C,
-                               harq_process->rvidx,
+                               dlsch->dlsch_config.rv,
                                harq_process->first_rx,
                                E,
                                harq_process->F,
@@ -400,8 +305,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
                            uint32_t frame,
                            uint16_t nb_symb_sch,
                            uint8_t nr_slot_rx,
-                           uint8_t harq_pid,
-                           uint8_t is_crnti) {
+                           uint8_t harq_pid) {
   uint32_t A,E;
   uint32_t G;
   uint32_t ret,offset;
@@ -416,20 +320,20 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 
   // HARQ stats
   phy_vars_ue->dl_stats[harq_process->DLround]++;
-  LOG_D(PHY,"Round %d RV idx %d\n",harq_process->DLround,harq_process->rvidx);
+  LOG_D(PHY,"Round %d RV idx %d\n",harq_process->DLround,dlsch->dlsch_config.rv);
   uint8_t kc;
   uint16_t nb_rb;// = 30;
-  uint8_t dmrs_Type = harq_process->dmrsConfigType;
+  uint8_t dmrs_Type = dlsch->dlsch_config.dmrsConfigType;
   AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
   uint8_t nb_re_dmrs;
 
   if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) {
-    nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
+    nb_re_dmrs = 6*dlsch->dlsch_config.n_dmrs_cdm_groups;
   } else {
-    nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
+    nb_re_dmrs = 4*dlsch->dlsch_config.n_dmrs_cdm_groups;
   }
 
-  uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
+  uint16_t dmrs_length = get_num_dmrs(dlsch->dlsch_config.dlDmrsSymbPos);
   vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
 
   //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0];
@@ -466,18 +370,18 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
     return(max_ldpc_iterations + 1);
   }
   */
-  nb_rb = harq_process->nb_rb;
-  A = harq_process->TBS;
+  nb_rb = dlsch->dlsch_config.number_rbs;
+  A = dlsch->dlsch_config.TBS;
   ret = dlsch->max_ldpc_iterations + 1;
   dlsch->last_iteration_cnt = ret;
-  harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, harq_process->Qm,harq_process->Nl);
+  harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, dlsch->dlsch_config.qamModOrder,dlsch->Nl);
   G = harq_process->G;
 
   // target_code_rate is in 0.1 units
-  float Coderate = (float) harq_process->R / 10240.0f;
+  float Coderate = (float) dlsch->dlsch_config.targetCodeRate / 10240.0f;
 
   LOG_D(PHY,"%d.%d DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d Qm %d Coderate %f\n",
-        frame,nr_slot_rx,harq_pid,A,A/8,G, nb_re_dmrs, dmrs_length, harq_process->mcs, harq_process->Nl, nb_symb_sch, nb_rb, harq_process->Qm, Coderate);
+        frame,nr_slot_rx,harq_pid,A,A/8,G, nb_re_dmrs, dmrs_length, dlsch->dlsch_config.mcs, dlsch->Nl, nb_symb_sch, nb_rb, dlsch->dlsch_config.qamModOrder, Coderate);
 
   if ((A <=292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
     p_decParams->BG = 2;
@@ -503,13 +407,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
                     &harq_process->F,
                     p_decParams->BG);
 
-    if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*harq_process->Nl) {
+    if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*dlsch->Nl) {
       LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B);
       return(-1);
     }
 
     if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!frame%100))
-      LOG_I(PHY,"K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, harq_process->Nl);
+      LOG_I(PHY,"K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, dlsch->Nl);
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
@@ -519,7 +423,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
   p_decParams->outMode= 0;
   r_offset = 0;
-  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*harq_process->Nl;  //number of segments to be allocated
+  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*dlsch->Nl;  //number of segments to be allocated
 
   if (nb_rb != 273) {
     a_segments = a_segments*nb_rb;
@@ -542,7 +446,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   initNotifiedFIFO(&nf);
   for (r=0; r<harq_process->C; r++) {
     //printf("start rx segment %d\n",r);
-    E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
+    E = nr_get_E(G, harq_process->C, dlsch->dlsch_config.qamModOrder, dlsch->Nl, r);
     union ldpcReqUnion id = {.s={dlsch->rnti,frame,nr_slot_rx,0,0}};
     notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(ldpcDecode_ue_t), id.p, &nf, nr_processDLSegment_ptr);
     ldpcDecode_ue_t * rdata=(ldpcDecode_ue_t *) NotifiedFifoData(req);
@@ -557,11 +461,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
     rdata->nbSegments = harq_process->C;
     rdata->E = E;
     rdata->A = A;
-    rdata->Qm = harq_process->Qm;
+    rdata->Qm = dlsch->dlsch_config.qamModOrder;
     rdata->r_offset = r_offset;
     rdata->Kr_bytes = Kr_bytes;
-    rdata->rv_index = harq_process->rvidx;
-    rdata->Tbslbrm = harq_process->tbslbrm;
+    rdata->rv_index = dlsch->dlsch_config.rv;
+    rdata->Tbslbrm = dlsch->dlsch_config.tbslbrm;
     rdata->offset = offset;
     rdata->dlsch = dlsch;
     rdata->dlsch_id = 0;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 75e3717c36d..2a3de5a9bc8 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -110,7 +110,6 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         int32_t **dl_ch_mag_ptr,
                         NR_DL_UE_HARQ_t *dlsch0_harq,
                         NR_DL_UE_HARQ_t *dlsch1_harq,
-                        RX_type_t rx_type,
                         unsigned char harq_pid,
                         unsigned char gNB_id,
                         unsigned char gNB_id_i,
@@ -121,21 +120,19 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         int32_t codeword_TB1,
                         uint32_t len,
                         uint8_t nr_slot_rx,
-                        uint8_t beamforming_mode);
+                        NR_UE_DLSCH_t *dlsch);
 
 
 /* Main Function */
 int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                 UE_nr_rxtx_proc_t *proc,
-                PDSCH_t type,
+                NR_UE_DLSCH_t *dlsch,
                 unsigned char gNB_id,
                 unsigned char gNB_id_i,
                 uint32_t frame,
                 uint8_t nr_slot_rx,
                 unsigned char symbol,
                 unsigned char first_symbol_flag,
-                RX_type_t rx_type,
-                unsigned char i_mod,
                 unsigned char harq_pid)
 {
 
@@ -143,7 +140,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   NR_UE_PDSCH **pdsch_vars;
   NR_DL_FRAME_PARMS *frame_parms    = &ue->frame_parms;
   PHY_NR_MEASUREMENTS *measurements = &ue->measurements;
-  NR_UE_DLSCH_t   **dlsch;
 
   int avg[16];
 //  int avg_0[2];
@@ -156,8 +152,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   int avgs = 0;// rb;
   NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
 
-  uint8_t beamforming_mode = 0;
-
   int32_t **rxdataF_comp_ptr;
   int32_t **dl_ch_mag_ptr;
   int32_t codeword_TB0 = -1;
@@ -175,44 +169,20 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   uint16_t nbSymb=0;
   uint16_t pduBitmap=0x0;
 
-  switch (type) {
-  case SI_PDSCH:
-    pdsch_vars = ue->pdsch_vars;
-    dlsch = &ue->dlsch_SI[gNB_id];
-    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-
-    break;
-
-  case RA_PDSCH:
-    pdsch_vars = ue->pdsch_vars;
-    dlsch = &ue->dlsch_ra[gNB_id];
-    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-
-    break;
-
-  case PDSCH:
-    pdsch_vars = ue->pdsch_vars;
-    dlsch = ue->dlsch[gNB_id];
-    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-    if (NR_MAX_NB_LAYERS>4)
-      dlsch1_harq = dlsch[1]->harq_processes[harq_pid];
-    break;
-
-  default:
-    LOG_E(PHY, "[UE][FATAL] nr_slot_rx %d: Unknown PDSCH format %d\n", nr_slot_rx, type);
-    return -1;
-    break;
-  }
+  pdsch_vars = ue->pdsch_vars;
+  dlsch0_harq = &ue->dl_harq_processes[0][harq_pid];
+  if (NR_MAX_NB_LAYERS>4)
+    dlsch1_harq = &ue->dl_harq_processes[1][harq_pid];
 
   if (dlsch0_harq && dlsch1_harq){
 
     LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_slot_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status);
 
     if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status == ACTIVE)){
-      codeword_TB0 = dlsch0_harq->codeword;
+      codeword_TB0 = dlsch0_harq->codeword; // SV: where is this set? revisit for DL MIMO.
       codeword_TB1 = dlsch1_harq->codeword;
-      dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid];
-      dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
+      dlsch0_harq = &ue->dl_harq_processes[codeword_TB0][harq_pid];
+      dlsch1_harq = &ue->dl_harq_processes[codeword_TB1][harq_pid];
 
       #ifdef DEBUG_HARQ
         printf("[DEMOD] I am assuming both TBs are active, in cw0 %d and cw1 %d \n", codeword_TB0, codeword_TB1);
@@ -220,7 +190,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
 
     } else if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status != ACTIVE) ) {
       codeword_TB0 = dlsch0_harq->codeword;
-      dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid];
+      dlsch0_harq = &ue->dl_harq_processes[codeword_TB0][harq_pid];
       dlsch1_harq = NULL;
 
       #ifdef DEBUG_HARQ
@@ -230,7 +200,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     } else if ((dlsch0_harq->status != ACTIVE) && (dlsch1_harq->status == ACTIVE)){
       codeword_TB1 = dlsch1_harq->codeword;
       dlsch0_harq  = NULL;
-      dlsch1_harq  = dlsch[codeword_TB1]->harq_processes[harq_pid];
+      dlsch1_harq  = &ue->dl_harq_processes[codeword_TB1][harq_pid];
 
       #ifdef DEBUG_HARQ
         printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", codeword_TB1);
@@ -246,7 +216,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   } else if (dlsch0_harq) {
     if (dlsch0_harq->status == ACTIVE) {
       codeword_TB0 = dlsch0_harq->codeword;
-      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+      dlsch0_harq = &ue->dl_harq_processes[0][harq_pid];
 
       #ifdef DEBUG_HARQ
         printf("[DEMOD] I am assuming only TB0 is active\n");
@@ -265,8 +235,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
   #endif
 
-  start_rb = dlsch0_harq->start_rb;
-  nb_rb_pdsch =  dlsch0_harq->nb_rb;
+  start_rb = dlsch[0].dlsch_config.start_rb;
+  nb_rb_pdsch =  dlsch[0].dlsch_config.number_rbs;
 
   DevAssert(dlsch0_harq);
 
@@ -281,11 +251,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     return(-1);
   }
 
-  if (!dlsch[0]) {
-    LOG_W(PHY,"dlsch_demodulation.c: Null dlsch_ue pointer\n");
-    return(-1);
-  }
-
   if (!pdsch_vars) {
     LOG_W(PHY,"dlsch_demodulation.c: Null pdsch_vars pointer\n");
     return(-1);
@@ -301,8 +266,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
       slot = 1;
   }
 
-  uint8_t pilots = (dlsch0_harq->dlDmrsSymbPos >> symbol) & 1;
-  uint8_t config_type = dlsch0_harq->dmrsConfigType;
+  uint8_t pilots = (dlsch[0].dlsch_config.dlDmrsSymbPos >> symbol) & 1;
+  uint8_t config_type = dlsch[0].dlsch_config.dmrsConfigType;
   //----------------------------------------------------------
   //--------------------- RBs extraction ---------------------
   //----------------------------------------------------------
@@ -314,21 +279,21 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                        symbol,
                        pilots,
                        config_type,
-                       start_rb + dlsch0_harq->BWPStart,
+                       start_rb + dlsch[0].dlsch_config.BWPStart,
                        nb_rb_pdsch,
-                       dlsch0_harq->n_dmrs_cdm_groups,
-                       dlsch0_harq->Nl,
+                       dlsch[0].dlsch_config.n_dmrs_cdm_groups,
+                       dlsch[0].Nl,
                        frame_parms,
-                       dlsch0_harq->dlDmrsSymbPos,
+                       dlsch[0].dlsch_config.dlDmrsSymbPos,
                        ue->chest_time);
   stop_meas(&ue->generic_stat_bis[slot]);
   if (cpumeas(CPUMEAS_GETSTATE))
-    LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
-	  frame,nr_slot_rx,slot,symbol,type,ue->generic_stat_bis[slot].p_time/(cpuf*1000.0));
+    LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Pilot/Data extraction %5.2f \n",
+	  frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[slot].p_time/(cpuf*1000.0));
 
-  int nl = dlsch0_harq->Nl;
+  int nl = dlsch[0].Nl;
   int n_rx = frame_parms->nb_antennas_rx;
-  nb_re_pdsch = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb_pdsch*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb_pdsch*(12-4*dlsch0_harq->n_dmrs_cdm_groups)) : (nb_rb_pdsch*12);
+  nb_re_pdsch = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb_pdsch*(12-6*dlsch[0].dlsch_config.n_dmrs_cdm_groups): nb_rb_pdsch*(12-4*dlsch[0].dlsch_config.n_dmrs_cdm_groups)) : (nb_rb_pdsch*12);
   //----------------------------------------------------------
   //--------------------- Channel Scaling --------------------
   //----------------------------------------------------------
@@ -337,7 +302,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                          frame_parms,
                          nl,
                          n_rx,
-                         dlsch,
                          symbol,
                          pilots,
                          nb_re_pdsch,
@@ -368,7 +332,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
         //LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
         median[(aatx*n_rx)+aarx] = avg[(aatx*n_rx)+aarx];
       }
-    if (dlsch0_harq->Nl > 1) {
+    if (dlsch[0].Nl > 1) {
       nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
                                     median,
                                     nl,
@@ -395,11 +359,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   stop_meas(&ue->generic_stat_bis[slot]);
 
 #if T_TRACER
-  if (type == PDSCH)
-  {
-    T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id),  T_INT(0), T_INT(frame%1024), T_INT(nr_slot_rx),
-                             T_INT(avg[0]), T_INT(avg[1]),    T_INT(avg[2]),             T_INT(avg[3]));
-  }
+  T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id),  T_INT(0), T_INT(frame%1024), T_INT(nr_slot_rx),
+                           T_INT(avg[0]), T_INT(avg[1]),    T_INT(avg[2]),             T_INT(avg[3]));
 #endif
 
   if (cpumeas(CPUMEAS_GETSTATE))
@@ -424,7 +385,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                 symbol,
                                 nb_re_pdsch,
                                 first_symbol_flag,
-                                dlsch0_harq->Qm,
+                                dlsch[0].dlsch_config.qamModOrder,
                                 nb_rb_pdsch,
                                 pdsch_vars[gNB_id]->log2_maxh,
                                 measurements); // log2_maxh+I0_shift
@@ -454,7 +415,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                  nb_rb_pdsch,
                                  n_rx,
                                  nl,
-                                 dlsch0_harq->Qm,
+                                 dlsch[0].dlsch_config.qamModOrder,
                                  pdsch_vars[gNB_id]->log2_maxh,
                                  symbol,
                                  nb_re_pdsch);
@@ -473,18 +434,18 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch;
 
   if(dlsch0_harq->status == ACTIVE) {
-    startSymbIdx = dlsch0_harq->start_symbol;
-    nbSymb = dlsch0_harq->nb_symbols;
-    pduBitmap = dlsch0_harq->pduBitmap;
+    startSymbIdx = dlsch[0].dlsch_config.start_symbol;
+    nbSymb = dlsch[0].dlsch_config.number_symbols;
+    pduBitmap = dlsch[0].dlsch_config.pduBitmap;
   }
   if(dlsch1_harq) {
-    startSymbIdx = dlsch1_harq->start_symbol;
-    nbSymb = dlsch1_harq->nb_symbols;
-    pduBitmap = dlsch1_harq->pduBitmap;
+    startSymbIdx = dlsch[1].dlsch_config.start_symbol;
+    nbSymb = dlsch[1].dlsch_config.number_symbols;
+    pduBitmap = dlsch[1].dlsch_config.pduBitmap;
   }
   
   /* Check for PTRS bitmap and process it respectively */
-  if((pduBitmap & 0x1) && (type == PDSCH)) {
+  if((pduBitmap & 0x1) && (dlsch[0].rnti_type == _C_RNTI_)) {
     nr_pdsch_ptrs_processing(ue,
                              pdsch_vars,
                              frame_parms,
@@ -494,7 +455,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                              nr_slot_rx,
                              symbol,
                              (nb_rb_pdsch*12),
-                             dlsch[0]->rnti,rx_type);
+                             dlsch[0].rnti,dlsch);
     pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
   }
   
@@ -512,33 +473,35 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
       nr_dlsch_llr(pdsch_vars, frame_parms,
                    rxdataF_comp_ptr, dl_ch_mag_ptr,
                    dlsch0_harq, dlsch1_harq,
-                   rx_type, harq_pid,
+                   harq_pid,
                    gNB_id, gNB_id_i,
                    first_symbol_flag,
                    i, nb_rb_pdsch,
                    codeword_TB0, codeword_TB1,
                    pdsch_vars[gNB_id]->dl_valid_re[i-1],
-                   nr_slot_rx, beamforming_mode);
+                   nr_slot_rx, dlsch);
     }
     
-    int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType;
+    int dmrs_type = dlsch[0].dlsch_config.dmrsConfigType;
     uint8_t nb_re_dmrs;
-    uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos);
+    uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos);
     if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
-      nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
+      nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
     } else {
-      nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
+      nb_re_dmrs = 4*dlsch[0].dlsch_config.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);
+
+    dlsch0_harq->G = nr_get_G(dlsch[0].dlsch_config.number_rbs,
+                              dlsch[0].dlsch_config.number_symbols,
+                              nb_re_dmrs,
+                              dmrs_len,
+                              dlsch[0].dlsch_config.qamModOrder,
+                              dlsch[0].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,
+                             dlsch[0].Nl,
+                             dlsch[0].dlsch_config.qamModOrder,
+                             dlsch0_harq->G,
                              codeword_TB0,
                              codeword_TB1,
                              pdsch_vars[gNB_id]->layer_llr);    
@@ -1345,7 +1308,6 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
 			    NR_DL_FRAME_PARMS *frame_parms,
 			    uint8_t n_tx,
 			    uint8_t n_rx,
-			    NR_UE_DLSCH_t **dlsch_ue,
 			    uint8_t symbol,
 			    uint8_t pilots,
 			    uint32_t len,
@@ -2387,7 +2349,6 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         int32_t **dl_ch_mag_ptr,
                         NR_DL_UE_HARQ_t *dlsch0_harq,
                         NR_DL_UE_HARQ_t *dlsch1_harq,
-                        RX_type_t rx_type,
                         unsigned char harq_pid,
                         unsigned char gNB_id,
                         unsigned char gNB_id_i,
@@ -2398,7 +2359,7 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         int32_t codeword_TB1,
                         uint32_t len,
                         uint8_t nr_slot_rx,
-                        uint8_t beamforming_mode)
+                        NR_UE_DLSCH_t *dlsch)
 {
   uint32_t llr_offset_symbol;
   
@@ -2406,133 +2367,78 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
     pdsch_vars[gNB_id]->llr_offset[symbol-1] = 0;
   llr_offset_symbol = pdsch_vars[gNB_id]->llr_offset[symbol-1];
 
-  pdsch_vars[gNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol;
+  pdsch_vars[gNB_id]->llr_offset[symbol] = len*dlsch->dlsch_config.qamModOrder + llr_offset_symbol;
  
-  /*LOG_I(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n",
-    symbol,
-    nb_rb,dlsch0_harq->Qm,
-    pdsch_vars[gNB_id]->llr_length[symbol],
-    pdsch_vars[gNB_id]->llr_offset[symbol],
-    (int16_t*)pdsch_vars[gNB_id]->llr[0],
-    pllr_symbol_cw0);*/
-
-  switch (dlsch0_harq->Qm) {
-  case 2 :
-    switch (rx_type) {
-      case rx_standard :
-        for(int l =0; l<dlsch0_harq->Nl; l++)
-          nr_dlsch_qpsk_llr(frame_parms,
+  switch (dlsch[0].dlsch_config.qamModOrder) {
+    case 2 :
+      for(int l=0; l < dlsch[0].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);
+      break;
+
+    case 4 :
+      for(int l=0; l < dlsch[0].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);
+      break;
+
+    case 6 :
+      for(int l=0; l < dlsch[0].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);
+      break;
+
+    case 8:
+      for(int l=0; l < dlsch[0].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 ://From LTE Code!!
-        //not implemented yet
-        break;
-      case rx_IC_dual_stream :
-        //not implemented yet
-        break;
-      case rx_SIC_dual_stream :
-        //not implemented yet
-        break;
-    }
-    break;
-  case 4 :
-    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 :
-    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;
-    }
+                            nb_rb);
+      break;
 
-    break;
-  case 8:
-    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:
-    LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
-    return(-1);
-    break;
+    default:
+      LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
+      return(-1);
+      break;
   }
 
   if (dlsch1_harq) {
-    switch (dlsch1_harq->Qm) {
-    case 2 :
-      if (rx_type==rx_standard) {
+    switch (dlsch[1].dlsch_config.qamModOrder) {
+      case 2 :
         nr_dlsch_qpsk_llr(frame_parms,
                           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) {
+                          nb_rb);
+        break;
+
+      case 4:
         nr_dlsch_16qam_llr(frame_parms,
                            pdsch_vars[gNB_id]->rxdataF_comp0[0],
                            pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
@@ -2540,12 +2446,10 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                            symbol,
                            len,
                            first_symbol_flag,
-                           nb_rb,
-                           beamforming_mode);
-      }
-      break;
-    case 6 :
-      if (rx_type==rx_standard) {
+                           nb_rb);
+        break;
+
+      case 6 :
         nr_dlsch_64qam_llr(frame_parms,
                            pdsch_vars[gNB_id]->rxdataF_comp0[0],
                            pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
@@ -2554,12 +2458,10 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                            symbol,
                            len,
                            first_symbol_flag,
-                           nb_rb,
-                           beamforming_mode);
-        }
+                           nb_rb);
         break;
-    case 8 :
-      if (rx_type==rx_standard) {
+
+      case 8 :
         nr_dlsch_256qam_llr(frame_parms,
                             pdsch_vars[gNB_id]->rxdataF_comp0[0],
                             pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
@@ -2569,10 +2471,9 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                             symbol,
                             len,
                             first_symbol_flag,
-                            nb_rb,
-                            beamforming_mode);
-      }
+                            nb_rb);
         break;
+
       default:
         LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
         return(-1);
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 6f8ec17f581..d97cef81fd9 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
@@ -634,8 +634,7 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
                    uint8_t symbol,
                    uint32_t len,
                    uint8_t first_symbol_flag,
-                   uint16_t nb_rb,
-                   uint8_t beamforming_mode)
+                   uint16_t nb_rb)
 {
 
   c16_t *rxF   = (c16_t *)&rxdataF_comp[((int32_t)symbol*nb_rb*12)];
@@ -677,8 +676,7 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
-                     uint16_t nb_rb,
-                     uint8_t beamforming_mode)
+                     uint16_t nb_rb)
 {
 
 #if defined(__x86_64__) || defined(__i386__)
@@ -780,8 +778,7 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
 			uint8_t symbol,
 			uint32_t len,
 			uint8_t first_symbol_flag,
-			uint16_t nb_rb,
-			uint8_t beamforming_mode)
+			uint16_t nb_rb)
 {
 #if defined(__x86_64__) || defined(__i386__)
   __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
@@ -923,8 +920,7 @@ void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
-                     uint16_t nb_rb,
-                     uint8_t beamforming_mode)
+                     uint16_t nb_rb)
 {
   __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
   __m128i *ch_mag,*ch_magb,*ch_magr;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index 6bf425974d0..fa7d0381be1 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -101,7 +101,7 @@ void free_list(NR_UE_SSB *node) {
 }
 
 
-int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, NR_UE_PDCCH_CONFIG *phy_pdcch_config)
+int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, nr_phy_data_t *phy_data)
 {
   NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   int ret =-1;
@@ -165,7 +165,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
                      0,
                      temp_ptr->i_ssb,
                      SISO,
-                     phy_pdcch_config,
+                     phy_data,
                      &result);
 
     temp_ptr=temp_ptr->next_ssb;
@@ -216,7 +216,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
   int ret=-1;
   int rx_power=0; //aarx,
 
-  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
+  nr_phy_data_t phy_data = {0};
+  NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data.phy_pdcch_config;
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN);
 
@@ -336,7 +337,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
 
       if (ret==0) { //we got sss channel
         nr_gold_pbch(ue);
-        ret = nr_pbch_detection(proc, ue, 1, &phy_pdcch_config);  // start pbch detection at first symbol after pss
+        ret = nr_pbch_detection(proc, ue, 1, &phy_data);  // start pbch detection at first symbol after pss
       }
 
       if (ret == 0) {
@@ -518,6 +519,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
 
   // if stand alone and sync on ssb do sib1 detection as part of initial sync
   if (sa==1 && ret==0) {
+    nr_ue_dlsch_init(phy_data.dlsch, 1, ue->max_ldpc_iterations);
     bool dec = false;
     int gnb_id = 0; //FIXME
 
@@ -525,65 +527,59 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
     int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16);
     __attribute__ ((aligned(16))) int32_t pdcch_dl_ch_estimates[4*fp->nb_antennas_rx][pdcch_est_size];
 
-    for(int n_ss = 0; n_ss<phy_pdcch_config.nb_search_space; n_ss++) {
-      proc->nr_slot_rx = phy_pdcch_config.slot; // setting PDCCH slot to proc
-      uint8_t nb_symb_pdcch = phy_pdcch_config.pdcch_config[n_ss].coreset.duration;
-      int start_symb = phy_pdcch_config.pdcch_config[n_ss].coreset.StartSymbolIndex;
+    for(int n_ss = 0; n_ss<phy_pdcch_config->nb_search_space; n_ss++) {
+      proc->nr_slot_rx = phy_pdcch_config->slot; // setting PDCCH slot to proc
+      uint8_t nb_symb_pdcch = phy_pdcch_config->pdcch_config[n_ss].coreset.duration;
+      int start_symb = phy_pdcch_config->pdcch_config[n_ss].coreset.StartSymbolIndex;
       for (uint16_t l=start_symb; l<start_symb+nb_symb_pdcch; l++) {
         nr_slot_fep_init_sync(ue,
                               proc,
                               l, // the UE PHY has no notion of the symbols to be monitored in the search space
-                              phy_pdcch_config.slot,
-                              is*fp->samples_per_frame+phy_pdcch_config.sfn*fp->samples_per_frame+ue->rx_offset,
+                              phy_pdcch_config->slot,
+                              is*fp->samples_per_frame+phy_pdcch_config->sfn*fp->samples_per_frame+ue->rx_offset,
                               true);
 
         nr_pdcch_channel_estimation(ue,
                                     proc,
                                     0,
-                                    phy_pdcch_config.slot,
+                                    phy_pdcch_config->slot,
                                     l,
-                                    &phy_pdcch_config.pdcch_config[n_ss].coreset,
+                                    &phy_pdcch_config->pdcch_config[n_ss].coreset,
                                     fp->first_carrier_offset,
-                                    phy_pdcch_config.pdcch_config[n_ss].BWPStart,
+                                    phy_pdcch_config->pdcch_config[n_ss].BWPStart,
                                     pdcch_est_size,
                                     pdcch_dl_ch_estimates);
 
       }
-      int  dci_cnt = nr_ue_pdcch_procedures(gnb_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, &phy_pdcch_config, n_ss);
+      int  dci_cnt = nr_ue_pdcch_procedures(gnb_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, &phy_data, n_ss);
       if (dci_cnt>0){
-        NR_UE_DLSCH_t *dlsch = ue->dlsch_SI[gnb_id];
-        if (dlsch && (dlsch->active == 1)) {
-          uint8_t harq_pid = dlsch->current_harq_pid;
-          NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid];
-          uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
-          uint16_t start_symb_sch = dlsch0_harq->start_symbol;
+        NR_UE_DLSCH_t *dlsch = phy_data.dlsch;
+        if (dlsch[0].active == 1) {
+          uint16_t nb_symb_sch = dlsch->dlsch_config.number_symbols;
+          uint16_t start_symb_sch = dlsch->dlsch_config.start_symbol;
 
           for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
             nr_slot_fep_init_sync(ue,
                                   proc,
                                   m,
-                                  phy_pdcch_config.slot,  // same slot and offset as pdcch
-                                  is*fp->samples_per_frame+phy_pdcch_config.sfn*fp->samples_per_frame+ue->rx_offset,
+                                  phy_pdcch_config->slot,  // same slot and offset as pdcch
+                                  is*fp->samples_per_frame+phy_pdcch_config->sfn*fp->samples_per_frame+ue->rx_offset,
                                   true);
           }
 
           int ret = nr_ue_pdsch_procedures(ue,
                                            proc,
                                            gnb_id,
-                                           SI_PDSCH,
-                                           ue->dlsch_SI[gnb_id],
-                                           NULL);
+                                           dlsch);
           if (ret >= 0)
             dec = nr_ue_dlsch_procedures(ue,
                                          proc,
                                          gnb_id,
-                                         SI_PDSCH,
-                                         ue->dlsch_SI[gnb_id],
-                                         NULL,
-                                         &ue->dlsch_SI_errors[gnb_id]);
+                                         dlsch,
+                                         NULL);
 
           // deactivate dlsch once dlsch proc is done
-          ue->dlsch_SI[gnb_id]->active = 0;
+          dlsch->active = 0;
         }
       }
     }
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index 7e9af83fe8d..2a037d1e70b 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -391,7 +391,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
                 uint8_t gNB_id,
                 uint8_t i_ssb,
                 MIMO_mode_t mimo_mode,
-                NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+                nr_phy_data_t *phy_data,
                 fapiPbch_t *result) {
 
   NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
@@ -580,7 +580,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
   fapi_nr_rx_indication_t *rx_ind=calloc(sizeof(*rx_ind),1);
   uint16_t number_pdus = 1;
 
-  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, phy_pdcch_config);
+  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, phy_data);
   nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus, proc,(void *)result);
 
   if (ue->if_inst && ue->if_inst->dl_indication)
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 48426a1774a..8e9bfd6201c 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -47,22 +47,10 @@
  * @{
  */
 
-/** \fn free_ue_dlsch(NR_UE_DLSCH_t *dlsch)
-    \brief This function frees memory allocated for a particular DLSCH at UE
-    @param dlsch Pointer to DLSCH to be removed
-*/
-void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlsch, uint16_t N_RB_DL);
-
 
-/** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft)
-    \brief This function allocates structures for a particular DLSCH at UE
-    @returns Pointer to DLSCH to be removed
-    @param Kmimo Kmimo factor from 36-212/36-213
-    @param Mdlharq Maximum number of HARQ rounds (36-212/36-213)
-    @param Nsoft Soft-LLR buffer size from UE-Category
-    @params N_RB_DL total number of resource blocks (determine the operating BW)
+/** \brief This function initialises structures for DLSCH at UE
 */
-NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint16_t N_RB_DL);
+void nr_ue_dlsch_init(NR_UE_DLSCH_t *dlsch_list, int num_dlsch, uint8_t max_ldpc_iterations);
 
 void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr,
                       uint16_t N_RB_UL,
@@ -478,8 +466,7 @@ int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
                    uint8_t symbol,
                    uint32_t len,
                    uint8_t first_symbol_flag,
-                   uint16_t nb_rb,
-                   uint8_t beamforming_mode);
+                   uint16_t nb_rb);
 
 /**
    \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
@@ -502,8 +489,7 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
-                     uint16_t nb_rb,
-                     uint8_t beamforming_mode);
+                     uint16_t nb_rb);
 /**
    \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
    @param frame_parms Frame descriptor structure
@@ -526,8 +512,7 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
-                     uint16_t nb_rb,
-                     uint8_t beamforming_mode);
+                     uint16_t nb_rb);
 
 void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
                      int32_t *rxdataF_comp,
@@ -538,8 +523,7 @@ void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
                      uint8_t symbol,
                      uint32_t len,
                      uint8_t first_symbol_flag,
-                     uint16_t nb_rb,
-                     uint8_t beamforming_mode);
+                     uint16_t nb_rb);
 
 
 /** \fn dlsch_extract_rbs(int32_t **rxdataF,
@@ -683,7 +667,6 @@ void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
                          NR_DL_FRAME_PARMS *frame_parms,
                          uint8_t n_tx,
                          uint8_t n_rx,
-                         NR_UE_DLSCH_t **dlsch_ue,
                          uint8_t symbol,
                          uint8_t start_symbol,
                          uint32_t len,
@@ -718,8 +701,7 @@ uint32_t  nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
                          uint32_t frame,
                          uint16_t nb_symb_sch,
                          uint8_t nr_slot_rx,
-                         uint8_t harq_pid,
-                         uint8_t is_crnti);
+                         uint8_t harq_pid);
 
 int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
                      NR_UE_ULSCH_t *ulsch,
@@ -800,13 +782,13 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
                uint8_t eNB_id,
                uint8_t i_ssb,
                MIMO_mode_t mimo_mode,
-               NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+               nr_phy_data_t *phy_data,
                fapiPbch_t* result);
 
 int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
                       PHY_VARS_NR_UE *ue,
                       int pbch_initial_symbol,
-                      NR_UE_PDCCH_CONFIG *phy_pdcch_config);
+                      nr_phy_data_t *phy_data);
 
 
 #ifndef modOrder
@@ -865,8 +847,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
                                   int16_t *pdcch_e_rx,
                                   fapi_nr_dci_indication_t *dci_ind,
-                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
-                                  NR_UE_PDCCH_CONFIG *phy_pdcch_config);
+                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
 
 
 /** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation.  It performs
@@ -884,21 +865,17 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
     @param nr_slot_rx Slot number
     @param symbol Symbol on which to act (within sub-frame)
     @param first_symbol_flag set to 1 on first DLSCH symbol
-    @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice.
-    @param i_mod Modulation order of the interfering stream
 */
 int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
-             UE_nr_rxtx_proc_t *proc,
-             PDSCH_t type,
-             unsigned char eNB_id,
-             unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
-             uint32_t frame,
-             uint8_t nr_slot_rx,
-             unsigned char symbol,
-             unsigned char first_symbol_flag,
-             RX_type_t rx_type,
-             unsigned char i_mod,
-             unsigned char harq_pid);
+                UE_nr_rxtx_proc_t *proc,
+                NR_UE_DLSCH_t *dlsch,
+                unsigned char gNB_id,
+                unsigned char gNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
+                uint32_t frame,
+                uint8_t nr_slot_rx,
+                unsigned char symbol,
+                unsigned char first_symbol_flag,
+                unsigned char harq_pid);
 
 int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot);
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index dc9ca67de4c..b91ad2b9cd4 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -183,16 +183,6 @@ typedef struct {
   int16_t **d;
   /// Index of current HARQ round for this DLSCH
   uint8_t DLround;
-  /// MCS table for this DLSCH
-  uint8_t mcs_table;
-  /// MCS format for this DLSCH
-  uint8_t mcs;
-  /// Qm (modulation order) for this DLSCH
-  uint8_t Qm;
-  /// target code rate R x 1024
-  uint16_t R;
-  /// Redundancy-version of the current sub-frame
-  uint8_t rvidx;
   /// MIMO mode for this DLSCH
   MIMO_nrmode_t mimo_mode;
   /// Number of code segments 
@@ -203,32 +193,10 @@ typedef struct {
   uint32_t F;
   /// LDPC lifting factor
   uint32_t Z;
-  /// Number of MIMO layers (streams) 
-  uint8_t Nl;
   /// current delta_pucch
   int8_t delta_PUCCH;
   /// Number of soft channel bits
   uint32_t G;
-  /// Start PRB of BWP
-  uint16_t BWPStart;
-  /// Number of PRBs in BWP
-  uint16_t BWPSize;
-  /// Current Number of RBs
-  uint16_t nb_rb;
-  /// Starting RB number
-  uint16_t start_rb;
-  /// Number of Symbols
-  uint16_t nb_symbols;
-  /// DMRS symbol positions
-  uint16_t dlDmrsSymbPos;
-  /// DMRS Configuration Type
-  uint8_t dmrsConfigType;
-  // Number of DMRS CDM groups with no data
-  uint8_t n_dmrs_cdm_groups;
-  /// DMRS ports bitmap
-  uint16_t dmrs_ports;
-  /// Starting Symbol number
-  uint16_t start_symbol;
   /// Current subband PMI allocation
   uint16_t pmi_alloc;
   /// Current RB allocation (even slots)
@@ -243,22 +211,6 @@ typedef struct {
   uint8_t codeword;
   /// HARQ-ACKs
   uint8_t ack;
-  /// PTRS Frequency Density
-  uint8_t PTRSFreqDensity;
-  /// PTRS Time Density
-  uint8_t PTRSTimeDensity;
-  uint8_t PTRSPortIndex ;
-  uint8_t nEpreRatioOfPDSCHToPTRS;
-  uint8_t PTRSReOffset;
-  /// bit mask of PT-RS ofdm symbol indicies
-  uint16_t ptrs_symbols;
-  // PTRS symbol index, to be updated every PTRS symbol within a slot.
-  uint8_t ptrs_symbol_index;
-  uint32_t tbslbrm;
-  uint8_t nscid;
-  uint16_t dlDmrsScramblingId;
-  /// PDU BITMAP 
-  uint16_t pduBitmap;
   /// Last index of LLR buffer that contains information.
   /// Used for computing LDPC decoder R
   int llrLen;
@@ -270,17 +222,13 @@ typedef struct {
   /// RNTI type
   uint8_t rnti_type;
   /// Active flag for DLSCH demodulation
-  uint8_t active;
-  /// accumulated tx power adjustment for PUCCH
-  int8_t g_pucch;
+  bool active;
   /// Transmission mode
   uint8_t mode1_flag;
   /// amplitude of PDSCH (compared to RS) in symbols without pilots
   int16_t sqrt_rho_a;
   /// amplitude of PDSCH (compared to RS) in symbols containing pilots
   int16_t sqrt_rho_b;
-  /// Current HARQ process id threadRx Odd and threadRx Even
-  uint8_t current_harq_pid;
   /// Current subband antenna selection
   uint32_t antenna_alloc;
   /// Current subband RI allocation
@@ -291,24 +239,22 @@ typedef struct {
   uint32_t cqi_alloc2;
   /// saved subband PMI allocation from last PUSCH/PUCCH report
   uint16_t pmi_alloc;
-  /// Pointers to up to HARQ processes
-  NR_DL_UE_HARQ_t *harq_processes[NR_MAX_DLSCH_HARQ_PROCESSES];
-  // DL number of harq processes
-  uint8_t number_harq_processes_for_pdsch;
+  /// Structure to hold dlsch config from MAC
+  fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config;
   /* higher layer parameter for reception of two transport blocks TS 38.213 9.1.3.1 Type-2 HARQ-ACK codebook dtermination */
   uint8_t Number_MCS_HARQ_DL_DCI;
   /* spatial bundling of PUCCH */
   uint8_t HARQ_ACK_spatial_bundling_PUCCH;
-  /// Maximum number of HARQ processes(for definition see 36-212 V8.6 2009-03, p.17
-  uint8_t Mdlharq;
-  /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17)
-  uint8_t Kmimo;
-  /// Nsoft parameter related to UE Category
-  uint32_t Nsoft;
+  /// Number of MIMO layers (streams) 
+  uint8_t Nl;
   /// Maximum number of LDPC iterations
   uint8_t max_ldpc_iterations;
   /// number of iterations used in last turbo decoding
   uint8_t last_iteration_cnt;
+  /// bit mask of PT-RS ofdm symbol indicies
+  uint16_t ptrs_symbols;
+  // PTRS symbol index, to be updated every PTRS symbol within a slot.
+  uint8_t ptrs_symbol_index;
 } NR_UE_DLSCH_t;
 
 typedef enum {format0_0,
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 7533ca685fb..8a73a4fb86a 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -538,14 +538,10 @@ typedef struct {
   NR_UE_CSI_IM    *csiim_vars[NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_CSI_RS    *csirs_vars[NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_SRS       *srs_vars[NUMBER_OF_CONNECTED_gNB_MAX];
-  NR_UE_DLSCH_t   *dlsch[NUMBER_OF_CONNECTED_gNB_MAX][NR_MAX_NB_LAYERS>4 ? 2:1];
   NR_UE_ULSCH_t   *ulsch[NUMBER_OF_CONNECTED_gNB_MAX];
-  NR_UE_DLSCH_t   *dlsch_SI[NUMBER_OF_CONNECTED_gNB_MAX];
-  NR_UE_DLSCH_t   *dlsch_ra[NUMBER_OF_CONNECTED_gNB_MAX];
-  NR_UE_DLSCH_t   *dlsch_p[NUMBER_OF_CONNECTED_gNB_MAX];
-  NR_UE_DLSCH_t   *dlsch_MCH[NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_PRS       *prs_vars[NR_MAX_PRS_COMB_SIZE];
   uint8_t          prs_active_gNBs;
+  NR_DL_UE_HARQ_t  dl_harq_processes[NR_MAX_NB_LAYERS>4 ? 2:1][NR_MAX_DLSCH_HARQ_PROCESSES];
   
   //Paging parameters
   uint32_t              IMSImod1024;
@@ -760,6 +756,8 @@ typedef struct {
 
 typedef struct nr_phy_data_s {
   NR_UE_PUCCH pucch_vars;
+  NR_UE_PDCCH_CONFIG phy_pdcch_config;
+  NR_UE_DLSCH_t dlsch[NR_MAX_NB_LAYERS>4 ? 2:1];
 } nr_phy_data_t;
 /* this structure is used to pass both UE phy vars and
  * proc to the function UE_thread_rxn_txnp4
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index 9ba3ac74b12..51749889c9e 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -96,7 +96,7 @@ typedef struct {
   @param proc Pointer to RXn-TXnp4 proc information
   @param eNB_id Local id of eNB on which to act
 */
-void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id);
+void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
 
 /*! \brief Scheduling for UE RX procedures in normal subframes.
   @param ue                     Pointer to UE variables on which to act
@@ -109,10 +109,10 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
-                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+                           nr_phy_data_t *phy_data,
                            notifiedFIFO_t *txFifo);
 
-int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
+int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
 
 void processSlotTX(void *arg);
 
@@ -176,22 +176,20 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
 bool nr_ue_dlsch_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 *dlsch_errors);
+                            NR_UE_DLSCH_t *dlsch1);
 
 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 gNB_id,
+                           NR_UE_DLSCH_t *dlsch);
 
 int nr_ue_pdcch_procedures(uint8_t gNB_id,
                            PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            int32_t pdcch_est_size,
                            int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
-                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+                           nr_phy_data_t *phy_data,
                            int n_ss);
 
 int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index cb4ffbe66c7..54ad0127183 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -289,61 +289,32 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
 
 
 void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
+                     NR_DL_UE_HARQ_t *harq_list,
                      fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
                      module_id_t module_id,
                      int rnti) {
 
   const uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
-  dlsch0->current_harq_pid = current_harq_pid;
-  dlsch0->active = 1;
+  dlsch0->active = true;
   dlsch0->rnti = rnti;
 
   LOG_D(PHY,"current_harq_pid = %d\n", current_harq_pid);
 
-  NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
-  AssertFatal(dlsch0_harq, "no harq_process for HARQ PID %d\n", current_harq_pid);
-
-  dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
-  dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
-  dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
-  dlsch0_harq->start_rb = dlsch_config_pdu->start_rb;
-  dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols;
-  dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol;
-  dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos;
-  dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType;
-  dlsch0_harq->n_dmrs_cdm_groups = dlsch_config_pdu->n_dmrs_cdm_groups;
-  dlsch0_harq->dmrs_ports = dlsch_config_pdu->dmrs_ports;
-  dlsch0_harq->mcs = dlsch_config_pdu->mcs;
-  dlsch0_harq->rvidx = dlsch_config_pdu->rv;
-  dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
-  dlsch0_harq->R = dlsch_config_pdu->targetCodeRate;
-  dlsch0_harq->Qm = dlsch_config_pdu->qamModOrder;
-  dlsch0_harq->TBS = dlsch_config_pdu->TBS;
-  dlsch0_harq->tbslbrm = dlsch_config_pdu->tbslbrm;
-  dlsch0_harq->nscid = dlsch_config_pdu->nscid;
-  dlsch0_harq->dlDmrsScramblingId = dlsch_config_pdu->dlDmrsScramblingId;
+  NR_DL_UE_HARQ_t *dlsch0_harq = &harq_list[current_harq_pid];
+
   //get nrOfLayers from DCI info
   uint8_t Nl = 0;
   for (int i = 0; i < 12; i++) { // max 12 ports
     if ((dlsch_config_pdu->dmrs_ports>>i)&0x01) Nl += 1;
   }
-  dlsch0_harq->Nl = Nl;
-  dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
-  downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch_config_pdu->rv, dlsch0->rnti_type);
+  dlsch0->Nl = Nl;
+  downlink_harq_process(dlsch0_harq, current_harq_pid, dlsch_config_pdu->ndi, dlsch_config_pdu->rv, dlsch0->rnti_type);
   if (dlsch0_harq->status != ACTIVE) {
     // dlsch0_harq->status not ACTIVE due to false retransmission
     // Reset the following flag to skip PDSCH procedures in that case and retrasmit harq status
-    dlsch0->active = 0;
-    update_harq_status(module_id,dlsch0->current_harq_pid,dlsch0_harq->ack);
+    dlsch0->active = false;
+    update_harq_status(module_id, current_harq_pid, dlsch0_harq->ack);
   }
-  /* PTRS */
-  dlsch0_harq->PTRSFreqDensity = dlsch_config_pdu->PTRSFreqDensity;
-  dlsch0_harq->PTRSTimeDensity = dlsch_config_pdu->PTRSTimeDensity;
-  dlsch0_harq->PTRSPortIndex = dlsch_config_pdu->PTRSPortIndex;
-  dlsch0_harq->nEpreRatioOfPDSCHToPTRS = dlsch_config_pdu->nEpreRatioOfPDSCHToPTRS;
-  dlsch0_harq->PTRSReOffset = dlsch_config_pdu->PTRSReOffset;
-  dlsch0_harq->pduBitmap = dlsch_config_pdu->pduBitmap;
-  LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs);
 }
 
 
@@ -357,7 +328,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
     int slot = scheduled_response->slot;
 
     // Note: we have to handle the thread IDs for this. To be revisited completely.
-    NR_UE_DLSCH_t *dlsch0 = NULL;
+    NR_UE_DLSCH_t *dlsch0 = &((nr_phy_data_t *)scheduled_response->phy_data)->dlsch[0];
     NR_UE_ULSCH_t *ulsch = PHY_vars_UE_g[module_id][cc_id]->ulsch[0];
     NR_UE_PUCCH *pucch_vars = &((nr_phy_data_t *)scheduled_response->phy_data)->pucch_vars;
     NR_UE_CSI_IM *csiim_vars = PHY_vars_UE_g[module_id][cc_id]->csiim_vars[0];
@@ -380,7 +351,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
         switch(dl_config->dl_config_list[i].pdu_type) {
           case FAPI_NR_DL_CONFIG_TYPE_DCI:
             if (NULL == phy_pdcch_config) {
-              phy_pdcch_config = (NR_UE_PDCCH_CONFIG *)scheduled_response->phy_data;
+              phy_pdcch_config = &((nr_phy_data_t *)scheduled_response->phy_data)->phy_pdcch_config;
               phy_pdcch_config->nb_search_space = 0;
             }
             pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
@@ -402,24 +373,23 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
             break;
           case FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH:
             dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
-            dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0];
             dlsch0->rnti_type = _RA_RNTI_;
-            dlsch0->harq_processes[dlsch_config_pdu->harq_process_nbr]->status = ACTIVE;
-            configure_dlsch(dlsch0, dlsch_config_pdu, module_id,
+            dlsch0->dlsch_config = *dlsch_config_pdu;
+            configure_dlsch(dlsch0, PHY_vars_UE_g[module_id][cc_id]->dl_harq_processes[0], dlsch_config_pdu, module_id,
                             dl_config->dl_config_list[i].dlsch_config_pdu.rnti);
             break;
           case FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH:
             dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
-            dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0];
             dlsch0->rnti_type = _SI_RNTI_;
-            dlsch0->harq_processes[dlsch_config_pdu->harq_process_nbr]->status = ACTIVE;
-            configure_dlsch(dlsch0, dlsch_config_pdu, module_id,
+            dlsch0->dlsch_config = *dlsch_config_pdu;
+            configure_dlsch(dlsch0, PHY_vars_UE_g[module_id][cc_id]->dl_harq_processes[0], dlsch_config_pdu, module_id,
                             dl_config->dl_config_list[i].dlsch_config_pdu.rnti);
             break;
           case FAPI_NR_DL_CONFIG_TYPE_DLSCH:
             dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
-            dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[0][0];
-            configure_dlsch(dlsch0, dlsch_config_pdu, module_id,
+            dlsch0->rnti_type = _C_RNTI_;
+            dlsch0->dlsch_config = *dlsch_config_pdu;
+            configure_dlsch(dlsch0, PHY_vars_UE_g[module_id][cc_id]->dl_harq_processes[0], dlsch_config_pdu, module_id,
                             dl_config->dl_config_list[i].dlsch_config_pdu.rnti);
             break;
         }
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 697638f6cf0..fb4a737da12 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -130,39 +130,34 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
     LOG_E(PHY, "In %s: multiple number of DL PDUs not supported yet...\n", __FUNCTION__);
   }
 
-  if (pdu_type !=  FAPI_NR_RX_PDU_TYPE_SSB)
+  NR_DL_UE_HARQ_t *dl_harq0 = NULL;
+
+  if ((pdu_type !=  FAPI_NR_RX_PDU_TYPE_SSB) && dlsch0) {
+    dl_harq0 = &ue->dl_harq_processes[0][dlsch0->dlsch_config.harq_process_nbr];
     trace_NRpdu(DIRECTION_DOWNLINK,
-		dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
-		dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8,
+		dl_harq0->b,
+		dlsch0->dlsch_config.TBS / 8,
 		WS_C_RNTI,
 		dlsch0->rnti,
 		proc->frame_rx,
 		proc->nr_slot_rx,
 		0,0);
+  }
   switch (pdu_type){
     case FAPI_NR_RX_PDU_TYPE_SIB:
-      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->current_harq_pid;
-      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dlsch0->harq_processes[dlsch0->current_harq_pid]->ack;
-      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[dlsch0->current_harq_pid]->b;
-      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8;
-    break;
+    case FAPI_NR_RX_PDU_TYPE_RAR:
     case FAPI_NR_RX_PDU_TYPE_DLSCH:
       if(dlsch0) {
-        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->current_harq_pid;
-        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dlsch0->harq_processes[dlsch0->current_harq_pid]->ack;
-        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[dlsch0->current_harq_pid]->b;
-        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8;
+        dl_harq0 = &ue->dl_harq_processes[0][dlsch0->dlsch_config.harq_process_nbr];
+        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->dlsch_config.harq_process_nbr;
+        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dl_harq0->ack;
+        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dl_harq0->b;
+        rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->dlsch_config.TBS / 8;
       }
       if(dlsch1) {
         AssertFatal(1==0,"Second codeword currently not supported\n");
       }
       break;
-    case FAPI_NR_RX_PDU_TYPE_RAR:
-      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->current_harq_pid;
-      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dlsch0->harq_processes[dlsch0->current_harq_pid]->ack;
-      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[dlsch0->current_harq_pid]->b;
-      rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8;
-    break;
     case FAPI_NR_RX_PDU_TYPE_SSB:
       rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.pdu=malloc(sizeof(((fapiPbch_t*)typeSpecific)->decoded_output));
       memcpy(rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.pdu,
@@ -312,7 +307,8 @@ void nr_ue_measurement_procedures(uint16_t l,
                                   PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
                                   uint8_t gNB_id,
-                                  uint16_t slot){
+                                  uint16_t slot,
+                                  NR_UE_DLSCH_t *dlsch){
 
   NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   int frame_rx   = proc->frame_rx;
@@ -327,7 +323,7 @@ void nr_ue_measurement_procedures(uint16_t l,
       nr_slot_rx,
       ue->common_vars.rxdata);
 
-    nr_ue_measurements(ue, proc, nr_slot_rx);
+    nr_ue_measurements(ue, proc, nr_slot_rx, dlsch);
 
 #if T_TRACER
     if(slot == 0)
@@ -365,7 +361,7 @@ static void nr_ue_pbch_procedures(uint8_t gNB_id,
                                   UE_nr_rxtx_proc_t *proc,
                                   int estimateSz,
                                   struct complex16 dl_ch_estimates[][estimateSz],
-                                  NR_UE_PDCCH_CONFIG *phy_pdcch_config) {
+                                  nr_phy_data_t *phy_data) {
 
   int ret = 0;
   DevAssert(ue);
@@ -384,7 +380,7 @@ static void nr_ue_pbch_procedures(uint8_t gNB_id,
                    gNB_id,
                    (ue->frame_parms.ssb_index)&7,
                    SISO,
-                   phy_pdcch_config,
+                   phy_data,
                    &result);
 
   if (ret==0) {
@@ -493,7 +489,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
                            UE_nr_rxtx_proc_t *proc,
                            int32_t pdcch_est_size,
                            int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
-                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+                           nr_phy_data_t *phy_data,
                            int n_ss)
 {
   int frame_rx = proc->frame_rx;
@@ -501,6 +497,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
   unsigned int dci_cnt=0;
   fapi_nr_dci_indication_t *dci_ind = calloc(1, sizeof(*dci_ind));
   nr_downlink_indication_t dl_indication;
+  NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
 
   fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[n_ss];
 
@@ -522,7 +519,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
 	 n_ss);
 #endif
 
-  dci_cnt = nr_dci_decoding_procedure(ue, proc, pdcch_e_rx, dci_ind, rel15, phy_pdcch_config);
+  dci_cnt = nr_dci_decoding_procedure(ue, proc, pdcch_e_rx, dci_ind, rel15);
 
 #ifdef NR_PDCCH_SCHED_DEBUG
   LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt);
@@ -543,7 +540,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
   dci_ind->number_of_dcis = dci_cnt;
 
   // fill dl_indication message
-  nr_fill_dl_indication(&dl_indication, dci_ind, NULL, proc, ue, gNB_id, phy_pdcch_config);
+  nr_fill_dl_indication(&dl_indication, dci_ind, NULL, proc, ue, gNB_id, phy_data);
   //  send to mac
   ue->if_inst->dl_indication(&dl_indication, NULL);
 
@@ -555,47 +552,51 @@ 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 gNB_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, NR_UE_DLSCH_t *dlsch) {
 
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
   int m;
-  int i_mod,gNB_id_i,dual_stream_UE;
+  int gNB_id_i;
   int first_symbol_flag=0;
 
-  if (!dlsch0)
-    return 0;
-  if (dlsch0->active == 0)
+  if (!dlsch[0].active)
     return 0;
 
-  if (!dlsch1)  {
-    int harq_pid = dlsch0->current_harq_pid;
-    NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
-    uint16_t BWPStart       = dlsch0_harq->BWPStart;
-    uint16_t pdsch_start_rb = dlsch0_harq->start_rb;
-    uint16_t pdsch_nb_rb    = dlsch0_harq->nb_rb;
-    uint16_t s0             = dlsch0_harq->start_symbol;
-    uint16_t s1             = dlsch0_harq->nb_symbols;
+  NR_UE_DLSCH_t *dlsch1 = NULL;
+
+  if (NR_MAX_NB_LAYERS > 4)
+    dlsch1 = &dlsch[1];
+
+  if (!dlsch1) {
+    NR_UE_DLSCH_t *dlsch0 = &dlsch[0];
+    int harq_pid = dlsch0->dlsch_config.harq_process_nbr;
+    NR_DL_UE_HARQ_t *dlsch0_harq = ue->dl_harq_processes[harq_pid];
+    uint16_t BWPStart       = dlsch0->dlsch_config.BWPStart;
+    uint16_t pdsch_start_rb = dlsch0->dlsch_config.start_rb;
+    uint16_t pdsch_nb_rb    = dlsch0->dlsch_config.number_rbs;
+    uint16_t s0             = dlsch0->dlsch_config.start_symbol;
+    uint16_t s1             = dlsch0->dlsch_config.number_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, Nl %d\n",
-          ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0_harq->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0_harq->dlDmrsSymbPos, dlsch0_harq->Nl);
+    LOG_D(PHY,"[UE %d] nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x, Nl %d\n",
+          ue->Mod_id,nr_slot_rx,harq_pid,dlsch0_harq->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->dlsch_config.dlDmrsSymbPos, dlsch0->Nl);
 
     for (m = s0; m < (s0 +s1); m++) {
-      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
+      if (dlsch0->dlsch_config.dlDmrsSymbPos & (1 << m)) {
+        for (uint8_t aatx=0; aatx<dlsch0->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers
           LOG_D(PHY,"PDSCH Channel estimation gNB id %d, PDSCH antenna port %d, slot %d, symbol %d\n",0,aatx,nr_slot_rx,m);
           nr_pdsch_channel_estimation(ue,
                                       proc,
                                       gNB_id,
                                       is_SI,
                                       nr_slot_rx,
-                                      get_dmrs_port(aatx,dlsch0_harq->dmrs_ports),
+                                      get_dmrs_port(aatx,dlsch0->dlsch_config.dmrs_ports),
                                       m,
-                                      dlsch0_harq->nscid,
-                                      dlsch0_harq->dlDmrsScramblingId,
+                                      dlsch0->dlsch_config.nscid,
+                                      dlsch0->dlsch_config.dlDmrsScramblingId,
                                       BWPStart,
-                                      dlsch0_harq->dmrsConfigType,
+                                      dlsch0->dlsch_config.dmrsConfigType,
                                       ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12,
                                       pdsch_nb_rb);
 #if 0
@@ -615,30 +616,28 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
     if (ue->chest_time == 1) { // averaging time domain channel estimates
       nr_chest_time_domain_avg(&ue->frame_parms,
                                ue->pdsch_vars[gNB_id]->dl_ch_estimates,
-                               dlsch0_harq->nb_symbols,
-                               dlsch0_harq->start_symbol,
-                               dlsch0_harq->dlDmrsSymbPos,
+                               dlsch0->dlsch_config.number_symbols,
+                               dlsch0->dlsch_config.start_symbol,
+                               dlsch0->dlsch_config.dlDmrsSymbPos,
                                pdsch_nb_rb);
     }
 
     uint16_t first_symbol_with_data = s0;
     uint32_t dmrs_data_re;
 
-    if (dlsch0_harq->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)
-      dmrs_data_re = 12 - 6 * dlsch0_harq->n_dmrs_cdm_groups;
+    if (dlsch0->dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1)
+      dmrs_data_re = 12 - 6 * dlsch0->dlsch_config.n_dmrs_cdm_groups;
     else
-      dmrs_data_re = 12 - 4 * dlsch0_harq->n_dmrs_cdm_groups;
+      dmrs_data_re = 12 - 4 * dlsch0->dlsch_config.n_dmrs_cdm_groups;
 
-    while ((dmrs_data_re == 0) && (dlsch0_harq->dlDmrsSymbPos & (1 << first_symbol_with_data))) {
+    while ((dmrs_data_re == 0) && (dlsch0->dlsch_config.dlDmrsSymbPos & (1 << first_symbol_with_data))) {
       first_symbol_with_data++;
     }
 
     start_meas(&ue->rx_pdsch_stats);
     for (m = s0; m < (s1 + s0); m++) {
  
-      dual_stream_UE = 0;
       gNB_id_i = gNB_id+1;
-      i_mod = 0;
       if (m==first_symbol_with_data)
         first_symbol_flag = 1;
       else
@@ -650,21 +649,17 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
       start_meas(&ue->dlsch_llr_stats_parallelization[slot]);
       // process DLSCH received symbols in the slot
       // symbol by symbol processing (if data/DMRS are multiplexed is checked inside the function)
-      if (pdsch == PDSCH || pdsch == SI_PDSCH || pdsch == RA_PDSCH) {
-        if (nr_rx_pdsch(ue,
-                        proc,
-                        pdsch,
-                        gNB_id,
-                        gNB_id_i,
-                        frame_rx,
-                        nr_slot_rx,
-                        m,
-                        first_symbol_flag,
-                        dual_stream_UE,
-                        i_mod,
-                        harq_pid) < 0)
-          return -1;
-      } else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n");
+      if (nr_rx_pdsch(ue,
+                      proc,
+                      dlsch,
+                      gNB_id,
+                      gNB_id_i,
+                      frame_rx,
+                      nr_slot_rx,
+                      m,
+                      first_symbol_flag,
+                      harq_pid) < 0)
+        return -1;
 
       stop_meas(&ue->dlsch_llr_stats_parallelization[slot]);
       if (cpumeas(CPUMEAS_GETSTATE))
@@ -681,357 +676,304 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
 bool nr_ue_dlsch_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 *dlsch_errors) {
+                            NR_UE_DLSCH_t *dlsch1) {
 
   if (dlsch0==NULL)
     AssertFatal(0,"dlsch0 should be defined at this level \n");
   bool dec = false;
-  int harq_pid = dlsch0->current_harq_pid;
+  int harq_pid = dlsch0->dlsch_config.harq_process_nbr;
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
   uint32_t ret = UINT32_MAX, ret1 = UINT32_MAX;
   NR_UE_PDSCH *pdsch_vars;
-  uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos);
+  NR_DL_UE_HARQ_t *dl_harq0 = &ue->dl_harq_processes[0][harq_pid];
+  NR_DL_UE_HARQ_t *dl_harq1 = &ue->dl_harq_processes[NR_MAX_NB_LAYERS>4 ? 1:0][harq_pid];
+  uint16_t dmrs_len = get_num_dmrs(dlsch0->dlsch_config.dlDmrsSymbPos);
   nr_downlink_indication_t dl_indication;
   fapi_nr_rx_indication_t *rx_ind = calloc(1, sizeof(*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[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;
-  uint16_t start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
-  uint8_t dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
+  uint8_t is_cw0_active = dl_harq0->status;
+  uint16_t nb_symb_sch = dlsch0->dlsch_config.number_symbols;
+  uint16_t start_symbol = dlsch0->dlsch_config.start_symbol;
+  uint8_t dmrs_type = dlsch0->dlsch_config.dmrsConfigType;
 
   uint8_t nb_re_dmrs;
   if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
-    nb_re_dmrs = 6*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
+    nb_re_dmrs = 6*dlsch0->dlsch_config.n_dmrs_cdm_groups;
   }
   else {
-    nb_re_dmrs = 4*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
+    nb_re_dmrs = 4*dlsch0->dlsch_config.n_dmrs_cdm_groups;
   }
 
   uint8_t is_cw1_active = 0;
   if(dlsch1)
-    is_cw1_active = dlsch1->harq_processes[harq_pid]->status;
+    is_cw1_active = dl_harq1->status;
 
   LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw0_active);
   LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw1_active);
 
-  if(is_cw0_active && is_cw1_active)
-    {
-      dlsch0->Kmimo = 2;
-      dlsch1->Kmimo = 2;
-    }
-  else
-    {
-      dlsch0->Kmimo = 1;
-    }
-  if (1) {
-    switch (pdsch) {
-    case SI_PDSCH:
-    case RA_PDSCH:
-    case P_PDSCH:
-    case PDSCH:
-      pdsch_vars = ue->pdsch_vars[gNB_id];
+  pdsch_vars = ue->pdsch_vars[gNB_id];
+
+  // exit dlsch procedures as there are no active dlsch
+  if (is_cw0_active != ACTIVE && is_cw1_active != ACTIVE)
+    return false;
+
+  // start ldpc decode for CW 0
+  dl_harq0->G = nr_get_G(dlsch0->dlsch_config.number_rbs,
+                         nb_symb_sch,
+                         nb_re_dmrs,
+                         dmrs_len,
+                         dlsch0->dlsch_config.qamModOrder,
+                         dlsch0->Nl);
+
+  start_meas(&ue->dlsch_unscrambling_stats);
+  nr_dlsch_unscrambling(pdsch_vars->llr[0],
+                        dl_harq0->G,
+                        0,
+                        ue->frame_parms.Nid_cell,
+                        dlsch0->rnti);
+    
+
+  stop_meas(&ue->dlsch_unscrambling_stats);
+
+  start_meas(&ue->dlsch_decoding_stats);
+
+  ret = nr_dlsch_decoding(ue,
+                          proc,
+                          gNB_id,
+                          pdsch_vars->llr[0],
+                          &ue->frame_parms,
+                          dlsch0,
+                          dl_harq0,
+                          frame_rx,
+                          nb_symb_sch,
+                          nr_slot_rx,
+                          harq_pid);
+
+  LOG_T(PHY,"dlsch decoding, ret = %d\n", ret);
+
+
+  if(ret<ue->max_ldpc_iterations+1)
+    dec = true;
+
+  int ind_type = -1;
+  switch(dlsch0->rnti_type) {
+    case _RA_RNTI_:
+      ind_type = FAPI_NR_RX_PDU_TYPE_RAR;
+      break;
+
+    case _SI_RNTI_:
+      ind_type = FAPI_NR_RX_PDU_TYPE_SIB;
       break;
-    case PMCH:
-    case PDSCH1:
-      LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch);
-      pdsch_vars = NULL;
-      return false;
+
+    case _C_RNTI_:
+      ind_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
       break;
+
     default:
-      pdsch_vars = NULL;
-      return false;
+      AssertFatal(true, "Invalid DLSCH type %d\n", dlsch0->rnti_type);
       break;
+  }
 
-    }
-    if (frame_rx < *dlsch_errors)
-      *dlsch_errors=0;
+  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
+  nr_fill_rx_indication(rx_ind, ind_type, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
 
-    // exit dlsch procedures as there are no active dlsch
-    if (is_cw0_active != ACTIVE && is_cw1_active != ACTIVE)
-      return false;
+  LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch0->dlsch_config.TBS, dlsch0->dlsch_config.TBS / 8);
 
-    // start ldpc decode for CW 0
-    dlsch0->harq_processes[harq_pid]->G = nr_get_G(dlsch0->harq_processes[harq_pid]->nb_rb,
-                                                   nb_symb_sch,
-                                                   nb_re_dmrs,
-                                                   dmrs_len,
-                                                   dlsch0->harq_processes[harq_pid]->Qm,
-                                                   dlsch0->harq_processes[harq_pid]->Nl);
+  stop_meas(&ue->dlsch_decoding_stats);
+  if (cpumeas(CPUMEAS_GETSTATE))  {
+    LOG_D(PHY, " --> Unscrambling for CW0 %5.3f\n",
+          (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+    LOG_D(PHY, "AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n",
+          frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0));
+  }
 
+  if(is_cw1_active) {
+    // start ldpc decode for CW 1
+    dl_harq1->G = nr_get_G(dlsch1->dlsch_config.number_rbs,
+                           nb_symb_sch,
+                           nb_re_dmrs,
+                           dmrs_len,
+                           dlsch1->dlsch_config.qamModOrder,
+                           dlsch1->Nl);
     start_meas(&ue->dlsch_unscrambling_stats);
-    nr_dlsch_unscrambling(pdsch_vars->llr[0],
-                          dlsch0->harq_processes[harq_pid]->G,
+    nr_dlsch_unscrambling(pdsch_vars->llr[1],
+                          dl_harq1->G,
                           0,
                           ue->frame_parms.Nid_cell,
-                          dlsch0->rnti);
-      
-
+                          dlsch1->rnti);
     stop_meas(&ue->dlsch_unscrambling_stats);
 
-
-#if 0
-      LOG_I(PHY," ------ start ldpc decoder for AbsSubframe %d.%d / %d  ------  \n", frame_rx, nr_slot_rx, harq_pid);
-      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb);
-      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even);
-      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm);
-      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[gNB_id]->num_pdcch_symbols);
-#endif
-
-
-   start_meas(&ue->dlsch_decoding_stats);
-
-    ret = nr_dlsch_decoding(ue,
-                            proc,
-                            gNB_id,
-                            pdsch_vars->llr[0],
-                            &ue->frame_parms,
-                            dlsch0,
-                            dlsch0->harq_processes[harq_pid],
-                            frame_rx,
-                            nb_symb_sch,
-                            nr_slot_rx,
-                            harq_pid,
-                            pdsch==PDSCH);
-
-    LOG_T(PHY,"dlsch decoding, ret = %d\n", ret);
-
-
-    if(ret<dlsch0->max_ldpc_iterations+1)
-      dec = true;
-
-    switch (pdsch) {
-      case RA_PDSCH:
-        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
-        nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
-        ue->UE_mode[gNB_id] = RA_RESPONSE;
-        break;
-      case PDSCH:
-        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
-        nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
-        break;
-      case SI_PDSCH:
-        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
-        nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
-        break;
-      default:
-        break;
-    }
-
-    LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch0->harq_processes[harq_pid]->TBS, dlsch0->harq_processes[harq_pid]->TBS / 8);
+    start_meas(&ue->dlsch_decoding_stats);
+
+    ret1 = nr_dlsch_decoding(ue,
+                             proc,
+                             gNB_id,
+                             pdsch_vars->llr[1],
+                             &ue->frame_parms,
+                             dlsch1,
+                             dl_harq1,
+                             frame_rx,
+                             nb_symb_sch,
+                             nr_slot_rx,
+                             harq_pid);
+    LOG_T(PHY,"CW dlsch decoding, ret1 = %d\n", ret1);
 
     stop_meas(&ue->dlsch_decoding_stats);
-    if (cpumeas(CPUMEAS_GETSTATE))  {
-      LOG_D(PHY, " --> Unscrambling for CW0 %5.3f\n",
+    if (cpumeas(CPUMEAS_GETSTATE)) {
+      LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n",
             (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
-      LOG_D(PHY, "AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n",
+      LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
             frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0));
-    }
-
-    if(is_cw1_active) {
-      // start ldpc decode for CW 1
-      dlsch1->harq_processes[harq_pid]->G = nr_get_G(dlsch1->harq_processes[harq_pid]->nb_rb,
-                                                     nb_symb_sch,
-                                                     nb_re_dmrs,
-                                                     dmrs_len,
-                                                     dlsch1->harq_processes[harq_pid]->Qm,
-                                                     dlsch1->harq_processes[harq_pid]->Nl);
-      start_meas(&ue->dlsch_unscrambling_stats);
-      nr_dlsch_unscrambling(pdsch_vars->llr[1],
-                            dlsch1->harq_processes[harq_pid]->G,
-                            0,
-                            ue->frame_parms.Nid_cell,
-                            dlsch1->rnti);
-      stop_meas(&ue->dlsch_unscrambling_stats);
-
-#if 0
-          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb);
-          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even);
-          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm);
-          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[gNB_id]->num_pdcch_symbols);
-#endif
-
-      start_meas(&ue->dlsch_decoding_stats);
-
-
-      ret1 = nr_dlsch_decoding(ue,
-                               proc,
-                               gNB_id,
-                               pdsch_vars->llr[1],
-                               &ue->frame_parms,
-                               dlsch1,
-                               dlsch1->harq_processes[harq_pid],
-                               frame_rx,
-                               nb_symb_sch,
-                               nr_slot_rx,
-                               harq_pid,
-                               pdsch==PDSCH);//proc->decoder_switch
-      LOG_T(PHY,"CW dlsch decoding, ret1 = %d\n", ret1);
-
-      stop_meas(&ue->dlsch_decoding_stats);
-      if (cpumeas(CPUMEAS_GETSTATE)) {
-        LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n",
-              (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
-        LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
-              frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0));
-        }
-    LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS);
-    }
-    //  send to mac
-    if (ue->if_inst && ue->if_inst->dl_indication) {
-      ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
-    }
-
-    if (ue->mac_enabled == 1) { // TODO: move this from PHY to MAC layer!
-
-      /* Time Alignment procedure
-      // - UE processing capability 1
-      // - Setting the TA update to be applied after the reception of the TA command
-      // - Timing adjustment computed according to TS 38.213 section 4.2
-      // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are
-      //   computed according to sections 5.3 and 6.4 of TS 38.214 */
-      const int numerology = ue->frame_parms.numerology_index;
-      const int ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
-      const int nb_prefix_samples = ue->frame_parms.nb_prefix_samples;
-      const int samples_per_subframe = ue->frame_parms.samples_per_subframe;
-      const int slots_per_frame = ue->frame_parms.slots_per_frame;
-      const int slots_per_subframe = ue->frame_parms.slots_per_subframe;
-
-      const double tc_factor = 1.0 / samples_per_subframe;
-      const uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size);
-
-      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_BWP_Id_t dl_bwp = mac->DL_BWP_Id;
-      NR_BWP_Id_t ul_bwp = mac->UL_BWP_Id;
-
-      NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
-      if(ul_bwp){
-        if (mac->ULbwp[ul_bwp-1] &&
-            mac->ULbwp[ul_bwp-1]->bwp_Dedicated &&
-            mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config &&
-            mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config->choice.setup &&
-            mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
-          pusch_TimeDomainAllocationList = mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
-        }
-        else if (mac->ULbwp[ul_bwp-1] &&
-                 mac->ULbwp[ul_bwp-1]->bwp_Common &&
-                 mac->ULbwp[ul_bwp-1]->bwp_Common->pusch_ConfigCommon &&
-                 mac->ULbwp[ul_bwp-1]->bwp_Common->pusch_ConfigCommon->choice.setup &&
-                 mac->ULbwp[ul_bwp-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
-          pusch_TimeDomainAllocationList = mac->ULbwp[ul_bwp-1]->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 = NULL;
-      NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL;
-      if(dl_bwp){
-        pdsch_Config = (mac->DLbwp[dl_bwp-1] && mac->DLbwp[dl_bwp-1]->bwp_Dedicated->pdsch_Config->choice.setup) ? mac->DLbwp[dl_bwp-1]->bwp_Dedicated->pdsch_Config->choice.setup : NULL;
-        if (mac->DLbwp[dl_bwp-1] && mac->DLbwp[dl_bwp-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
-          pdsch_TimeDomainAllocationList = pdsch_Config->pdsch_TimeDomainAllocationList->choice.setup;
-        else if (mac->DLbwp[dl_bwp-1] && mac->DLbwp[dl_bwp-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
-          pdsch_TimeDomainAllocationList = mac->DLbwp[dl_bwp-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+  LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch0->dlsch_config.TBS);
+  }
+  //  send to mac
+  if (ue->if_inst && ue->if_inst->dl_indication) {
+    ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
+  }
+
+  if (ue->mac_enabled == 1) { // TODO: move this from PHY to MAC layer!
+
+    /* Time Alignment procedure
+    // - UE processing capability 1
+    // - Setting the TA update to be applied after the reception of the TA command
+    // - Timing adjustment computed according to TS 38.213 section 4.2
+    // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are
+    //   computed according to sections 5.3 and 6.4 of TS 38.214 */
+    const int numerology = ue->frame_parms.numerology_index;
+    const int ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
+    const int nb_prefix_samples = ue->frame_parms.nb_prefix_samples;
+    const int samples_per_subframe = ue->frame_parms.samples_per_subframe;
+    const int slots_per_frame = ue->frame_parms.slots_per_frame;
+    const int slots_per_subframe = ue->frame_parms.slots_per_subframe;
+
+    const double tc_factor = 1.0 / samples_per_subframe;
+    const uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size);
+
+    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_BWP_Id_t dl_bwp = mac->DL_BWP_Id;
+    NR_BWP_Id_t ul_bwp = mac->UL_BWP_Id;
+
+    NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
+    if(ul_bwp){
+      if (mac->ULbwp[ul_bwp-1] &&
+          mac->ULbwp[ul_bwp-1]->bwp_Dedicated &&
+          mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config &&
+          mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config->choice.setup &&
+          mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
+        pusch_TimeDomainAllocationList = mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
       }
-      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;
+      else if (mac->ULbwp[ul_bwp-1] &&
+               mac->ULbwp[ul_bwp-1]->bwp_Common &&
+               mac->ULbwp[ul_bwp-1]->bwp_Common->pusch_ConfigCommon &&
+               mac->ULbwp[ul_bwp-1]->bwp_Common->pusch_ConfigCommon->choice.setup &&
+               mac->ULbwp[ul_bwp-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+        pusch_TimeDomainAllocationList = mac->ULbwp[ul_bwp-1]->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 = NULL;
+    NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL;
+    if(dl_bwp){
+      pdsch_Config = (mac->DLbwp[dl_bwp-1] && mac->DLbwp[dl_bwp-1]->bwp_Dedicated->pdsch_Config->choice.setup) ? mac->DLbwp[dl_bwp-1]->bwp_Dedicated->pdsch_Config->choice.setup : NULL;
+      if (mac->DLbwp[dl_bwp-1] && mac->DLbwp[dl_bwp-1]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList)
+        pdsch_TimeDomainAllocationList = pdsch_Config->pdsch_TimeDomainAllocationList->choice.setup;
+      else if (mac->DLbwp[dl_bwp-1] && mac->DLbwp[dl_bwp-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
+        pdsch_TimeDomainAllocationList = mac->DLbwp[dl_bwp-1]->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;
 
-      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;
+    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 decoding time N_1 for processing capability 1 */
-      int N_1;
+    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;
 
-      if (add_pos_dl == pdsch_dmrs_pos0)
-        N_1 = pdsch_N_1_capability_1[numerology][1];
-      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];
+    /* PDSCH decoding time N_1 for processing capability 1 */
+    int N_1;
 
-      /* PUSCH preapration time N_2 for processing capability 1 */
-      const int N_2 = pusch_N_2_timing_capability_1[numerology][1];
+    if (add_pos_dl == pdsch_dmrs_pos0)
+      N_1 = pdsch_N_1_capability_1[numerology][1];
+    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];
 
-      /* 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;
-      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
-          d_1_1 = 0;
-      else // mapping type B
-        switch (nb_symb_sch){
-          case 7: d_1_1 = 0; break;
-          case 4: d_1_1 = 3; break;
-          case 2: d_1_1 = 3 + d; break;
-          default: break;
-        }
+    /* PUSCH preapration time N_2 for processing capability 1 */
+    const int N_2 = pusch_N_2_timing_capability_1[numerology][1];
 
-      /* d_2_1 */
-      int d_2_1;
-      if (mapping_type_ul == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB && start_symbol != 0)
-        d_2_1 = 0;
+    /* 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;
+    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
-        d_2_1 = 1;
-
-      /* d_2_2 */
-      const double d_2_2 = pusch_d_2_2_timing_capability_1[numerology][1];
-
-      /* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time
-      // N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */
-      double N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor;
-      double N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor;
-      if (N_t_2 < d_2_2) N_t_2 = d_2_2;
-
-      /* Time alignment procedure */
-      // N_t_1 + N_t_2 + N_TA_max must be in msec
-      const double t_subframe = 1.0; // subframe duration of 1 msec
-      const int ul_tx_timing_adjustment = 1 + (int)ceil(slots_per_subframe*(N_t_1 + N_t_2 + N_TA_max + 0.5)/t_subframe);
-
-      if (ul_time_alignment->apply_ta == 1){
-        ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame;
-        if (nr_slot_rx + ul_tx_timing_adjustment > slots_per_frame){
-          ul_time_alignment->ta_frame = (frame_rx + 1) % 1024;
-        } else {
-          ul_time_alignment->ta_frame = frame_rx;
-        }
-        // reset TA flag
-        ul_time_alignment->apply_ta = 0;
-        LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n",
-             frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot);
+        d_1_1 = 0;
+    else // mapping type B
+      switch (nb_symb_sch){
+        case 7: d_1_1 = 0; break;
+        case 4: d_1_1 = 3; break;
+        case 2: d_1_1 = 3 + d; break;
+        default: break;
       }
+
+    /* d_2_1 */
+    int d_2_1;
+    if (mapping_type_ul == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB && start_symbol != 0)
+      d_2_1 = 0;
+    else
+      d_2_1 = 1;
+
+    /* d_2_2 */
+    const double d_2_2 = pusch_d_2_2_timing_capability_1[numerology][1];
+
+    /* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time
+    // N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */
+    double N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor;
+    double N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor;
+    if (N_t_2 < d_2_2) N_t_2 = d_2_2;
+
+    /* Time alignment procedure */
+    // N_t_1 + N_t_2 + N_TA_max must be in msec
+    const double t_subframe = 1.0; // subframe duration of 1 msec
+    const int ul_tx_timing_adjustment = 1 + (int)ceil(slots_per_subframe*(N_t_1 + N_t_2 + N_TA_max + 0.5)/t_subframe);
+
+    if (ul_time_alignment->apply_ta == 1){
+      ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame;
+      if (nr_slot_rx + ul_tx_timing_adjustment > slots_per_frame){
+        ul_time_alignment->ta_frame = (frame_rx + 1) % 1024;
+      } else {
+        ul_time_alignment->ta_frame = frame_rx;
+      }
+      // reset TA flag
+      ul_time_alignment->apply_ta = 0;
+      LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n",
+           frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot);
     }
   }
   return dec;
@@ -1041,13 +983,15 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
-                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+                           nr_phy_data_t *phy_data,
                            notifiedFIFO_t *txFifo) {
 
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
   fapi_nr_config_request_t *cfg = &ue->nrUE_config;
   NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
+  NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
+  nr_ue_dlsch_init(phy_data->dlsch, NR_MAX_NB_LAYERS>4 ? 2:1, ue->max_ldpc_iterations);
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
   start_meas(&ue->phy_proc_rx);
@@ -1101,7 +1045,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
           if(ssb_index == fp->ssb_index) {
 
             LOG_D(PHY," ------  Decode MIB: frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
-            nr_ue_pbch_procedures(gNB_id, ue, proc, estimateSz, dl_ch_estimates, phy_pdcch_config);
+            nr_ue_pbch_procedures(gNB_id, ue, proc, estimateSz, dl_ch_estimates, phy_data);
 
             if (ue->no_timing_correction==0) {
              LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
@@ -1202,29 +1146,20 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
       stop_meas(&ue->ofdm_demod_stats);
 
     }
-    dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_pdcch_config, n_ss);
+    dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss);
   }
+  phy_pdcch_config->nb_search_space = 0;
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
 
+  NR_UE_DLSCH_t *dlsch = &phy_data->dlsch[0];
   if (dci_cnt > 0) {
 
     LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt);
 
-    NR_UE_DLSCH_t *dlsch = NULL;
-    if (ue->dlsch[gNB_id][0]->active == 1){
-      dlsch = ue->dlsch[gNB_id][0];
-    } else if (ue->dlsch_SI[0]->active == 1){
-      dlsch = ue->dlsch_SI[0];
-    } else if (ue->dlsch_ra[0]->active == 1){
-      dlsch = ue->dlsch_ra[0];
-    }
-
-    if (dlsch) {
+    if (dlsch->active) {
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_IN);
-      uint8_t harq_pid = dlsch->current_harq_pid;
-      NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid];
-      uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
-      uint16_t start_symb_sch = dlsch0_harq->start_symbol;
+      uint16_t nb_symb_sch = dlsch[0].dlsch_config.number_symbols;
+      uint16_t start_symb_sch = dlsch[0].dlsch_config.start_symbol;
 
       LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
       //to update from pdsch config
@@ -1253,91 +1188,15 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   start_meas(&ue->generic_stat);
   // do procedures for C-RNTI
   int ret_pdsch = 0;
-  if (ue->dlsch[gNB_id][0]->active == 1) {
+  if (dlsch->active) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_IN);
     ret_pdsch = nr_ue_pdsch_procedures(ue,
                                        proc,
                                        gNB_id,
-                                       PDSCH,
-                                       ue->dlsch[gNB_id][0],
-                                       NULL);
+                                       dlsch);
 
-    nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx);
+    nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx, dlsch);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_OUT);
-  }
-
-  // do procedures for SI-RNTI
-  if ((ue->dlsch_SI[gNB_id]) && (ue->dlsch_SI[gNB_id]->active == 1)) {
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
-    nr_ue_pdsch_procedures(ue,
-                           proc,
-                           gNB_id,
-                           SI_PDSCH,
-                           ue->dlsch_SI[gNB_id],
-                           NULL);
-    
-    nr_ue_dlsch_procedures(ue,
-                           proc,
-                           gNB_id,
-                           SI_PDSCH,
-                           ue->dlsch_SI[gNB_id],
-                           NULL,
-                           &ue->dlsch_SI_errors[gNB_id]);
-
-    // deactivate dlsch once dlsch proc is done
-    ue->dlsch_SI[gNB_id]->active = 0;
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
-  }
-
-  // do procedures for P-RNTI
-  if ((ue->dlsch_p[gNB_id]) && (ue->dlsch_p[gNB_id]->active == 1)) {
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
-    nr_ue_pdsch_procedures(ue,
-                           proc,
-                           gNB_id,
-                           P_PDSCH,
-                           ue->dlsch_p[gNB_id],
-                           NULL);
-
-    nr_ue_dlsch_procedures(ue,
-                           proc,
-                           gNB_id,
-                           P_PDSCH,
-                           ue->dlsch_p[gNB_id],
-                           NULL,
-                           &ue->dlsch_p_errors[gNB_id]);
-
-    // deactivate dlsch once dlsch proc is done
-    ue->dlsch_p[gNB_id]->active = 0;
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
-  }
-
-  // do procedures for RA-RNTI
-  if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1) && (ue->UE_mode[gNB_id] != PUSCH)) {
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
-    nr_ue_pdsch_procedures(ue,
-                           proc,
-                           gNB_id,
-                           RA_PDSCH,
-                           ue->dlsch_ra[gNB_id],
-                           NULL);
-
-    nr_ue_dlsch_procedures(ue,
-                           proc,
-                           gNB_id,
-                           RA_PDSCH,
-                           ue->dlsch_ra[gNB_id],
-                           NULL,
-                           &ue->dlsch_ra_errors[gNB_id]);
-
-    // deactivate dlsch once dlsch proc is done
-    ue->dlsch_ra[gNB_id]->active = 0;
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
-  }
-  // do procedures for C-RNTI
-  if (ue->dlsch[gNB_id][0]->active == 1) {
 
     LOG_D(PHY, "DLSCH data reception at nr_slot_rx: %d\n", nr_slot_rx);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
@@ -1346,29 +1205,20 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
 
     NR_UE_DLSCH_t *dlsch1 = NULL;
     if (NR_MAX_NB_LAYERS>4)
-      dlsch1 = ue->dlsch[gNB_id][1];
+      dlsch1 = &phy_data->dlsch[1];
 
     if (ret_pdsch >= 0)
-      nr_ue_dlsch_procedures(ue,
-			   proc,
-			   gNB_id,
-			   PDSCH,
-			   ue->dlsch[gNB_id][0],
-			   dlsch1,
-			   &ue->dlsch_errors[gNB_id]);
-
-  stop_meas(&ue->dlsch_procedures_stat);
-  if (cpumeas(CPUMEAS_GETSTATE)) {
-    LOG_D(PHY, "[SFN %d] Slot1:       Pdsch Proc %5.2f\n",nr_slot_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0));
-    LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0));
-  }
+      nr_ue_dlsch_procedures(ue, proc, gNB_id, dlsch, dlsch1);
 
-  // deactivate dlsch once dlsch proc is done
-  ue->dlsch[gNB_id][0]->active = 0;
+    stop_meas(&ue->dlsch_procedures_stat);
+    if (cpumeas(CPUMEAS_GETSTATE)) {
+      LOG_D(PHY, "[SFN %d] Slot1:       Pdsch Proc %5.2f\n",nr_slot_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0));
+      LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0));
+    }
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
 
- }
+  }
 
   // do procedures for CSI-IM
   if ((ue->csiim_vars[gNB_id]) && (ue->csiim_vars[gNB_id]->active == 1)) {
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index 3b36b0d6e5a..706e64bfd12 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -106,8 +106,6 @@ int main(int argc, char **argv)
   int frame_length_complex_samples;
   //int frame_length_complex_samples_no_prefix;
   NR_DL_FRAME_PARMS *frame_parms;
-  uint8_t Kmimo = 0;
-  uint32_t Nsoft = 0;
   double sigma;
   unsigned char qbits = 8;
   int ret;
@@ -403,24 +401,19 @@ int main(int argc, char **argv)
 
 	//nr_init_frame_parms_ue(&UE->frame_parms);
 	//init_nr_ue_transport(UE, 0);
-        int num_codeword = NR_MAX_NB_LAYERS > 4? 2:1;
-  for (i = 0; i < num_codeword; i++) {
-    UE->dlsch[0][i] = new_nr_ue_dlsch(Kmimo, 8, Nsoft, 5, N_RB_DL);
-    if (!UE->dlsch[0][i]) {
-      printf("Can't get ue dlsch structures\n");
-      exit(-1);
-    }
-
-    UE->dlsch[0][i]->rnti = n_rnti;
-  }
+  NR_UE_DLSCH_t dlsch_ue[NR_MAX_NB_LAYERS > 4? 2:1] = {0};
+  int num_codeword = NR_MAX_NB_LAYERS > 4? 2:1;
+  nr_ue_dlsch_init(dlsch_ue, num_codeword, 5);
+  for (int i=0; i < num_codeword; i++)
+    dlsch_ue[0].rnti = n_rnti;
+  nr_init_harq_processes(UE->dl_harq_processes[0], 8, nb_rb);
 
 	unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
-        processingData_L1tx_t msgDataTx;
-        init_DLSCH_struct(gNB, &msgDataTx);
+  processingData_L1tx_t msgDataTx;
+  init_DLSCH_struct(gNB, &msgDataTx);
 	NR_gNB_DLSCH_t *dlsch = msgDataTx.dlsch[0][0];
 	nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
 	//time_stats_t *rm_stats, *te_stats, *i_stats;
-	uint8_t is_crnti = 0;
 	unsigned int TBS = 8424;
 	uint8_t nb_re_dmrs = 6;  // No data in dmrs symbol
 	uint16_t length_dmrs = 1;
@@ -432,7 +425,7 @@ int main(int argc, char **argv)
 	//printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe],
 	//    dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl);
 	unsigned char mod_order = nr_get_Qm_dl(Imcs, mcs_table);
-        uint16_t rate = nr_get_code_rate_dl(Imcs, mcs_table);
+  uint16_t rate = nr_get_code_rate_dl(Imcs, mcs_table);
 	unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
 	TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl);
 	printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
@@ -442,14 +435,14 @@ int main(int argc, char **argv)
 	rel15->qamModOrder[0] = mod_order;
 	rel15->nrOfLayers     = Nl;
 	rel15->TBSize[0]      = TBS>>3;
-        rel15->targetCodeRate[0] = rate;
-        rel15->NrOfCodewords = 1;
-        rel15->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
+  rel15->targetCodeRate[0] = rate;
+  rel15->NrOfCodewords = 1;
+  rel15->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
 	rel15->dlDmrsSymbPos = 4;
 	rel15->mcsIndex[0] = Imcs;
-        rel15->numDmrsCdmGrpsNoData = 1;
-        rel15->maintenance_parms_v3.tbSizeLbrmBytes = Tbslbrm;
-        rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS, rate);
+  rel15->numDmrsCdmGrpsNoData = 1;
+  rel15->maintenance_parms_v3.tbSizeLbrmBytes = Tbslbrm;
+  rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS, rate);
 	double modulated_input[16 * 68 * 384]; // [hna] 16 segments, 68*Zc
 	short channel_output_fixed[16 * 68 * 384];
 	//unsigned char *estimated_output;
@@ -457,21 +450,22 @@ int main(int argc, char **argv)
 	unsigned char test_input_bit[16 * 68 * 384];
 	//estimated_output = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
 	unsigned char estimated_output_bit[16 * 68 * 384];
-	NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[0][0];
-	NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid];
-	harq_process->mcs = Imcs;
-	harq_process->mcs_table = mcs_table;
-	harq_process->Nl = Nl;
-	harq_process->nb_rb = nb_rb;
-	harq_process->Qm = mod_order;
-	harq_process->rvidx = rvidx;
-	harq_process->R = rate;
-        harq_process->TBS = TBS;
-	harq_process->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
-	harq_process->dlDmrsSymbPos = 4;
-	harq_process->n_dmrs_cdm_groups = 1;
-        harq_process->tbslbrm = Tbslbrm;
-	printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch);
+	NR_UE_DLSCH_t *dlsch0_ue = &dlsch_ue[0];
+	NR_DL_UE_HARQ_t *harq_process = &UE->dl_harq_processes[0][harq_pid];
+  harq_process->first_rx = 1;
+	dlsch0_ue->dlsch_config.mcs = Imcs;
+	dlsch0_ue->dlsch_config.mcs_table = mcs_table;
+	dlsch0_ue->Nl = Nl;
+	dlsch0_ue->dlsch_config.number_rbs = nb_rb;
+	dlsch0_ue->dlsch_config.qamModOrder = mod_order;
+	dlsch0_ue->dlsch_config.rv = rvidx;
+	dlsch0_ue->dlsch_config.targetCodeRate = rate;
+  dlsch0_ue->dlsch_config.TBS = TBS;
+	dlsch0_ue->dlsch_config.dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
+	dlsch0_ue->dlsch_config.dlDmrsSymbPos = 4;
+	dlsch0_ue->dlsch_config.n_dmrs_cdm_groups = 1;
+  dlsch0_ue->dlsch_config.tbslbrm = Tbslbrm;
+	printf("harq process ue mcs = %d Qm = %d, symb %d\n", dlsch0_ue->dlsch_config.mcs, dlsch0_ue->dlsch_config.qamModOrder, nb_symb_sch);
 
 	unsigned char *test_input=dlsch->harq_process.pdu;
 	//unsigned char test_input[TBS / 8]  __attribute__ ((aligned(16)));
@@ -539,8 +533,8 @@ int main(int argc, char **argv)
 			vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_IN);
 
 			ret = nr_dlsch_decoding(UE, &proc, 0, channel_output_fixed, &UE->frame_parms,
-					dlsch0_ue, dlsch0_ue->harq_processes[0], frame, nb_symb_sch,
-					slot,harq_pid, is_crnti);
+					dlsch0_ue, harq_process, frame, nb_symb_sch,
+					slot,harq_pid);
 
 			vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_OUT);
 
@@ -551,7 +545,7 @@ int main(int argc, char **argv)
 			errors_bit = 0;
 
 			for (i = 0; i < TBS; i++) {
-				estimated_output_bit[i] = (dlsch0_ue->harq_processes[0]->b[i / 8] & (1 << (i & 7))) >> (i & 7);
+				estimated_output_bit[i] = (harq_process->b[i / 8] & (1 << (i & 7))) >> (i & 7);
 				test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
 
 				if (estimated_output_bit[i] != test_input_bit[i]) {
@@ -620,7 +614,7 @@ int main(int argc, char **argv)
 
   int num_cw = NR_MAX_NB_LAYERS > 4? 2:1;
   for (int i = 0; i < num_cw; i++)
-    free_nr_ue_dlsch(&UE->dlsch[0][i], N_RB_DL);
+    free_nr_ue_dl_harq(UE->dl_harq_processes[i], 8, nb_rb);
   term_nr_ue_signal(UE, 1);
   free(UE);
 
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 3a0c90842dd..8a7f7cce85f 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -1015,7 +1015,7 @@ int main(int argc, char **argv)
 
   nr_dcireq_t dcireq;
   nr_scheduled_response_t scheduled_response;
-  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
+  nr_phy_data_t phy_data = {0};
 
   memset((void*)&dcireq,0,sizeof(dcireq));
   memset((void*)&scheduled_response,0,sizeof(scheduled_response));
@@ -1030,7 +1030,7 @@ int main(int argc, char **argv)
   scheduled_response.CC_id     = 0;
   scheduled_response.frame = frame;
   scheduled_response.slot  = slot;
-  scheduled_response.phy_data = &phy_pdcch_config;
+  scheduled_response.phy_data = &phy_data;
 
   nr_ue_phy_config_request(&UE_mac->phy_config);
   //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
@@ -1084,10 +1084,10 @@ int main(int argc, char **argv)
       dcireq.frame     = frame;
       dcireq.slot      = slot;
 
-      NR_UE_DLSCH_t *dlsch0 = UE->dlsch[0][0];
+      NR_UE_DLSCH_t *dlsch0 = &phy_data.dlsch[0];
 
       int harq_pid = slot;
-      NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid];
+      NR_DL_UE_HARQ_t *UE_harq_process = &UE->dl_harq_processes[0][harq_pid];
 
       NR_gNB_DLSCH_t *gNB_dlsch = msgDataTx->dlsch[0][0];
       nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
@@ -1262,24 +1262,24 @@ int main(int argc, char **argv)
         phy_procedures_nrUE_RX(UE,
                                &UE_proc,
                                0,
-                               &phy_pdcch_config,
+                               &phy_data,
                                NULL);
         
         //----------------------------------------------------------
         //---------------------- count errors ----------------------
         //----------------------------------------------------------
 
-        if (UE->dlsch[0][0]->last_iteration_cnt >=
-          UE->dlsch[0][0]->max_ldpc_iterations+1)
+        if (dlsch0->last_iteration_cnt >=
+          dlsch0->max_ldpc_iterations+1)
           n_errors[round][snrRun]++;
 
         NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars;
         int16_t *UE_llr = pdsch_vars[0]->llr[0];
 
-        TBS                  = UE_harq_process->TBS;//rel15->TBSize[0];
+        TBS                  = dlsch0->dlsch_config.TBS;//rel15->TBSize[0];
         uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
         uint16_t nb_rb       = rel15->rbSize;
-        uint8_t  nb_re_dmrs  = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*UE_harq_process->n_dmrs_cdm_groups : 4*UE_harq_process->n_dmrs_cdm_groups;
+        uint8_t  nb_re_dmrs  = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*dlsch0->dlsch_config.n_dmrs_cdm_groups : 4*dlsch0->dlsch_config.n_dmrs_cdm_groups;
         uint8_t  mod_order   = rel15->qamModOrder[0];
         uint8_t  nb_symb_sch = rel15->NrOfSymbols;
 
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 0a50e79139b..d8514dee519 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -86,25 +86,23 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
 			   UE_nr_rxtx_proc_t *proc,
          int32_t pdcch_est_size,
          int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
-         NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+         nr_phy_data_t *phy_data,
          int n_ss) {
   return 0;
 }
 
 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 eNB_id,
+                           NR_UE_DLSCH_t *dlsch) {
   return 0;
 }
 
 bool nr_ue_dlsch_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 *dlsch_errors) {
+                            NR_UE_DLSCH_t *dlsch1) {
   return false;
 }
 
@@ -746,7 +744,7 @@ int main(int argc, char **argv)
       }
       else {
         UE_nr_rxtx_proc_t proc={0};
-        NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
+        nr_phy_data_t phy_data={0};
 
 	UE->rx_offset=0;
 	uint8_t ssb_index = 0;
@@ -776,7 +774,7 @@ int main(int argc, char **argv)
                          0,
                          ssb_index%8,
                          SISO,
-                         &phy_pdcch_config,
+                         &phy_data,
                          &result);
 
 	if (ret==0) {
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index e5487174596..1559f55a434 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -1131,21 +1131,19 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
 
   NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon = mac->scc != NULL ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon;
+  LOG_T(NR_MAC, "In %s():%d not calling scheduler. sched mode = %d and mac->ra.ra_state = %d\n",
+        __FUNCTION__, __LINE__, ul_info->ue_sched_mode, mac->ra.ra_state);
 
   switch (ul_info->ue_sched_mode) {
     case SCHED_PUSCH:
       ret = nr_ue_scheduler(NULL, ul_info);
       if (is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type) && !get_softmodem_params()->phy_test)
         nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx);
-      LOG_T(NR_MAC, "In %s():%d not calling scheduler. sched mode = %d and mac->ra.ra_state = %d\n",
-            __FUNCTION__, __LINE__, ul_info->ue_sched_mode, mac->ra.ra_state);
       break;
 
     case SCHED_PUCCH:
       if (is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type))
         nr_ue_pucch_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->phy_data);
-      LOG_T(NR_MAC, "In %s():%d not calling scheduler. sched mode = %d and mac->ra.ra_state = %d\n",
-            __FUNCTION__, __LINE__, ul_info->ue_sched_mode, mac->ra.ra_state);
       break;
   }
 
@@ -1241,7 +1239,6 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
                                            (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.ack_nack,
                                            (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu,
                                            (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB;
-            free((dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu);
             break;
           case FAPI_NR_RX_PDU_TYPE_DLSCH:
             ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
-- 
GitLab