diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
index 884ab771e6359f2015eddb7feccd2046e97310de..6f081fa24ffe87cb61054bcaed03011724e0b5f4 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -126,10 +126,10 @@ gNBs =
         # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
         #  
         msg1_SubcarrierSpacing                                      = 1,
-
 # restrictedSetConfig
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
+
       # pusch-ConfigCommon (up to 16 elements)
         initialULBWPk2_0                      = 6;
         initialULBWPmappingType_0             = 1
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 1cbc465ebe9d05874ebf32d54e71e4e5ccb4ccf2..900d4c8324a6fe1d82c4b058f5a16d2ae37fd3f2 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1739,6 +1739,7 @@ set(PHY_SRC_UE
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/sss_nr.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/cic_filter_nr.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+  ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -3258,7 +3259,7 @@ if (${T_TRACER})
         SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL
         NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
         PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
-        L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR
+        L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR
         CN_UTILS GTPV1U NR_GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB
         ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts)
     if (TARGET ${i})
diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md
index 23d32effbbdef58bf8a0d530b4eb7b397a9ae918..1f8d8cfccf30c82ce962f880c2cdd8a7065f6051 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -254,9 +254,11 @@ The NAS layer is based on **3GPP 24.301** and implements the following functions
 The following features are valid for the gNB and the 5G-NR UE.
 
 *  Static TDD, 
+*  FDD
 *  Normal CP
 *  30 kHz subcarrier spacing
 *  Bandwidths up to 80MHz (217 Physical Resource Blocks)
+*  Intermediate downlink and uplink frequencies to interface with IF equipment
 *  Single antenna port (single beam)
 *  Slot format: 14 OFDM symbols in UL or DL
 *  Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 supported)
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index 5fb08245655887c4de5b29d873a999e6eb9be48b..af4a57041f97eac1ac53a0ffd25afcd535b413b4 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -132,6 +132,42 @@ With the RF simulator (on the same machine):
 
 `sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --do-ra --rfsim --parallel-config PARALLEL_SINGLE_THREAD`
 
+## IF setup with OAI
+
+The -C and -CO flags can be used together at UE side to set custom downlink and uplink FR1 intermediate frequencies for the IF equipment.
+
+In order to run this setup, the following flags are needed at the UE side:
+
+`-C` 
+
+`--CO`
+
+and the following parameters must be configured in the RUs section of the gNB configuration file:
+
+`if_freq`
+
+`if_offset`
+
+### Run OAI with custom DL/UL intermediate frequencies
+
+The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 at gNB side.
+
+From the `cmake_targets/ran_build/build` folder:
+
+gNB on machine 1:
+
+`sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf`
+
+UE on machine 2:
+
+`sudo ./nr-uesoftmodem -C 2169080000 --CO -400000000`
+
+
+
+
+
+
+
 
 [oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
 
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 3dd09b49ebcdbb11a4c14b0578afb82fdd75f4f3..216c39ea6745678ad1be3b6f15cc23b97b7de952 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -728,31 +728,27 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
   //nr_subframe_t SF_type     = nr_slot_select(cfg,slot%fp->slots_per_frame);
   if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT || IS_SOFTMODEM_RFSIM) {
 
-    if(slot_type == NR_MIXED_SLOT) {
-      txsymb = 0;
-      for(int symbol_count =0;symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT;symbol_count++) {
-        if (cfg->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0)
-          txsymb++;
+    if (cfg->cell_config.frame_duplex_type.value == TDD){
+      if(slot_type == NR_MIXED_SLOT) {
+        txsymb = 0;
+        for(int symbol_count = 0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
+          if (cfg->tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value == 0)
+            txsymb++;
+        }
+        AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb);
+        if(slot%(fp->slots_per_subframe/2))
+          siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
+        else
+          siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
+                 //+ ru->end_of_burst_delay;
+        flags = 3; // end of burst
       }
-      AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb);
-      if(slot%(fp->slots_per_subframe/2))
-        siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
-      else
-        siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
-               //+ ru->end_of_burst_delay;
-      flags=3; // end of burst
-    }
 
-    if (cfg->cell_config.frame_duplex_type.value == TDD &&
-        slot_type == NR_DOWNLINK_SLOT &&
-        prevslot_type == NR_UPLINK_SLOT) {
-      flags = 2; // start of burst
-    }
+      if (slot_type == NR_DOWNLINK_SLOT && prevslot_type == NR_UPLINK_SLOT)
+        flags = 2; // start of burst
 
-    if (cfg->cell_config.frame_duplex_type.value == TDD &&
-        slot_type == NR_DOWNLINK_SLOT &&
-        nextslot_type == NR_UPLINK_SLOT) {
-      flags = 3; // end of burst
+      if (slot_type == NR_DOWNLINK_SLOT && nextslot_type == NR_UPLINK_SLOT)
+        flags = 3; // end of burst
     }
 
     if (fp->freq_range==nr_FR2) {
@@ -768,7 +764,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
       */
       flags |= beam<<8;
     }
-    
+
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags ); 
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame );
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot );
@@ -1150,19 +1146,22 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
     if (ru->if_frequency == 0) {
       cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
       cfg->rx_freq[i] = (double)fp->ul_CarrierFreq;
-    }
-    else {
+    } else if (ru->if_freq_offset){
+      cfg->tx_freq[i] = (double)(ru->if_frequency);
+      cfg->rx_freq[i] = (double)(ru->if_frequency + ru->if_freq_offset);
+      LOG_I(PHY, "Setting IF TX frequency to %lu Hz with IF RX frequency offset %d Hz\n", ru->if_frequency, ru->if_freq_offset);
+    } else {
       cfg->tx_freq[i] = (double)ru->if_frequency;
       cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq);
     }
     cfg->tx_gain[i] = ru->att_tx;
     cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx;
     cfg->configFilename = rf_config_file;
-    printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n",
+    LOG_I(PHY, "Channel %d: setting tx_gain offset %f, rx_gain offset %f, tx_freq %lu Hz, rx_freq %lu Hz\n",
            i, cfg->tx_gain[i],
            cfg->rx_gain[i],
-           cfg->tx_freq[i],
-           cfg->rx_freq[i]);
+           (unsigned long)cfg->tx_freq[i],
+           (unsigned long)cfg->rx_freq[i]);
   }
 }
 
@@ -2495,6 +2494,7 @@ void RCconfig_RU(void)
       RC.ru[j]->att_tx                            = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
       RC.ru[j]->att_rx                            = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr);
       RC.ru[j]->if_frequency                      = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr);
+      RC.ru[j]->if_freq_offset                    = *(RUParamList.paramarray[j][RU_IF_FREQ_OFFSET].iptr);
 
       if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) {
         RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt;
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 00d6bae2ef832eee06737c18c19fc4998e75e4ca..c1c6e98a41714e5f5ace665da5a897980a2734f7 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -135,17 +135,15 @@ typedef enum {
 
 
 void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
-                     NR_DL_FRAME_PARMS *frame_parms,
                      uint8_t UE_id,
                      uint8_t abstraction_flag)
 {
 
   int nb_connected_gNB = 1, gNB_id;
 
-  memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS));
-
   ue->Mod_id      = UE_id;
   ue->mac_enabled = 1;
+  ue->if_inst     = nr_ue_if_module_init(0);
 
   // Setting UE mode to NOT_SYNCHED by default
   for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){
@@ -158,6 +156,9 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
 
   // intialize transport
   init_nr_ue_transport(ue, abstraction_flag);
+
+  // init N_TA offset
+  init_N_TA_offset(ue);
 }
 
 /*!
@@ -175,31 +176,30 @@ static void UE_synch(void *arg) {
   int i, hw_slot_offset;
   PHY_VARS_NR_UE *UE = syncD->UE;
   sync_mode_t sync_mode = pbch;
-  int CC_id = UE->CC_id;
-  int freq_offset=0;
+  //int CC_id = UE->CC_id;
+  static int freq_offset=0;
   UE->is_synchronized = 0;
 
   if (UE->UE_scan == 0) {
 
+    #ifdef FR2_TEST
     // Overwrite DL frequency (for FR2 testing)
     if (downlink_frequency[0][0]!=0){
        UE->frame_parms.dl_CarrierFreq = downlink_frequency[0][0];
        UE->frame_parms.ul_CarrierFreq = downlink_frequency[0][0];
     }
-
-    LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu64", UL %"PRIu64" (oai_exit %d, rx_num_channels %d)\n",
-           UE->frame_parms.dl_CarrierFreq, UE->frame_parms.ul_CarrierFreq,
-           oai_exit, openair0_cfg[0].rx_num_channels);
+    #endif
 
     for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
-      openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq;
-      openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq;
-      openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
-
-      if (UE->frame_parms.frame_type == FDD) 
-        openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD;
-      else 
-        openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD;
+
+      LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %f, UL %f (RF card %d, oai_exit %d, channel %d, rx_num_channels %d)\n",
+        openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i],
+        openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i],
+        UE->rf_map.card,
+        oai_exit,
+        i,
+        openair0_cfg[0].rx_num_channels);
+
     }
 
     sync_mode = pbch;
@@ -254,31 +254,25 @@ static void UE_synch(void *arg) {
     case pbch:
       LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
 
+      uint64_t dl_carrier, ul_carrier;
+      double rx_gain_off = 0;
+      nr_get_carrier_frequencies(&UE->frame_parms, &dl_carrier, &ul_carrier);
+
       if (nr_initial_sync( &syncD->proc, UE, UE->mode,2) == 0) {
         freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
         hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) +
                          round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0);
-        LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %lu, UL %lu), UE_scan_carrier %d\n",
-              hw_slot_offset,
-              freq_offset,
-              UE->rx_total_gain_dB,
-              UE->frame_parms.dl_CarrierFreq+freq_offset,
-              UE->frame_parms.ul_CarrierFreq+freq_offset,
-              UE->UE_scan_carrier );
 
         // rerun with new cell parameters and frequency-offset
-        for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
-          openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
+        // todo: the freq_offset computed on DL shall be scaled before being applied to UL
+        nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset);
 
-          if (freq_offset >= 0)
-            openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(freq_offset);
-          else
-            openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(freq_offset);
-
-          openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
-            openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+(UE->frame_parms.ul_CarrierFreq-UE->frame_parms.dl_CarrierFreq);
-          UE->frame_parms.dl_CarrierFreq = openair0_cfg[CC_id].rx_freq[i];
-        }
+        LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n",
+              hw_slot_offset,
+              freq_offset,
+              openair0_cfg[UE->rf_map.card].rx_gain[0],
+              openair0_cfg[UE->rf_map.card].rx_freq[0],
+              openair0_cfg[UE->rf_map.card].tx_freq[0]);
 
         // reconfigure for potentially different bandwidth
         switch(UE->frame_parms.N_RB_DL) {
@@ -322,7 +316,6 @@ static void UE_synch(void *arg) {
           //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
           //UE->rfdevice.trx_stop_func(&UE->rfdevice);
           // sleep(1);
-          //nr_init_frame_parms_ue(&UE->frame_parms);
           /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
             LOG_E(HW,"Could not start the device\n");
             oai_exit=1;
@@ -335,31 +328,21 @@ static void UE_synch(void *arg) {
           UE->is_synchronized = 1;
         }
       } else {
-        // initial sync failed
-        // calculate new offset and try again
+
         if (UE->UE_scan_carrier == 1) {
+
           if (freq_offset >= 0)
             freq_offset += 100;
 
           freq_offset *= -1;
-          LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %lu, UL %lu)\n",
-                freq_offset,
-                UE->rx_total_gain_dB,
-                UE->frame_parms.dl_CarrierFreq+freq_offset,
-                UE->frame_parms.ul_CarrierFreq+freq_offset );
 
-          for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
-            openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq+freq_offset;
-            openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq+freq_offset;
-            openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
+          nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset);
 
-            if (UE->UE_scan_carrier==1)
-              openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
-          }
+          LOG_I(PHY, "Initial sync failed: trying carrier off %d Hz\n", freq_offset);
 
           if (UE->mode != loop_through_memory)
             UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
-        }// initial_sync=0
+        }
 
         break;
 
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index de7a3af980254c4f4a1f67db791c893ee76792cd..08834ed74022fccebe0651aa70bad61c65e8215e 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -40,7 +40,7 @@
 //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
 #include "openair1/PHY/MODULATION/nr_modulation.h"
 #include "PHY/phy_vars_nr_ue.h"
-#include "PHY/LTE_TRANSPORT/transport_vars.h"
+#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
 #include "SCHED/sched_common_vars.h"
 #include "PHY/MODULATION/modulation_vars.h"
 //#include "../../SIMU/USER/init_lte.h"
@@ -85,7 +85,9 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include "executables/softmodem-common.h"
 #include "executables/thread-common.h"
 
-// Raphael : missing
+extern const char *duplex_mode[];
+
+// Thread variables
 pthread_cond_t nfapi_sync_cond;
 pthread_mutex_t nfapi_sync_mutex;
 int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
@@ -94,30 +96,40 @@ pthread_cond_t sync_cond;
 pthread_mutex_t sync_mutex;
 int sync_var=-1; //!< protected by mutex \ref sync_mutex.
 int config_sync_var=-1;
+tpool_t *Tpool;
+#ifdef UE_DLSCH_PARALLELISATION
+  tpool_t *Tpool_dl;
+#endif
 
 RAN_CONTEXT_t RC;
 volatile int             start_eNB = 0;
 volatile int             start_UE = 0;
 volatile int             oai_exit = 0;
 
-int                      single_thread_flag=1;
-static double            snr_dB=20;
-
-int                      threequarter_fs=0;
+// Command line options
 
-uint64_t                 downlink_frequency[MAX_NUM_CCs][4];
-int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
-//int32_t					 uplink_counter = 0;
+extern int16_t  nr_dlsch_demod_shift;
+static int      tx_max_power[MAX_NUM_CCs] = {0};
 
-
-extern int16_t nr_dlsch_demod_shift;
-
-int UE_scan = 0;
-int UE_scan_carrier = 0;
-int UE_fo_compensation = 0;
+int      single_thread_flag = 1;
+int         threequarter_fs = 0;
+int         UE_scan_carrier = 0;
+int      UE_fo_compensation = 0;
 int UE_no_timing_correction = 0;
-runmode_t mode = normal_txrx;
-openair0_config_t openair0_cfg[MAX_CARDS];
+int                 N_RB_DL = 0;
+int                 tddflag = 0;
+int                 vcdflag = 0;
+uint8_t       nb_antenna_tx = 1;
+uint8_t       nb_antenna_rx = 1;
+double          rx_gain_off = 0.0;
+uint32_t     timing_advance = 0;
+char             *usrp_args = NULL;
+char       *rrc_config_path = NULL;
+int               dumpframe = 0;
+
+uint64_t        downlink_frequency[MAX_NUM_CCs][4];
+int32_t         uplink_frequency_offset[MAX_NUM_CCs][4];
+int             rx_input_level_dBm;
 
 #if MAX_NUM_CCs == 1
 rx_gain_t                rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}};
@@ -129,74 +141,25 @@ double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}};
 double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}};
 #endif
 
-double rx_gain_off = 0.0;
-
-double sample_rate=30.72e6;
-double bw = 10.0e6;
-
-static int  tx_max_power[MAX_NUM_CCs] = {0};
-
-
-int chain_offset=0;
-
-
-uint8_t dci_Format = 0;
-uint8_t agregation_Level =0xFF;
-
-uint8_t nb_antenna_tx = 1;
-uint8_t nb_antenna_rx = 1;
-
-char ref[128] = "internal";
-char channels[128] = "0";
-
-
-int rx_input_level_dBm;
-
-//static int online_log_messages=0;
-
-
-int otg_enabled;
-//int number_of_cards = 1;
+// UE and OAI config variables
 
-static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
-int16_t node_synch_ref[MAX_NUM_CCs];
-
-uint32_t target_dl_mcs = 28; //maximum allowed mcs
-uint32_t target_ul_mcs = 20;
-uint32_t timing_advance = 0;
-uint64_t num_missed_slots=0; // counter for the number of missed slots
-
-
-int transmission_mode=1;
-int numerology = 0;
-int usrp_tx_thread = 0;
-
-/* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */
-//uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD;
-/* struct for ethernet specific parameters given in eNB conf file */
-//eth_params_t *eth_params;
-
-double cpuf;
+openair0_config_t openair0_cfg[MAX_CARDS];
+int16_t           node_synch_ref[MAX_NUM_CCs];
+int               otg_enabled;
+double            cpuf;
+
+runmode_t            mode = normal_txrx;
+int               UE_scan = 0;
+int          chain_offset = 0;
+uint64_t num_missed_slots = 0; // counter for the number of missed slots
+int     transmission_mode = 1;
+int            numerology = 0;
+int        usrp_tx_thread = 0;
+int           oaisim_flag = 0;
+int            emulate_rf = 0;
 
 char uecap_xer[1024],uecap_xer_in=0;
 
-int oaisim_flag=0;
-int emulate_rf = 0;
-
-tpool_t *Tpool;
-#ifdef UE_DLSCH_PARALLELISATION
-  tpool_t *Tpool_dl;
-#endif
-
-
-char *usrp_args=NULL;
-
-char *rrc_config_path=NULL;
-
-/* forward declarations */
-void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
-
-
 /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
  * this is very hackish - find a proper solution
  */
@@ -245,37 +208,6 @@ void exit_function(const char *file, const char *function, const int line, const
   exit(1);
 }
 
-
-void reset_stats(long arg) {
-  //int i,j,k;
-  /*PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
-
-  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-      for (k=0; k<8; k++) { //harq_processes
-          for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) {
-              phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0;
-              phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0;
-              phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0;
-          }
-
-          phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0;
-          phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0;
-          phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0;
-
-          for (j=0; j<phy_vars_eNB->ulsch[i]->Mlimit; j++) {
-              phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0;
-              phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0;
-              phy_vars_eNB->UE_stats[i].ulsch_round_errors[k][j]=0;
-              phy_vars_eNB->UE_stats[i].ulsch_round_fer[k][j]=0;
-          }
-      }
-
-      phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0;
-      phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0;
-      phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0;
-  }*/
-}
-
 void *l2l1_task(void *arg) {
   MessageDef *message_p = NULL;
   int         result;
@@ -316,21 +248,12 @@ void *l2l1_task(void *arg) {
   return NULL;
 }
 
-
-int16_t dlsch_demod_shift;
-
 static void get_options(void) {
-  int CC_id;
-  int tddflag=0, nonbiotflag, vcdflag=0;
+
   char *loopfile=NULL;
-  int dumpframe=0;
-  //uint32_t noS1;
-  //uint32_t nokrnmod;
-  //uint32_t nokrnmod;
+
   paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ;
   config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
-
-
   paramdef_t cmdline_uemodeparams[] = CMDLINE_UEMODEPARAMS_DESC;
   paramdef_t cmdline_ueparams[] = CMDLINE_NRUEPARAMS_DESC;
   config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL);
@@ -351,54 +274,12 @@ static void get_options(void) {
   if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr)
     if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx;
 
-  if (dumpframe  > 0)  mode = rx_dump_frame;
-
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0];
-  }
-
-  UE_scan=0;
-
-  if (tddflag > 0) {
-    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
-      frame_parms[CC_id]->frame_type = TDD;
-  }
+  if ((cmdline_uemodeparams[CMDLINE_DUMPMEMORY_IDX].paramflags & PARAMFLAG_PARAMSET) != 0)
+    mode = rx_dump_frame;
 
   if (vcdflag > 0)
     ouput_vcd = 1;
 
-  /*if (frame_parms[0]->N_RB_DL !=0) {
-      if ( frame_parms[0]->N_RB_DL < 6 ) {
-       frame_parms[0]->N_RB_DL = 6;
-       printf ( "%i: Invalid number of resource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL);
-      }
-      if ( frame_parms[0]->N_RB_DL > 100 ) {
-       frame_parms[0]->N_RB_DL = 100;
-       printf ( "%i: Invalid number of resource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL);
-      }
-      if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) {
-       frame_parms[0]->N_RB_DL = 50;
-       printf ( "%i: Invalid number of resource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL);
-      }
-      if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) {
-       frame_parms[0]->N_RB_DL = 25;
-       printf ( "%i: Invalid number of resource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL);
-      }
-      UE_scan = 0;
-      frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL;
-      for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
-        frame_parms[CC_id]->N_RB_DL=frame_parms[0]->N_RB_DL;
-        frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL;
-      }
-  }*/
-
-  for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
-    tx_max_power[CC_id]=tx_max_power[0];
-    rx_gain[0][CC_id] = rx_gain[0][0];
-    tx_gain[0][CC_id] = tx_gain[0][0];
-  }
-
-
   if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT))  && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) {
     // Here the configuration file is the XER encoded UE capabilities
     // Read it in and store in asn1c data structures
@@ -408,44 +289,56 @@ static void get_options(void) {
   } /* UE with config file  */
 }
 
+// set PHY vars from command line
+void set_options(int CC_id, PHY_VARS_NR_UE *UE){
+
+  // Init power variables
+  tx_max_power[CC_id] = tx_max_power[0];
+  rx_gain[0][CC_id]   = rx_gain[0][0];
+  tx_gain[0][CC_id]   = tx_gain[0][0];
+
+  // Set UE variables
+  UE->UE_scan              = UE_scan;
+  UE->UE_scan_carrier      = UE_scan_carrier;
+  UE->UE_fo_compensation   = UE_fo_compensation;
+  UE->no_timing_correction = UE_no_timing_correction;
+  UE->mode                 = mode;
+  UE->rx_total_gain_dB     = (int)rx_gain[CC_id][0] + rx_gain_off;
+  UE->tx_total_gain_dB     = (int)tx_gain[CC_id][0];
+  UE->tx_power_max_dBm     = tx_max_power[CC_id];
+
+  LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan %d, UE_scan_carrier %d, UE_no_timing_correction %d \n", mode, UE_fo_compensation, UE_scan, UE_scan_carrier, UE_no_timing_correction);
+
+  // Set FP variables
+  NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
+  fp->nb_antennas_tx    = nb_antenna_tx;
+  fp->nb_antennas_rx    = nb_antenna_rx;
+  fp->threequarter_fs   = threequarter_fs;
+  if (tddflag){
+    fp->frame_type = TDD;
+    LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type);
+  }
+  if (N_RB_DL){
+    fp->N_RB_DL = N_RB_DL;
+    LOG_I(PHY, "Set UE N_RB_DL %d\n", N_RB_DL);
+  }
 
-void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
-  int CC_id;
+  LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", nb_antenna_rx, nb_antenna_tx, threequarter_fs);
 
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    /* Set some default values that may be overwritten while reading options */
-    frame_parms[CC_id] = (NR_DL_FRAME_PARMS *) calloc(sizeof(NR_DL_FRAME_PARMS),1);
-    frame_parms[CC_id]->nr_band          = 78;
-    frame_parms[CC_id]->frame_type          = FDD;
-    frame_parms[CC_id]->tdd_config          = 3;
-    //frame_parms[CC_id]->tdd_config_S        = 0;
-    frame_parms[CC_id]->N_RB_DL             = 106;
-    frame_parms[CC_id]->N_RB_UL             = 106;
-    frame_parms[CC_id]->Ncp                 = NORMAL;
-    //frame_parms[CC_id]->Ncp_UL              = NORMAL;
-    frame_parms[CC_id]->Nid_cell            = 0;
-    //frame_parms[CC_id]->num_MBSFN_config    = 0;
-    frame_parms[CC_id]->nb_antenna_ports_gNB  = 1;
-    frame_parms[CC_id]->nb_antennas_tx      = 1;
-    frame_parms[CC_id]->nb_antennas_rx      = 1;
-    //frame_parms[CC_id]->nushift             = 0;
-    // NR: Init to legacy LTE 20Mhz params
-    frame_parms[CC_id]->numerology_index  = 0;
-    frame_parms[CC_id]->ttis_per_subframe = 1;
-    frame_parms[CC_id]->slots_per_tti   = 2;
-  }
 }
 
 void init_openair0(void) {
   int card;
-  int i;
+  int freq_off = 0;
+  NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms;
 
   for (card=0; card<MAX_CARDS; card++) {
+    uint64_t dl_carrier, ul_carrier;
     openair0_cfg[card].configFilename = NULL;
-    openair0_cfg[card].threequarter_fs = frame_parms[0]->threequarter_fs;
-    numerology = frame_parms[0]->numerology_index;
+    openair0_cfg[card].threequarter_fs = frame_parms->threequarter_fs;
+    numerology = frame_parms->numerology_index;
 
-    if(frame_parms[0]->N_RB_DL == 66) {
+    if(frame_parms->N_RB_DL == 66) {
       if (numerology==3) {
           openair0_cfg[card].sample_rate=122.88e6;
           openair0_cfg[card].samples_per_frame = 1228800;
@@ -453,7 +346,7 @@ void init_openair0(void) {
           LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n");
           exit(-1);
         }
-    }else if(frame_parms[0]->N_RB_DL == 32) {
+    }else if(frame_parms->N_RB_DL == 32) {
       if (numerology==3) {
           openair0_cfg[card].sample_rate=61.44e6;
           openair0_cfg[card].samples_per_frame = 614400;
@@ -461,9 +354,9 @@ void init_openair0(void) {
           LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n");
           exit(-1);
         }
-    }else if(frame_parms[0]->N_RB_DL == 217) {
+    }else if(frame_parms->N_RB_DL == 217) {
       if (numerology==1) {
-        if (frame_parms[0]->threequarter_fs) {
+        if (frame_parms->threequarter_fs) {
           openair0_cfg[card].sample_rate=92.16e6;
           openair0_cfg[card].samples_per_frame = 921600;
         }
@@ -475,9 +368,9 @@ void init_openair0(void) {
         LOG_E(PHY,"Unsupported numerology!\n");
         exit(-1);
       }
-    } else if(frame_parms[0]->N_RB_DL == 273) {
+    } else if(frame_parms->N_RB_DL == 273) {
       if (numerology==1) {
-        if (frame_parms[0]->threequarter_fs) {
+        if (frame_parms->threequarter_fs) {
           AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n");
         }
         else {
@@ -488,9 +381,9 @@ void init_openair0(void) {
         LOG_E(PHY,"Unsupported numerology!\n");
         exit(-1);
       }
-    } else if(frame_parms[0]->N_RB_DL == 106) {
+    } else if(frame_parms->N_RB_DL == 106) {
       if (numerology==0) {
-        if (frame_parms[0]->threequarter_fs) {
+        if (frame_parms->threequarter_fs) {
           openair0_cfg[card].sample_rate=23.04e6;
           openair0_cfg[card].samples_per_frame = 230400;
         } else {
@@ -498,7 +391,7 @@ void init_openair0(void) {
           openair0_cfg[card].samples_per_frame = 307200;
         }
       } else if (numerology==1) {
-        if (frame_parms[0]->threequarter_fs) {
+        if (frame_parms->threequarter_fs) {
           openair0_cfg[card].sample_rate=46.08e6;
           openair0_cfg[card].samples_per_frame = 460800;
 	}
@@ -513,57 +406,44 @@ void init_openair0(void) {
         LOG_E(PHY,"Unsupported numerology!\n");
         exit(-1);
       }
-    } else if(frame_parms[0]->N_RB_DL == 50) {
+    } else if(frame_parms->N_RB_DL == 50) {
       openair0_cfg[card].sample_rate=15.36e6;
       openair0_cfg[card].samples_per_frame = 153600;
-    } else if (frame_parms[0]->N_RB_DL == 25) {
+    } else if (frame_parms->N_RB_DL == 25) {
       openair0_cfg[card].sample_rate=7.68e6;
       openair0_cfg[card].samples_per_frame = 76800;
-    } else if (frame_parms[0]->N_RB_DL == 6) {
+    } else if (frame_parms->N_RB_DL == 6) {
       openair0_cfg[card].sample_rate=1.92e6;
       openair0_cfg[card].samples_per_frame = 19200;
     }
     else {
-      LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms[0]->N_RB_DL);
+      LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms->N_RB_DL);
       exit(-1);
     }
 
-    if (frame_parms[0]->frame_type==TDD)
+    if (frame_parms->frame_type==TDD)
       openair0_cfg[card].duplex_mode = duplex_mode_TDD;
-    else //FDD
+    else
       openair0_cfg[card].duplex_mode = duplex_mode_FDD;
 
-    printf("HW: Configuring card %d, nb_antennas_tx/rx %hhu/%hhu\n",card,
-           PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx,
-           PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx);
     openair0_cfg[card].Mod_id = 0;
-    openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
+    openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL;
     openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
     openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
-    openair0_cfg[card].tx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx);
-    openair0_cfg[card].rx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx);
-
-    for (i=0; i<4; i++) {
-      if (i<openair0_cfg[card].tx_num_channels)
-        openair0_cfg[card].tx_freq[i] = frame_parms[0]->ul_CarrierFreq;
-      else
-        openair0_cfg[card].tx_freq[i]=0.0;
-
-      if (i<openair0_cfg[card].rx_num_channels)
-        openair0_cfg[card].rx_freq[i] = frame_parms[0]->dl_CarrierFreq;
-      else
-        openair0_cfg[card].rx_freq[i]=0.0;
-
-      openair0_cfg[card].autocal[i] = 1;
-      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
-      openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off;
-      openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
-      printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
-             card,i, openair0_cfg[card].tx_gain[i],
-             openair0_cfg[card].rx_gain[i],
-             openair0_cfg[card].tx_freq[i],
-             openair0_cfg[card].rx_freq[i]);
-    }
+    openair0_cfg[card].tx_num_channels = min(2, frame_parms->nb_antennas_tx);
+    openair0_cfg[card].rx_num_channels = min(2, frame_parms->nb_antennas_rx);
+
+    LOG_I(PHY, "HW: Configuring card %d, tx/rx num_channels %d/%d, duplex_mode %s\n",
+      card,
+      openair0_cfg[card].tx_num_channels,
+      openair0_cfg[card].rx_num_channels,
+      duplex_mode[openair0_cfg[card].duplex_mode]);
+
+    nr_get_carrier_frequencies(frame_parms, &dl_carrier, &ul_carrier);
+
+    nr_rf_card_config(&openair0_cfg[card], rx_gain_off, ul_carrier, dl_carrier, freq_off);
+
+    openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
 
     if (usrp_args) openair0_cfg[card].sdr_addrs = usrp_args;
 
@@ -607,14 +487,12 @@ int main( int argc, char **argv ) {
   }
   set_softmodem_sighandler();
   CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
-  set_default_frame_parms(frame_parms);
-  mode = normal_txrx;
   memset(openair0_cfg,0,sizeof(openair0_config_t)*MAX_CARDS);
   memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
   // initialize logging
   logInit();
   // get options and fill parameters from configuration file
-  get_options (); //Command-line options, enb_properties
+  get_options(); //Command-line options
   get_common_options(SOFTMODEM_5GUE_BIT );
 #if T_TRACER
   T_Config_Init();
@@ -649,14 +527,6 @@ int main( int argc, char **argv ) {
   init_NR_UE(1,rrc_config_path);
   if(IS_SOFTMODEM_NOS1)
 	  init_pdcp();
-/*
-#ifdef PDCP_USE_NETLINK
-  netlink_init();
-#if defined(PDCP_USE_NETLINK_QUEUES)
-  pdcp_netlink_init();
-#endif
-#endif
-*/
 
   NB_UE_INST=1;
   NB_INST=1;
@@ -667,93 +537,33 @@ int main( int argc, char **argv ) {
     AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
 
   for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    printf("frame_parms %d\n",frame_parms[CC_id]->ofdm_symbol_size);
-    frame_parms[CC_id]->nb_antennas_tx     = nb_antenna_tx;
-    frame_parms[CC_id]->nb_antennas_rx     = nb_antenna_rx;
-    frame_parms[CC_id]->nb_antenna_ports_gNB = 1; //initial value overwritten by initial sync later
-    frame_parms[CC_id]->threequarter_fs = threequarter_fs;
-    LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx);
 
     PHY_vars_UE_g[0][CC_id] = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
-
     UE[CC_id] = PHY_vars_UE_g[0][CC_id];
     memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE));
 
+    set_options(CC_id, UE[CC_id]);
+
     NR_UE_MAC_INST_t *mac = get_mac_inst(0);
     if(mac->if_module != NULL && mac->if_module->phy_config_request != NULL)
       mac->if_module->phy_config_request(&mac->phy_config);
 
     fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
-    nr_init_frame_parms_ue(frame_parms[CC_id],nrUE_config,NORMAL);
-    
-    init_symbol_rotation(frame_parms[CC_id],frame_parms[CC_id]->dl_CarrierFreq);
-    init_nr_ue_vars(UE[CC_id],frame_parms[CC_id],0,abstraction_flag);
-
-    UE[CC_id]->mac_enabled = 1;
-    UE[CC_id]->if_inst = nr_ue_if_module_init(0);
-    UE[CC_id]->UE_scan = UE_scan;
-    UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
-    UE[CC_id]->UE_fo_compensation = UE_fo_compensation;
-    UE[CC_id]->mode    = mode;
-    UE[CC_id]->no_timing_correction = UE_no_timing_correction;
-    printf("UE[%d]->mode = %d\n",CC_id,mode);
-
-    UE[CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0] + rx_gain_off;
-    UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
-
-    if (UE[CC_id]->frame_parms.frame_type == FDD) {
-      UE[CC_id]->N_TA_offset = 0;
-    } else {
-      int N_RB = UE[CC_id]->frame_parms.N_RB_DL;
-      int N_TA_offset = UE[CC_id]->frame_parms.ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples  for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
-      double factor=1;
-      switch (UE[CC_id]->frame_parms.numerology_index) {
-        case 0: //15 kHz scs
-          AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n");
-          if (N_RB <= 25) factor = .25;      // 7.68 Ms/s
-          else if (N_RB <=50) factor = .5;   // 15.36 Ms/s
-          else if (N_RB <=75) factor = 1.0;  // 30.72 Ms/s
-          else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
-          else AssertFatal(1==0,"Too many PRBS for mu=0\n");
-          break;
-        case 1: //30 kHz sc
-          AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n");
-          if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
-          else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
-          break;
-        case 2: //60 kHz scs
-          AssertFatal(1==0,"scs_common should not be 60 kHz\n");
-          break;
-        case 3: //120 kHz scs
-          AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n");
-          break;
-        case 4: //240 kHz scs
-          AssertFatal(1==0,"scs_common should not be 60 kHz\n");
-          if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
-          else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
-          else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB);
-          break;
-
-        if (N_RB == 100)
-          UE[CC_id]->N_TA_offset = 624;
-        else if (N_RB == 50)
-          UE[CC_id]->N_TA_offset = 624/2;
-        else if (N_RB == 25)
-          UE[CC_id]->N_TA_offset = 624/4;
-      }
-      if (UE[CC_id]->frame_parms.threequarter_fs == 1) factor = factor*.75;
-      UE[CC_id]->N_TA_offset = (int)(N_TA_offset * factor);
-      LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", UE[CC_id]->Mod_id, UE[CC_id]->N_TA_offset, factor, UE[CC_id]->frame_parms.ul_CarrierFreq, N_RB);
-    }
 
-   // Overwrite DL frequency (for FR2 testing)
+    nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
+    init_symbol_rotation(&UE[CC_id]->frame_parms, UE[CC_id]->frame_parms.dl_CarrierFreq);
+    init_nr_ue_vars(UE[CC_id], 0, abstraction_flag);
+
+    #ifdef FR2_TEST
+    // Overwrite DL frequency (for FR2 testing)
     if (downlink_frequency[0][0]!=0){
       frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0];
       if (frame_parms[CC_id]->frame_type == TDD)
-      frame_parms[CC_id]->ul_CarrierFreq = downlink_frequency[0][0];
+        frame_parms[CC_id]->ul_CarrierFreq = downlink_frequency[0][0];
     }
+    #endif
   }
-  //  printf("tx_max_power = %d -> amp %d\n",tx_max_power[0],get_tx_amp(tx_max_poHwer,tx_max_power));
+
   init_openair0();
   // init UE_PF_PO and mutex lock
   pthread_mutex_init(&ue_pf_po_mutex, NULL);
@@ -764,7 +574,6 @@ int main( int argc, char **argv ) {
   if(IS_SOFTMODEM_DOFORMS) { 
     load_softscope("nr",PHY_vars_UE_g[0][0]);
   }     
-  number_of_cards = 1;
 
   for(int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     PHY_vars_UE_g[0][CC_id]->rf_map.card=0;
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 418ed54fc6871fc7358c417dfc53bd8457836fae..b2d321ae293bb368558f4bdabbc411c54f1cd546 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -48,13 +48,12 @@
     {"ue-scan-carrier",          CONFIG_HLP_UESCAN,      PARAMFLAG_BOOL, iptr:&UE_scan_carrier,              defintval:0,           TYPE_INT,      0},     \
     {"ue-fo-compensation",       CONFIG_HLP_UEFO,        PARAMFLAG_BOOL, iptr:&UE_fo_compensation,           defintval:0,           TYPE_INT,      0},     \
     {"ue-max-power",             NULL,                   0,              iptr:&(tx_max_power[0]),            defintval:90,          TYPE_INT,      0},     \
-    {"r"  ,                      CONFIG_HLP_PRB,         0,              iptr:&(frame_parms[0]->N_RB_DL),    defintval:25,          TYPE_UINT,     0},     \
-    {"dlsch-demod-shift",        CONFIG_HLP_DLSHIFT,     0,              iptr:(int32_t *)&dlsch_demod_shift, defintval:0,           TYPE_INT,      0},     \
+    {"r"  ,                      CONFIG_HLP_PRB,         0,              iptr:&(N_RB_DL),                    defintval:25,          TYPE_UINT,     0},     \
     {"usrp-args",                CONFIG_HLP_USRP_ARGS,   0,              strptr:(char **)&usrp_args,         defstrval:"type=b200", TYPE_STRING,   0}      \
   }
 
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
-/*                                            command line parameters common to eNodeB and UE                                                         */
+/*                                            command line parameters common to gNB and UE                                                            */
 /*   optname                helpstr                 paramflags      XXXptr                                 defXXXval              type         numelt */
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define CMDLINE_PARAMS_DESC_UE {  \
@@ -62,22 +61,16 @@
   {"nr-dlsch-demod-shift",  CONFIG_HLP_DLSHIFT,     0,              iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0,           TYPE_INT,    0}, \
   {"A" ,                    CONFIG_HLP_TADV,        0,              uptr:&timing_advance,                  defintval:0,           TYPE_UINT,   0}, \
   {"E" ,                    CONFIG_HLP_TQFS,        PARAMFLAG_BOOL, iptr:&threequarter_fs,                 defintval:0,           TYPE_INT,    0}, \
-  {"m" ,                    CONFIG_HLP_DLMCS,       0,              uptr:&target_dl_mcs,                   defintval:0,           TYPE_UINT,   0}, \
-  {"t" ,                    CONFIG_HLP_ULMCS,       0,              uptr:&target_ul_mcs,                   defintval:0,           TYPE_UINT,   0}, \
   {"T" ,                    CONFIG_HLP_TDD,         PARAMFLAG_BOOL, iptr:&tddflag,                         defintval:0,           TYPE_INT,    0}, \
   {"V" ,                    CONFIG_HLP_VCD,         PARAMFLAG_BOOL, iptr:&vcdflag,                         defintval:0,           TYPE_INT,    0}, \
-  {"s" ,                    CONFIG_HLP_SNR,         0,              dblptr:&snr_dB,                        defdblval:25,          TYPE_DOUBLE, 0}, \
-  {"nbiot-disable",         CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag,                     defintval:0,           TYPE_INT,    0}, \
   {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0,        TYPE_INT,    0}, \
   {"rrc_config_path",       CONFIG_HLP_RRC_CFG_PATH,0,              strptr:(char **)&rrc_config_path,      defstrval:"./",        TYPE_STRING, 0} \
 }
 
-
 extern int T_port;
 extern int T_nowait;
 extern int T_dont_fork;
 
-
 // In nr-ue.c
 extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
 extern void fill_ue_band_info(void);
@@ -86,7 +79,7 @@ extern void init_NR_UE_threads(int);
 extern void reset_opp_meas(void);
 extern void print_opp_meas(void);
 void *UE_thread(void *arg);
-void init_nr_ue_vars(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag);
+void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id, uint8_t abstraction_flag);
 extern tpool_t *Tpool;
 extern tpool_t *Tpool_dl;
 #endif
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index 449d2e095765d01b5e4544e3d60d2b6f77c130c3..feb020154b4f2cc53bba83c8634b1fc9d9216aa2 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -63,6 +63,7 @@ extern "C"
 #define CONFIG_HLP_USIM          "use XOR autentication algo in case of test usim mode\n"
 #define CONFIG_HLP_NOSNGLT       "Disables single-thread mode in lte-softmodem\n"
 #define CONFIG_HLP_DLF           "Set the downlink frequency for all component carriers\n"
+#define CONFIG_HLP_ULF           "Set the uplink frequency offset for all component carriers\n"
 #define CONFIG_HLP_CHOFF         "Channel id offset\n"
 #define CONFIG_HLP_SOFTS         "Enable soft scope and L1 and L2 stats (Xforms)\n"
 #define CONFIG_HLP_EXMCAL        "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
@@ -123,6 +124,7 @@ extern "C"
     {"wait-for-sync",        NULL,                    PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC,                defintval:0,           TYPE_INT,    0},                     \
     {"single-thread-enable", CONFIG_HLP_NOSNGLT,      PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG,           defintval:0,           TYPE_INT,    0},                     \
     {"C" ,                   CONFIG_HLP_DLF,          0,              u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64,   0},                     \
+    {"CO" ,                  CONFIG_HLP_ULF,          0,              iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT,   0},                     \
     {"a" ,                   CONFIG_HLP_CHOFF,        0,              iptr:&CHAIN_OFFSET,                 defintval:0,           TYPE_INT,    0},                     \
     {"d" ,                   CONFIG_HLP_SOFTS,        PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms,         defintval:0,           TYPE_INT8,   0},                     \
     {"q" ,                   CONFIG_HLP_STMON,        PARAMFLAG_BOOL, iptr:&opp_enabled,                  defintval:0,           TYPE_INT,    0},                     \
@@ -230,6 +232,7 @@ extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr);
 #define SOFTMODEM_RTSIGNAL  (SIGRTMIN+1)
 extern void set_softmodem_sighandler(void);
 extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
+extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
 #ifdef __cplusplus
 }
 #endif
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index 67b9d8e9dd6420ab2d869e8379aa91128a3d9900..87a4d6f6af96ac2463434466bc9f4fab5d6e2132 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -23,6 +23,7 @@
 #include "PHY/impl_defs_nr.h"
 
 #define NFAPI_UE_MAX_NUM_CB 8
+#define NFAPI_MAX_NUM_UL_PDU 8
 
 /*
   typedef unsigned int	   uint32_t;
@@ -155,7 +156,7 @@ typedef struct {
   uint16_t slot;
   fapi_nr_tx_config_t tx_config;
   uint16_t number_of_pdus;
-  fapi_nr_tx_request_body_t *tx_request_body;
+  fapi_nr_tx_request_body_t tx_request_body[NFAPI_MAX_NUM_UL_PDU];
 } fapi_nr_tx_request_t;
 
 /// This struct replaces:
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index e4a0ff13ae3c4ec7054a6f2ebc673f440e5b0961..80469f3e815817fc97b8805ed31b4c2472924e78 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -45,8 +45,6 @@
 
 /*
 extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
-
-extern int32_t get_nr_uldl_offset(int nr_bandP);
 extern openair0_config_t openair0_cfg[MAX_CARDS];
 */
 
@@ -451,52 +449,26 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
   uint8_t short_sequence, num_sequences, rootSequenceIndex, fd_occasion;
   NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms;
   nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config;
+  int32_t dlul_offset = 0;
 
-  /*
-  gNB_config->cell_config.phy_cell_id.value             = phy_config->cfg->cell_config.phy_cell_id.value;
-  gNB_config->carrier_config.dl_frequency.value         = phy_config->cfg->carrier_config.dl_frequency.value;
-  gNB_config->carrier_config.uplink_frequency.value     = phy_config->cfg->carrier_config.uplink_frequency.value;
-  gNB_config->ssb_config.scs_common.value               = phy_config->cfg->ssb_config.scs_common.value;
-  gNB_config->carrier_config.dl_bandwidth.value         = phy_config->cfg->carrier_config.dl_bandwidth.value;
-  gNB_config->carrier_config.uplink_bandwidth.value     = phy_config->cfg->carrier_config.uplink_bandwidth.value;
-  gNB_config->ssb_table.ssb_subcarrier_offset.value     = phy_config->cfg->ssb_table.ssb_subcarrier_offset.value;
-  gNB_config->ssb_table.ssb_offset_point_a.value        = phy_config->cfg->ssb_table.ssb_offset_point_a.value;
-  gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = phy_config->cfg->ssb_table.ssb_mask_list[0].ssb_mask.value;
-  gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = phy_config->cfg->ssb_table.ssb_mask_list[1].ssb_mask.value;
-  gNB_config->ssb_table.ssb_period.value		= phy_config->cfg->ssb_table.ssb_period.value;
-  for (int i=0; i<5; i++) {
-    gNB_config->carrier_config.dl_grid_size[i].value    = phy_config->cfg->carrier_config.dl_grid_size[i].value;
-    gNB_config->carrier_config.ul_grid_size[i].value    = phy_config->cfg->carrier_config.ul_grid_size[i].value;
-    gNB_config->carrier_config.dl_k0[i].value           = phy_config->cfg->carrier_config.dl_k0[i].value;
-    gNB_config->carrier_config.ul_k0[i].value           = phy_config->cfg->carrier_config.ul_k0[i].value;
-  }
-
-
-  if (phy_config->cfg->cell_config.frame_duplex_type.value == 0) {
-    gNB_config->cell_config.frame_duplex_type.value = FDD;
-  } else {
-    gNB_config->cell_config.frame_duplex_type.value = TDD;
-  }
-
-  memcpy((void*)&gNB_config->prach_config,(void*)&phy_config->cfg->prach_config,sizeof(phy_config->cfg->prach_config));
-  memcpy((void*)&gNB_config->tdd_table,(void*)&phy_config->cfg->tdd_table,sizeof(phy_config->cfg->tdd_table));
-  */
   memcpy((void*)gNB_config,phy_config->cfg,sizeof(*phy_config->cfg));
   RC.gNB[Mod_id]->mac_enabled     = 1;
 
   uint64_t dl_bw_khz = (12*gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<<gNB_config->ssb_config.scs_common.value);
   fp->dl_CarrierFreq = ((dl_bw_khz>>1) + gNB_config->carrier_config.dl_frequency.value)*1000 ;
-
-  int32_t dlul_offset = 0;
-  lte_frame_type_t frame_type = 0;
   
-  get_band(fp->dl_CarrierFreq,&fp->nr_band,&dlul_offset,&frame_type);
-
   uint64_t ul_bw_khz = (12*gNB_config->carrier_config.ul_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<<gNB_config->ssb_config.scs_common.value);
   fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ;
 
-  AssertFatal(fp->ul_CarrierFreq==(fp->dl_CarrierFreq+dlul_offset), "Disagreement in uplink frequency for band %d\n", fp->nr_band);
+  fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+
+  get_delta_duplex(fp->nr_band, gNB_config->ssb_config.scs_common.value, &dlul_offset);
+  dlul_offset *= 1000;
+
+  AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + dlul_offset), "Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n", fp->nr_band, fp->ul_CarrierFreq, fp->dl_CarrierFreq + dlul_offset);
   
+  LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, dlul_offset);
+
   fp->threequarter_fs = openair0_cfg[0].threequarter_fs;
   LOG_I(PHY,"Configuring MIB for instance %d, : (Nid_cell %d,DL freq %llu, UL freq %llu)\n",
         Mod_id,
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 39e99e6ec3e0cfce6437ec0df76ba08224b711b7..ac63718c4b08f0e35753c9ca0709adb8367a6c13 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -350,13 +350,6 @@ void phy_config_meas_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n
 }
 */
 
-#if defined(Rel10) || defined(Rel14)
-void phy_config_dedicated_scell_ue(uint8_t Mod_id,
-                                   uint8_t eNB_index,
-                                   SCellToAddMod_r10_t *sCellToAddMod_r10,
-                                   int CC_id) {
-}
-#endif
 
 #if 0
 void phy_config_harq_ue(module_id_t Mod_id,
@@ -374,210 +367,6 @@ void phy_config_harq_ue(module_id_t Mod_id,
 
 extern uint16_t beta_cqi[16];
 
-/*
-void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
-                             struct PhysicalConfigDedicated *physicalConfigDedicated )
-{
-
-  static uint8_t first_dedicated_configuration = 0;
-  PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
-
-  phy_vars_ue->total_TBS[eNB_id]=0;
-  phy_vars_ue->total_TBS_last[eNB_id]=0;
-  phy_vars_ue->bitrate[eNB_id]=0;
-  phy_vars_ue->total_received_bits[eNB_id]=0;
-  phy_vars_ue->dlsch_errors[eNB_id]=0;
-  phy_vars_ue->dlsch_errors_last[eNB_id]=0;
-  phy_vars_ue->dlsch_received[eNB_id]=0;
-  phy_vars_ue->dlsch_received_last[eNB_id]=0;
-  phy_vars_ue->dlsch_fer[eNB_id]=0;
-
-  phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1;
-  phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1;
-
-  if (physicalConfigDedicated) {
-    LOG_D(PHY,"[UE %d] Received physicalConfigDedicated from eNB %d\n",Mod_id, eNB_id);
-    LOG_D(PHY,"------------------------------------------------------------------------\n");
-
-    if (physicalConfigDedicated->pdsch_ConfigDedicated) {
-      phy_vars_ue->pdsch_config_dedicated[eNB_id].p_a=physicalConfigDedicated->pdsch_ConfigDedicated->p_a;
-      LOG_D(PHY,"pdsch_config_dedicated.p_a %d\n",phy_vars_ue->pdsch_config_dedicated[eNB_id].p_a);
-      LOG_D(PHY,"\n");
-    }
-
-    if (physicalConfigDedicated->pucch_ConfigDedicated) {
-      if (physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.present==PUCCH_ConfigDedicated__ackNackRepetition_PR_release)
-        phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=0;
-      else {
-        phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=1;
-      }
-
-      if (physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode)
-        phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode = *physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode;
-      else
-        phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode = bundling;
-
-      if ( phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode == multiplexing)
-        LOG_D(PHY,"pucch_config_dedicated.tdd_AckNackFeedbackMode = multiplexing\n");
-      else
-        LOG_D(PHY,"pucch_config_dedicated.tdd_AckNackFeedbackMode = bundling\n");
-    }
-
-    if (physicalConfigDedicated->pusch_ConfigDedicated) {
-      phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index;
-      phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index;
-      phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index;
-
-
-      LOG_D(PHY,"pusch_config_dedicated.betaOffset_ACK_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index);
-      LOG_D(PHY,"pusch_config_dedicated.betaOffset_RI_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index);
-      LOG_D(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d => %d)\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index,beta_cqi[phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index]);
-      LOG_D(PHY,"\n");
-
-
-    }
-
-    if (physicalConfigDedicated->uplinkPowerControlDedicated) {
-
-      phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH = physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUSCH;
-      phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled= physicalConfigDedicated->uplinkPowerControlDedicated->deltaMCS_Enabled;
-      phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled= physicalConfigDedicated->uplinkPowerControlDedicated->accumulationEnabled;
-      phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUCCH= physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUCCH;
-      phy_vars_ue->ul_power_control_dedicated[eNB_id].pSRS_Offset= physicalConfigDedicated->uplinkPowerControlDedicated->pSRS_Offset;
-      phy_vars_ue->ul_power_control_dedicated[eNB_id].filterCoefficient= *physicalConfigDedicated->uplinkPowerControlDedicated->filterCoefficient;
-      LOG_D(PHY,"ul_power_control_dedicated.p0_UE_PUSCH %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH);
-      LOG_D(PHY,"ul_power_control_dedicated.deltaMCS_Enabled %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled);
-      LOG_D(PHY,"ul_power_control_dedicated.accumulationEnabled %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled);
-      LOG_D(PHY,"ul_power_control_dedicated.p0_UE_PUCCH %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUCCH);
-      LOG_D(PHY,"ul_power_control_dedicated.pSRS_Offset %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].pSRS_Offset);
-      LOG_D(PHY,"ul_power_control_dedicated.filterCoefficient %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].filterCoefficient);
-      LOG_D(PHY,"\n");
-    }
-
-    if (physicalConfigDedicated->antennaInfo) {
-      phy_vars_ue->transmission_mode[eNB_id] = 1+(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode);
-      LOG_I(PHY,"Transmission Mode %d\n",phy_vars_ue->transmission_mode[eNB_id]);
-      switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) {
-      case AntennaInfoDedicated__transmissionMode_tm1:
-        phy_vars_ue->transmission_mode[eNB_id] = 1;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm2:
-        phy_vars_ue->transmission_mode[eNB_id] = 2;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm3:
-        phy_vars_ue->transmission_mode[eNB_id] = 3;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm4:
-        phy_vars_ue->transmission_mode[eNB_id] = 4;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm5:
-        phy_vars_ue->transmission_mode[eNB_id] = 5;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm6:
-        phy_vars_ue->transmission_mode[eNB_id] = 6;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm7:
-        lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[0][eNB_id]->crnti);
-        phy_vars_ue->transmission_mode[eNB_id] = 7;
-        break;
-      default:
-        LOG_E(PHY,"Unknown transmission mode!\n");
-        break;
-      }
-    } else {
-      LOG_D(PHY,"[UE %d] Received NULL physicalConfigDedicated->antennaInfo from eNB %d\n",Mod_id, eNB_id);
-    }
-
-    if (physicalConfigDedicated->schedulingRequestConfig) {
-      if (physicalConfigDedicated->schedulingRequestConfig->present == SchedulingRequestConfig_PR_setup) {
-        phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex = physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex;
-        phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex=physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_ConfigIndex;
-        phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax=physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax;
-
-        LOG_D(PHY,"scheduling_request_config.sr_PUCCH_ResourceIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
-        LOG_D(PHY,"scheduling_request_config.sr_ConfigIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex);
-        LOG_D(PHY,"scheduling_request_config.dsr_TransMax %d\n",phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax);
-      }
-
-      LOG_D(PHY,"------------------------------------------------------------\n");
-
-    }
-
-    if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) {
-
-      phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 0;
-      if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
-        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 1;
-        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].duration             = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration;
-        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].cyclicShift          = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift;
-        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition   = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
-        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth        = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
-        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex      = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;
-        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_HoppingBandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;
-        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].transmissionComb     = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
-
-
-        LOG_D(PHY,"soundingrs_ul_config_dedicated.srs_ConfigIndex %d\n",phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex);
-      }
-
-      LOG_D(PHY,"------------------------------------------------------------\n");
-
-    }
-
-
-    if (physicalConfigDedicated->cqi_ReportConfig) {
-      if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) {
-        // configure PUSCH CQI reporting
-        phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic;
-        if ((phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm12) &&
-            (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm30) &&
-            (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm31))
-          LOG_E(PHY,"Unsupported Aperiodic CQI Feedback Mode : %d\n",phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic);
-      }
-      if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) {
-        if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) {
-        // configure PUCCH CQI reporting
-          phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
-          phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex     = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex;
-          if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex)
-            phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex;
-        }
-        else if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_release) {
-          // handle release
-          phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1;
-          phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1;
-        }
-      }
-    }
-
-  } else {
-    LOG_D(PHY,"[PHY][UE %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id,eNB_id);
-    return;
-  }
-
-  // fill cqi parameters for periodic CQI reporting
-  get_cqipmiri_params(phy_vars_ue,eNB_id);
-
-  // disable MIB SIB decoding once we are on connected mode
-  first_dedicated_configuration ++;
-  if(first_dedicated_configuration > 1)
-  {
-    LOG_I(PHY,"Disable SIB MIB decoding \n");
-    phy_vars_ue->decode_SIB = 0;
-    phy_vars_ue->decode_MIB = 0;
-  }
-  //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti;
-  if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234)
-      phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti;
-  else
-      phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti;
-
-  LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti,
-                               phy_vars_ue->pdcch_vars[1][eNB_id]->crnti);
-
-
-}*/
-
 /*! \brief Helper function to allocate memory for DLSCH data structures.
  * \param[out] pdsch Pointer to the LTE_UE_PDSCH structure to initialize.
  * \param[in] frame_parms LTE_DL_FRAME_PARMS structure.
@@ -656,7 +445,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   fp->nb_antennas_rx=1;
   // dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig;
   // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
-  printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
+  LOG_I(PHY, "Initializing UE vars (abstraction %u) for gNB TXant %u, UE RXant %u\n", abstraction_flag, fp->nb_antennas_tx, fp->nb_antennas_rx);
   //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
   phy_init_nr_top(ue);
   // many memory allocation sizes are hard coded
@@ -971,6 +760,61 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,
   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,0);
 }
 
+
+void init_N_TA_offset(PHY_VARS_NR_UE *ue){
+
+  NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
+
+  if (fp->frame_type == FDD) {
+    ue->N_TA_offset = 0;
+  } else {
+    int N_RB = fp->N_RB_DL;
+    int N_TA_offset = fp->ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples  for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
+    double factor = 1;
+    switch (fp->numerology_index) {
+      case 0: //15 kHz scs
+        AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n");
+        if (N_RB <= 25) factor = .25;      // 7.68 Ms/s
+        else if (N_RB <=50) factor = .5;   // 15.36 Ms/s
+        else if (N_RB <=75) factor = 1.0;  // 30.72 Ms/s
+        else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
+        else AssertFatal(1==0, "Too many PRBS for mu=0\n");
+        break;
+      case 1: //30 kHz sc
+        AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n");
+        if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
+        else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
+        break;
+      case 2: //60 kHz scs
+        AssertFatal(1==0, "scs_common should not be 60 kHz\n");
+        break;
+      case 3: //120 kHz scs
+        AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n");
+        break;
+      case 4: //240 kHz scs
+        AssertFatal(1==0, "scs_common should not be 60 kHz\n");
+        if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
+        else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
+        else AssertFatal(1==0, "N_RB %d is too big for curretn FR2 implementation\n", N_RB);
+        break;
+
+      if (N_RB == 100)
+        ue->N_TA_offset = 624;
+      else if (N_RB == 50)
+        ue->N_TA_offset = 624/2;
+      else if (N_RB == 25)
+        ue->N_TA_offset = 624/4;
+    }
+
+    if (fp->threequarter_fs == 1)
+      factor = factor*.75;
+
+    ue->N_TA_offset = (int)(N_TA_offset * factor);
+
+    LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, N_RB);
+  }
+}
+
 void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   crcTableInit();
@@ -988,57 +832,3 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
   //init_scrambling_lut();
   //set_taus_seed(1328);
 }
-
-void set_default_frame_parms_single(nfapi_nr_config_request_t *config,
-                                    NR_DL_FRAME_PARMS *frame_parms) {
-        /* Set some default values that may be overwritten while reading options */
-  frame_parms = (NR_DL_FRAME_PARMS*) malloc(sizeof(NR_DL_FRAME_PARMS));
-  config = (nfapi_nr_config_request_t*) malloc(sizeof(nfapi_nr_config_request_t));
-  config->subframe_config.numerology_index_mu.value =1;
-  config->subframe_config.duplex_mode.value = 1; //FDD
-  config->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL
-  config->rf_config.dl_carrier_bandwidth.value = 100;
-  config->rf_config.ul_carrier_bandwidth.value = 100;
-  config->sch_config.physical_cell_id.value = 0;
-  
-  frame_parms->frame_type          = FDD;
-  //frame_parms[CC_id]->tdd_config_S        = 0;
-  frame_parms->N_RB_DL             = 106;
-  frame_parms->N_RB_UL             = 106;
-  frame_parms->Ncp                 = NORMAL;
-  //frame_parms[CC_id]->Ncp_UL              = NORMAL;
-  frame_parms->Nid_cell            = 0;
-  //frame_parms[CC_id]->num_MBSFN_config    = 0;
-  frame_parms->nb_antenna_ports_gNB  = 1;
-  frame_parms->nb_antennas_tx      = 1;
-  frame_parms->nb_antennas_rx      = 1;
-  
-  //frame_parms[CC_id]->nushift             = 0;
-  
-  ///frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
-  //frame_parms[CC_id]->phich_config_common.phich_duration = normal;
-  
-  // UL RS Config
-  /*frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 1;//n_DMRS1 set to 0
-    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
-    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
-    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
-    
-    frame_parms[CC_id]->pusch_config_common.n_SB = 1;
-    frame_parms[CC_id]->pusch_config_common.hoppingMode = 0;
-    frame_parms[CC_id]->pusch_config_common.pusch_HoppingOffset = 0;
-    frame_parms[CC_id]->pusch_config_common.enable64QAM = 0;
-    
-    frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
-    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
-    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
-    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
-    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;*/
-  
-  // NR: Init to legacy LTE 20Mhz params
-  frame_parms->numerology_index	= 0;
-  frame_parms->ttis_per_subframe	= 1;
-  frame_parms->slots_per_tti		= 2;
-  
-  
-}
diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c
index b708fdcb6f53f398999a159ce8062923fc3e9ae9..92d8c2a1c666b215a9a3c3acead3dff93cbe33e3 100644
--- a/openair1/PHY/INIT/nr_parms.c
+++ b/openair1/PHY/INIT/nr_parms.c
@@ -27,8 +27,6 @@
 uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
 uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16};
 
-
-
 int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
 {
 
@@ -85,6 +83,7 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
 
 void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
 {
+
   switch(mu) {
 
     case NR_MU_0: //15kHz scs
@@ -265,13 +264,15 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg,
                         NR_DL_FRAME_PARMS *fp)
 {
 
+  AssertFatal (cfg != NULL, "%s %s:%i Null pointer to cfg %p!\n", __FUNCTION__, __FILE__, __LINE__, cfg);
+
   fp->frame_type = cfg->cell_config.frame_duplex_type.value;
   fp->L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ;
   fp->N_RB_DL = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value;
   fp->N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value;
 
   int Ncp = NFAPI_CP_NORMAL;
-  int mu = cfg!= NULL ?  cfg->ssb_config.scs_common.value : 0;
+  int mu = cfg->ssb_config.scs_common.value;
 
 #if DISABLE_LOG_X
   printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, fp->N_RB_DL, Ncp);
@@ -320,7 +321,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg,
   }
 
   fp->N_ssb = 0;
-  int num_tx_ant = (cfg == NULL) ? fp->Lmax : cfg->carrier_config.num_tx_ant.value;
+  int num_tx_ant = cfg->carrier_config.num_tx_ant.value;
 
   for (int p=0; p<num_tx_ant; p++)
     fp->N_ssb += ((fp->L_ssb >> (63-p)) & 0x01);
@@ -330,10 +331,23 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg,
 }
 
 int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
-			   fapi_nr_config_request_t* config, 
-			   int Ncp) 
+                           fapi_nr_config_request_t* config,
+                           uint16_t nr_band)
 {
 
+  uint8_t nb_ant_ports_gNB  = 1;
+  uint8_t tdd_cfg           = 3;
+  uint8_t Nid_cell          = 0;
+  int     Ncp               = NORMAL;
+
+  // default values until overwritten by RRCConnectionReconfiguration
+  fp->nb_antenna_ports_gNB = nb_ant_ports_gNB;
+  fp->tdd_config           = tdd_cfg;
+  fp->Nid_cell             = Nid_cell;
+  fp->nr_band              = nr_band;
+
+  LOG_I(PHY, "Initializing frame parms: set nb_antenna_ports_gNB %d, tdd_config, %d, Nid_cell %d\n", fp->nb_antenna_ports_gNB, fp->tdd_config, fp->Nid_cell);
+
   uint64_t dl_bw_khz = (12*config->carrier_config.dl_grid_size[config->ssb_config.scs_common])*(15<<config->ssb_config.scs_common);
   fp->dl_CarrierFreq = ((dl_bw_khz>>1) + config->carrier_config.dl_frequency)*1000 ;
 
@@ -345,11 +359,15 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
   fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index];
 
   int32_t uplink_frequency_offset = 0;
+  get_delta_duplex(fp->nr_band, fp->numerology_index, &uplink_frequency_offset);
+  get_frame_type(fp->nr_band, fp->numerology_index, &fp->frame_type);
+  uplink_frequency_offset *= 1000;
 
-  get_band(fp->dl_CarrierFreq, &fp->nr_band, &uplink_frequency_offset, &fp->frame_type);
+  LOG_I(PHY, "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, uplink_frequency_offset);
 
   AssertFatal(fp->frame_type==config->cell_config.frame_duplex_type, "Invalid duplex type in config request file for band %d\n", fp->nr_band);
-  AssertFatal(fp->ul_CarrierFreq==(fp->dl_CarrierFreq+uplink_frequency_offset), "Disagreement in uplink frequency for band %d\n", fp->nr_band);
+
+  AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + uplink_frequency_offset), "Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n", fp->nr_band, fp->ul_CarrierFreq, fp->dl_CarrierFreq + uplink_frequency_offset);
 
 #if DISABLE_LOG_X
   printf("Initializing UE frame parms for mu %d, N_RB %d, Ncp %d\n",fp->numerology_index, fp->N_RB_DL, Ncp);
@@ -365,11 +383,6 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
   set_scs_parameters(fp,fp->numerology_index,config->carrier_config.dl_bandwidth);
 
   fp->slots_per_frame = 10* fp->slots_per_subframe;
-
-  fp->nb_antenna_ports_gNB = 1; // default value until overwritten by RRCConnectionReconfiguration
-  fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration
-  fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration
-
   fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
   fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
   fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index 1862d5f8e00595bf05abb4d58f8f733e43a9227f..9c474264c8387288260a737533293541928c32c7 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -394,9 +394,10 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
 void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
 int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp);
 int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
-int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,fapi_nr_config_request_t *config,int Ncp);
+int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
 int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
 void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag);
+void init_N_TA_offset(PHY_VARS_NR_UE *ue);
 void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
 int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char abstraction_flag);
 void nr_phy_config_request(NR_PHY_Config_t *gNB);
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 71a5771f5be55947ee1eec2b38d6d1ac00a39135..71cd4c44e4af81fdc79f215c8955240f4505eacf 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -445,7 +445,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
       assert(0);
     }
 
-    if( symbol == 3)
+    if( dmrss == 2) // update time statistics for last PBCH symbol
     {
         // do ifft of channel estimate
         for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
index 347c9c2ab90dbbc16212f563b77c4147e7aff2a2..fa090933061678770e53c8f3aec0f010a6a693b7 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
@@ -59,7 +59,7 @@
 
 
 
-uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t nr_tti_rx) {
+uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t slot) {
   /*
     #ifdef DEBUG_DCI
     if (frame_parms->frame_type == TDD)
@@ -69,11 +69,11 @@ uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8
     #endif
   */
   uint8_t ret = 255;
-  uint8_t subframe = nr_tti_rx>>((int)(log2 (frame_parms->ttis_per_subframe)));
+  uint8_t subframe = slot / frame_parms->slots_per_subframe;
 
   AssertFatal(1==0,"Not ready for this ...\n");
   if (frame_parms->frame_type == FDD) {
-    ret = (((frame<<1)+nr_tti_rx)&7);
+    ret = (((frame<<1)+slot)&7);
   } else {
 
   }
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 7378f69c271a0ae9fc8c4d316ec58e0288afde31..43b2e9e3ce6fbe0992b851d572d0c32e51e313eb 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -296,7 +296,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
     return(dlsch->max_ldpc_iterations + 1);
   }
 
-  /*if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) {
+  /*if (nr_tti_rx> (frame_parms->slots_per_subframe-1)) {
     printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx);
     return(dlsch->max_ldpc_iterations + 1);
   }*/
@@ -649,14 +649,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
     }
   }
 
-  int32_t frame_rx_prev = frame;
-  int32_t tti_rx_prev = nr_tti_rx - 1;
-  if (tti_rx_prev < 0) {
-    frame_rx_prev--;
-    tti_rx_prev += 10*frame_parms->ttis_per_subframe;
-  }
-  frame_rx_prev = frame_rx_prev%1024;
-
   if (err_flag == 1) {
 //#if UE_DEBUG_TRACE
     LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
@@ -843,7 +835,7 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     return(dlsch->max_ldpc_iterations);
   }
 
- /* if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) {
+ /* if (nr_tti_rx> (frame_parms->slots_per_subframe-1)) {
     printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx);
     return(dlsch->max_ldpc_iterations);
   }
@@ -1246,14 +1238,6 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     }
   //} //loop r
 
-  int32_t frame_rx_prev = frame;
-  int32_t tti_rx_prev = nr_tti_rx - 1;
-  if (tti_rx_prev < 0) {
-    frame_rx_prev--;
-    tti_rx_prev += 10*frame_parms->ttis_per_subframe;
-  }
-  frame_rx_prev = frame_rx_prev%1024;
-
   if (err_flag == 1) {
 #if UE_DEBUG_TRACE
     LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index dd6fa10e5c79e01d21d025c4e3cedb1f6eaf4f0d..fae97f682480c8feb835046fe3964e327d88dcdf 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -242,6 +242,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
 
   dlsch0_harq->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
   dlsch0_harq->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
+  if (dlsch0_harq->Qm == 0 || dlsch0_harq->R == 0) {
+    LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
+      return -1;
+  }
 
   #ifdef DEBUG_HARQ
     printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode);
@@ -981,7 +985,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   }
 
   if (dlsch1_harq) {
-    switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) {
+    uint8_t Qm = nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table);
+    if (Qm == 0){
+      LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
+        return -1;
+    }
+    switch (Qm) {
       case 2 :
         if (rx_type==rx_standard) {
             nr_dlsch_qpsk_llr(frame_parms,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index 5c480d6646e3b695e54374f889f5ca80af850ec5..2db188f5321c2f152eabb3dfdce6327850e232e3 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -297,9 +297,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode,
 
       rx_sss_nr(ue,&metric_tdd_ncp,&phase_tdd_ncp);
 
-      //FK: why do we need to do this again here?
-      //nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0);
-
       nr_gold_pbch(ue);
       ret = nr_pbch_detection(proc, ue,1,mode);  // start pbch detection at first symbol after pss
 
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 845eace8b607609eac43b9307024675953953ec7..746c7edfa9792015d98ea0c24e721861f34354fe 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -1452,6 +1452,31 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
                     runmode_t mode,
                     int n_frames);
 
+/*!
+  \brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the availability of the latter
+  @param fp         Pointer to frame params
+  @param dl_Carrier Pointer to DL carrier to be set
+  @param ul_Carrier Pointer to UL carrier to be set
+*/
+void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp,
+                                uint64_t *dl_Carrier,
+                                uint64_t *ul_Carrier);
+
+/*!
+  \brief This function sets the OAI RF card rx/tx params
+  @param openair0_cfg   Pointer OAI config for a specific card
+  @param tx_gain_off    Tx gain offset
+  @param rx_gain_off    Rx gain offset
+  @param ul_Carrier     UL carrier to be set
+  @param dl_Carrier     DL carrier to be set
+  @param freq_offset    Freq offset to be set
+*/
+void nr_rf_card_config(openair0_config_t *openair0_cfg,
+                       double rx_gain_off,
+                       uint64_t ul_Carrier,
+                       uint64_t dl_Carrier,
+                       int freq_offset);
+
 
 /*!
   \brief Encoding of PUSCH/ACK/RI/ACK from 36-212.
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
new file mode 100644
index 0000000000000000000000000000000000000000..7cf64b28bb3d13361f81df11b9de66a12b991595
--- /dev/null
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file PHY/NR_UE_TRANSPORT/nr_ue_rf_config.c
+* \brief      Functional helpers to configure the RF boards at UE side
+* \author     Guido Casati
+* \date       2020
+* \version    0.1
+* \company    Fraunhofer IIS
+* \email:     guido.casati@iis.fraunhofer.de
+*/
+
+#include "PHY/defs_nr_UE.h"
+#include "PHY/phy_extern_nr_ue.h"
+#include "nr_transport_proto_ue.h"
+
+void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp, uint64_t *dl_carrier, uint64_t *ul_carrier){
+
+  if (downlink_frequency[0][0])
+    *dl_carrier = downlink_frequency[0][0];
+  else
+    *dl_carrier = fp->dl_CarrierFreq;
+
+  if (uplink_frequency_offset[0][0])
+    *ul_carrier = *dl_carrier + uplink_frequency_offset[0][0];
+  else
+    *ul_carrier = *dl_carrier + fp->ul_CarrierFreq - fp->dl_CarrierFreq;
+
+}
+
+void nr_rf_card_config(openair0_config_t *openair0_cfg,
+                       double rx_gain_offset,
+                       uint64_t ul_carrier,
+                       uint64_t dl_carrier,
+                       int freq_offset){
+
+  uint8_t mod_id     = 0;
+  uint8_t cc_id      = 0;
+  PHY_VARS_NR_UE *ue = PHY_vars_UE_g[mod_id][cc_id];
+  int rf_chain       = ue->rf_map.chain;
+  double rx_gain     = ue->rx_total_gain_dB;
+  double tx_gain     = ue->tx_total_gain_dB;
+
+  for (int i = rf_chain; i < rf_chain + 4; i++) {
+
+    if (i < openair0_cfg->rx_num_channels)
+      openair0_cfg->rx_freq[i + rf_chain] = dl_carrier + freq_offset;
+    else
+      openair0_cfg->rx_freq[i] = 0.0;
+
+    if (i<openair0_cfg->tx_num_channels)
+      openair0_cfg->tx_freq[i] = ul_carrier + freq_offset;
+    else
+      openair0_cfg->tx_freq[i] = 0.0;
+
+    if (tx_gain)
+      openair0_cfg->tx_gain[i] = tx_gain;
+    if (rx_gain)
+      openair0_cfg->rx_gain[i] = rx_gain - rx_gain_offset;
+
+    openair0_cfg->autocal[i] = 1;
+
+    LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n",
+      i,
+      rf_chain,
+      openair0_cfg->tx_gain[i],
+      openair0_cfg->rx_gain[i],
+      openair0_cfg->tx_freq[i],
+      openair0_cfg->rx_freq[i]);
+
+  }
+}
\ No newline at end of file
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index ee10c96c206767d34eae4a95c0921f45faab559e..5a8790802d8ec29feae7f3b5b52e7a2c156488d5 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -390,17 +390,20 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
       }
       printf("\n");*/
     encoder_implemparams_t impp;
-    impp.n_segments=harq_process->C;
-    impp.macro_num=0;
-    impp.tinput  = NULL;
-    impp.tprep   = NULL;
-    impp.tparity = NULL;
-    impp.toutput = NULL;
+    impp.n_segments = harq_process->C;
+    impp.tinput     = NULL;
+    impp.tprep      = NULL;
+    impp.tparity    = NULL;
+    impp.toutput    = NULL;
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
-    
-    nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,&impp);
-    
+
+    for(int j = 0; j < (harq_process->C/8 + 1); j++)
+    {
+      impp.macro_num = j;
+      nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,&impp);
+    }
+
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT);
 
     //stop_meas(te_stats);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index cf0fc716f91d31624d46cf86654467c3117a7ca0..4ac1c47b02f5b48d39ce87ce41c0ea7e512e2ee0 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -560,7 +560,6 @@ void set_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change
 {
   /* set new value according to rate_change */
   frame_parms_ue->ofdm_symbol_size = (frame_parms_ue->ofdm_symbol_size / rate_change);
-  frame_parms_ue->samples_per_tti = (frame_parms_ue->samples_per_tti / rate_change);
   frame_parms_ue->samples_per_subframe = (frame_parms_ue->samples_per_subframe / rate_change);
 
   free_context_pss_nr();
@@ -588,7 +587,6 @@ void set_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change
 void restore_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change)
 {
   frame_parms_ue->ofdm_symbol_size = frame_parms_ue->ofdm_symbol_size * rate_change;
-  frame_parms_ue->samples_per_tti = frame_parms_ue->samples_per_tti * rate_change;
   frame_parms_ue->samples_per_subframe = frame_parms_ue->samples_per_subframe * rate_change;
 
   free_context_pss_nr();
@@ -620,8 +618,6 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r
   NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
   int samples_for_frame = 2*frame_parms->samples_per_frame;
 
-  AssertFatal(frame_parms->samples_per_tti > 3839,"Illegal samples_per_tti %d\n",frame_parms->samples_per_tti);
-
 #if TEST_SYNCHRO_TIMING_PSS
 
   opp_enabled = 1;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
index aba3c12636e3a675aa0c4b9ed4bcf2e9b09bba9a..fafe3b287323e6af83e420f8eca608aacc69fdb4 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
@@ -278,7 +278,7 @@ int32_t generate_srs_nr(SRS_ResourceSet_t *p_srs_resource_set,
           n_SRS = l/R;
         }
         else {
-          int8_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * frame_parms->ttis_per_subframe;
+          int8_t N_slot_frame = frame_parms->slots_per_frame;
           n_SRS = ((N_slot_frame*frame_number + slot_number - T_offset)/T_SRS)*(N_symb_SRS/R)+(l/R);
         }
 
@@ -399,7 +399,7 @@ int is_srs_period_nr(SRS_Resource_t *p_SRS_Resource, NR_DL_FRAME_PARMS *frame_pa
     return (-1);
   }
 
-  int16_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * frame_parms->ttis_per_subframe;
+  int16_t N_slot_frame = frame_parms->slots_per_frame;
   if ((N_slot_frame*frame_tx + slot_tx - T_offset)%T_SRS == 0) {
     return (0);
   }
diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h
index 15300426f3e12768596b309edd6304eac126daf4..b465a51a2addf00ebc78da6e0c1d5f5cc079100c 100644
--- a/openair1/PHY/defs_RU.h
+++ b/openair1/PHY/defs_RU.h
@@ -624,6 +624,8 @@ typedef struct RU_t_s {
   int wakeup_L1_sleep_cnt_max;
   /// DL IF frequency in Hz
   uint64_t if_frequency;
+  /// UL IF frequency offset to DL IF frequency in Hz
+  int if_freq_offset;
 } RU_t;
 
 
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index b07582b45a1024d11db24fc5372137cb6b6188a0..e5678f894d7c0faa7399af59770a0fb71df45bc6 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -301,8 +301,6 @@ struct NR_DL_FRAME_PARMS {
   uint32_t samples_per_slot0;
   /// Number of samples in other slots of the subframe
   uint32_t samples_per_slotN0;
-  /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL)
-  uint16_t symbols_per_tti;
   /// Number of samples in a radio frame
   uint32_t samples_per_frame;
   /// Number of samples in a subframe without CP
@@ -311,15 +309,8 @@ struct NR_DL_FRAME_PARMS {
   uint32_t samples_per_slot_wCP;
   /// Number of samples in a radio frame without CP
   uint32_t samples_per_frame_wCP;
-  /// Number of samples in a tti (same as subrame in LTE, slot in NR)
-  uint32_t samples_per_tti;
   /// NR numerology index [0..5] as specified in 38.211 Section 4 (mu). 0=15khZ SCS, 1=30khZ, 2=60kHz, etc
   uint8_t numerology_index;
-  /// NR number of ttis per subframe deduced from numerology (cf 38.211): 1, 2, 4, 8(not supported),16(not supported),32(not supported)
-  uint8_t ttis_per_subframe;
-  /// NR number of slots per tti . Assumption only 2 Slot per TTI is supported (Slot Config 1 in 38.211)
-  uint8_t slots_per_tti;
-//#endif
   /// Number of Physical transmit antennas in node
   uint8_t nb_antennas_tx;
   /// Number of Receive antennas in node
diff --git a/openair1/PHY/phy_extern_nr_ue.h b/openair1/PHY/phy_extern_nr_ue.h
index 2f2a0427f41484531b043887c89a14e4d3e10e95..e06b0c913a68a99715f8a003da939eeadf95b6ba 100644
--- a/openair1/PHY/phy_extern_nr_ue.h
+++ b/openair1/PHY/phy_extern_nr_ue.h
@@ -32,7 +32,8 @@ extern char  fmageren_name2[512];
 extern unsigned int RX_DMA_BUFFER[4][NB_ANTENNAS_RX];
 extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
 
-//#include "PHY/LTE_TRANSPORT/transport_extern.h"
+extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
+extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
 
 extern const short conjugate[8],conjugate2[8];
 extern int number_of_cards;
diff --git a/openair1/PHY/thread_NR_UE.h b/openair1/PHY/thread_NR_UE.h
index 94271ed55d339383920d3dc0acef0db282ebfd10..487f6f3d1f3746d901a87c44a18e1e59359d4e16 100644
--- a/openair1/PHY/thread_NR_UE.h
+++ b/openair1/PHY/thread_NR_UE.h
@@ -11,9 +11,9 @@ typedef struct {
   /// timestamp transmitted to HW
   openair0_timestamp timestamp_tx;
   //#ifdef UE_NR_PHY_DEMO
-  /// NR TTI index within subframe_tx [0 .. ttis_per_subframe - 1] to act upon for transmission
+  /// NR TTI index within subframe_tx [0 .. slots_per_subframe - 1] to act upon for transmission
   int nr_tti_tx;
-  /// NR TTI index within subframe_rx [0 .. ttis_per_subframe - 1] to act upon for reception
+  /// NR TTI index within subframe_rx [0 .. slots_per_subframe - 1] to act upon for reception
   int nr_tti_rx;
   /// NR slot index within frame_tx [0 .. slots_per_frame - 1] to act upon for transmission
   int nr_slot_tx;
diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c
index 9d34f496b3fcd6e454ed5520ac9a2a065bee562f..f91ec73e5d887265d6d9cd10af609b1a9188fe27 100644
--- a/openair1/SCHED_NR/phy_frame_config_nr.c
+++ b/openair1/SCHED_NR/phy_frame_config_nr.c
@@ -252,7 +252,7 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) {
   while(p_current_TDD_UL_DL_SlotConfig != NULL) {
     int slot_index = p_current_TDD_UL_DL_SlotConfig->slotIndex;
 
-    if (slot_index < TDD_CONFIG_NB_FRAMES*(frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME)) {
+    if (slot_index < TDD_CONFIG_NB_FRAMES * frame_parms->slots_per_frame) {
       if (p_current_TDD_UL_DL_SlotConfig->nrofDownlinkSymbols != 0) {
         if (p_current_TDD_UL_DL_SlotConfig->nrofDownlinkSymbols == NR_TDD_SET_ALL_SYMBOLS) {
           if (p_current_TDD_UL_DL_SlotConfig->nrofUplinkSymbols == 0) {
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index e985bb74d8160808ca4eac94f6345ff6bad362db..f2ff272409beb6be77af01b16ec6694b7a361582 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -532,7 +532,9 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1);
   LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
 
-  fill_ul_rb_mask(gNB, frame_rx, slot_rx);
+  if (gNB->frame_parms.frame_type == TDD)
+    fill_ul_rb_mask(gNB, frame_rx, slot_rx);
+
   gNB_I0_measurements(gNB);
 
   for (int i=0;i<NUMBER_OF_NR_PUCCH_MAX;i++){
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 2df917d6769781a883e82583b4911e1f53c4c314..de7c4535f00be4593cceae064227d9b4a88c8922 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -154,8 +154,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
             ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
 
-            if (scheduled_response->tx_request){ // TBR todo here it should loop through the number of tx pdus
-              fapi_nr_tx_request_body_t *tx_req_body = scheduled_response->tx_request->tx_request_body;
+            if (scheduled_response->tx_request){ 
+              fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[i];
 
               memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length);
 
diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c
index 3c3017d658735efce65477680d2cb5f930173975..1a5afac5b5865e41cfccc92189a5a88b8f3066e5 100644
--- a/openair1/SCHED_NR_UE/harq_nr.c
+++ b/openair1/SCHED_NR_UE/harq_nr.c
@@ -114,7 +114,7 @@
 *********************************************************************/
 
 void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted,
-		                   NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t nr_tti_rx, uint8_t tx_offset)
+		                   NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t slot, uint8_t tx_offset)
 {
   if (nr_dci_info_extracted->identifier_dci_formats == DL_DCI) {
 
@@ -124,14 +124,14 @@ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_i
 
     dl_harq->harq_ack.vDAI_DL = nr_dci_info_extracted->dai+1;
     dl_harq->harq_ack.pucch_resource_indicator = nr_dci_info_extracted->pucch_resource_ind;
-    dl_harq->harq_ack.slot_for_feedback_ack = (nr_tti_rx + nr_dci_info_extracted->pdsch_to_harq_feedback_time_ind)%ue->frame_parms.ttis_per_subframe;
+    dl_harq->harq_ack.slot_for_feedback_ack = (slot + nr_dci_info_extracted->pdsch_to_harq_feedback_time_ind)%ue->frame_parms.slots_per_subframe;
     dl_harq->harq_ack.harq_id = nr_dci_info_extracted->harq_process_number;
     dl_harq->harq_ack.rx_status = downlink_harq_process(dl_harq, dlsch[0]->current_harq_pid, nr_dci_info_extracted->ndi, dlsch[0]->rnti_type);
   }
   else if (nr_dci_info_extracted->identifier_dci_formats == UL_DCI) {
 
 	/* store harq id for which pusch should be transmitted at rx_slot + tx_offset */
-	set_tx_harq_id(ulsch, nr_dci_info_extracted->harq_process_number, (nr_tti_rx + tx_offset)%ue->frame_parms.ttis_per_subframe);
+	set_tx_harq_id(ulsch, nr_dci_info_extracted->harq_process_number, (slot + tx_offset)%ue->frame_parms.slots_per_subframe);
     ulsch->harq_processes[nr_dci_info_extracted->harq_process_number]->tx_status = uplink_harq_process(ulsch, nr_dci_info_extracted->harq_process_number, nr_dci_info_extracted->ndi, ulsch->rnti_type);
   }
 }
diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
index b51c8afbb0a19e38d8ee1b44cab4b512fbb4270c..b1deb9191bbd90a32f226f6ab7ec9e49e1fe697a 100644
--- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
@@ -169,7 +169,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue,
   //int K_PUCCH = 0;
   if (O_ACK != 0) {
     /* it assumes that PDCCH is in the first symbol of receive slot FFS TDDO NR */
-    //int slots_gap = (proc->nr_tti_tx > proc->nr_tti_rx ? (proc->nr_tti_tx - proc->nr_tti_rx - 1) : ((proc->nr_tti_tx + ue->frame_parms.ttis_per_subframe) - proc->nr_tti_rx - 1));
+    //int slots_gap = (proc->nr_tti_tx > proc->nr_tti_rx ? (proc->nr_tti_tx - proc->nr_tti_rx - 1) : ((proc->nr_tti_tx + ue->frame_parms.slots_per_subframe) - proc->nr_tti_rx - 1));
     //K_PUCCH = (slots_gap * (ue->frame_parms.symbols_per_tti)) - 1;
   }
   else {
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
index 85e315ecdddc56544d1326659d23f27bfed9846a..a4ff68dd869eb5f926c49990bb3dc4faa481c726 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
@@ -238,7 +238,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
 
   /* update current context */
 
-  int subframe_number = (proc->nr_tti_rx)/(ue->frame_parms.slots_per_subframe);//ttis_per_subframe);
+  int subframe_number = proc->nr_slot_rx / ue->frame_parms.slots_per_subframe;
   nb_pucch_format_4_in_subframes[subframe_number] = 0; /* reset pucch format 4 counter at current rx position */
 
   int dl_harq_pid = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid;
@@ -490,7 +490,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
       //}
       nb_symbols = nb_symbols_excluding_dmrs[nb_symbols_total-4][index_additional_dmrs][index_hopping];
       nb_of_prbs = 1;
-      subframe_number = nr_tti_tx/(ue->frame_parms.slots_per_subframe);//ttis_per_subframe);
+      subframe_number = nr_tti_tx / ue->frame_parms.slots_per_subframe;
       nb_pucch_format_4_in_subframes[subframe_number]++; /* increment number of transmit pucch 4 in current subframe */
       NR_TST_PHY_PRINTF("PUCCH Number of pucch format 4 in subframe %d is %d \n", subframe_number, nb_pucch_format_4_in_subframes[subframe_number]);
       N_sc_ctrl_RB = N_SC_RB/(nb_pucch_format_4_in_subframes[subframe_number]);
@@ -1277,7 +1277,7 @@ int trigger_periodic_scheduling_request(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_n
     return (1); /* period is slot */
   }
 
-  int16_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * ue->frame_parms.slots_per_subframe;//ttis_per_subframe;
+  int16_t N_slot_frame = ue->frame_parms.slots_per_frame;
   if (((proc->frame_tx * N_slot_frame) + proc->nr_tti_tx - SR_offset)%SR_periodicity == 0) {
     return (1);
   }
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index c5ad4467afbb2c47aebe865cd0251507c02c3422..fc02cf5ece8024f0f18c1d2b068f989eb34df45c 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -116,9 +116,9 @@ int main(int argc, char **argv){
   int i, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1;
   int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0;
   uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0;
-  uint8_t frame = 1, subframe = 9, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, num_root_sequences = 16, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol;
+  uint8_t frame = 1, subframe = 9, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol;
   uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1;
-  uint32_t tx_lev = 10000, prach_errors = 0, samp_count; //,tx_lev_dB;
+  uint32_t tx_lev = 10000, prach_errors = 0; //,tx_lev_dB;
   uint64_t SSB_positions = 0x01, absoluteFrequencyPointA = 640000;
   uint16_t RA_sfn_index;
   uint8_t N_RA_slot;
@@ -705,7 +705,7 @@ int main(int argc, char **argv){
         //  printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB);
 
         if (awgn_flag == 0) {
-          multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_tti<<1, 0);
+          multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_frame, 0);
         }
 
         if (n_frames==1) {
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 2aafaa107eb9899703afc6560a5cecaea76c6467..d924f7ef3484d408c141df627403b1848d5150ef 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -671,8 +671,7 @@ int main(int argc, char **argv)
   nr_scheduled_response_t scheduled_response;
   fapi_nr_ul_config_request_t ul_config;
   fapi_nr_tx_request_t tx_req;
-  fapi_nr_tx_request_body_t tx_req_body;
-
+  
   uint8_t ptrs_mcs1 = 2;
   uint8_t ptrs_mcs2 = 4;
   uint8_t ptrs_mcs3 = 10;
@@ -908,16 +907,15 @@ int main(int argc, char **argv)
       scheduled_response.dl_config = NULL;
       scheduled_response.ul_config = &ul_config;
       scheduled_response.tx_request = &tx_req;
-      scheduled_response.tx_request->tx_request_body = &tx_req_body;
-
+      
       // Config UL TX PDU
       tx_req.slot = slot;
       tx_req.sfn = frame;
       // tx_req->tx_config // TbD
       tx_req.number_of_pdus = 1;
-      tx_req_body.pdu_length = TBS/8;
-      tx_req_body.pdu_index = 0;
-      tx_req_body.pdu = &ulsch_input_buffer[0];
+      tx_req.tx_request_body[0].pdu_length = TBS/8;
+      tx_req.tx_request_body[0].pdu_index = 0;
+      tx_req.tx_request_body[0].pdu = &ulsch_input_buffer[0];
 
       ul_config.slot = slot;
       ul_config.number_pdus = 1;
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c
index 1ab935fcae92c008b42b94a64beda8cac9733d55..c88c261667de88bf56aebb288a4090029e42d84d 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c
@@ -51,16 +51,16 @@
 
 void display_frame_configuration(NR_DL_FRAME_PARMS *frame_parms) {
 
-  printf("\nTdd configuration tti %d downlink %d uplink %d period %d \n", frame_parms->ttis_per_subframe, frame_parms->p_tdd_UL_DL_Configuration->nrofDownlinkSlots,
+  printf("\nTdd configuration tti %d downlink %d uplink %d period %d \n", frame_parms->slots_per_subframe, frame_parms->p_tdd_UL_DL_Configuration->nrofDownlinkSlots,
       frame_parms->p_tdd_UL_DL_Configuration->nrofUplinkSlots, frame_parms->p_tdd_UL_DL_Configuration->dl_UL_TransmissionPeriodicity);
 
   int k = (TDD_CONFIG_NB_FRAMES * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) - 1; //19;
   int tti = 0;
-  for (int j = 0; j < TDD_CONFIG_NB_FRAMES * frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; j++) {
+  for (int j = 0; j < TDD_CONFIG_NB_FRAMES * frame_parms->slots_per_frame; j++) {
     int frame = 0;
     if (j != 0) {
-      frame = (frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME)/j;
-      tti = (j)%(frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME);
+      frame = j / frame_parms->slots_per_frame;
+      tti = j % frame_parms->slots_per_frame;
     }
     else {
       frame = 0;
@@ -99,9 +99,10 @@ void display_frame_configuration(NR_DL_FRAME_PARMS *frame_parms) {
 *
 *********************************************************************/
 
-void set_tti_test(NR_DL_FRAME_PARMS *frame_parms, int ttis_per_subframe)
+void set_tti_test(NR_DL_FRAME_PARMS *frame_parms, int slots_per_subframe)
 {
-  frame_parms->ttis_per_subframe = ttis_per_subframe;
+  frame_parms->slots_per_subframe = slots_per_subframe;
+  frame_parms->slots_per_frame    = slots_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
 }
 
 /*******************************************************************
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
index ff15dec6a47b9327a5dad7d37a57385db43f2cf9..403a035c963818471efc060abda423cfb16f9b27 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
@@ -182,7 +182,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr
   /* set a tx slot with no ack */
   NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack;
 
-  harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+  harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
 
   printf("\n  => Test : Error due to acknownlegment not set \n");
 
@@ -300,7 +300,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_
   harq_status->send_harq_status = 1;
   harq_status->vDAI_DL = 2;
   harq_status->ack = DL_ACK;
-  harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+  harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
 
   printf("\n  => Test : PUCCH format from common config in dedicated mode: two positive downlink ACKnowledgments \n");
 
@@ -567,7 +567,7 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id,
 
   harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack;
 
-  harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+  harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
   harq_status->send_harq_status = 1;
   harq_status->vDAI_DL = 1;
   harq_status->ack = DL_ACK;
@@ -586,7 +586,7 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id,
 
     NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack;
 
-    harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+    harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
     harq_status->send_harq_status = 1;
     harq_status->vDAI_DL = i+1;
     harq_status->ack = DL_ACK;
@@ -620,7 +620,7 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id,
 
     NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack;
 
-    harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+    harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
     harq_status->send_harq_status = 1;
     harq_status->vDAI_DL = i+1;
     harq_status->ack = DL_ACK;
@@ -684,7 +684,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE
 
       NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack;
 
-      harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+      harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
       harq_status->send_harq_status = 1;
       harq_status->vDAI_DL = i+1;
       harq_status->ack = DL_ACK;
@@ -727,7 +727,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE
 
       NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack;
 
-      harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+      harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
       harq_status->send_harq_status = 1;
       harq_status->vDAI_DL = i+1;
       harq_status->ack = DL_ACK;
@@ -761,7 +761,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE
 
       NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack;
 
-      harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+      harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
       harq_status->send_harq_status = 1;
       harq_status->vDAI_DL = i+1;
       harq_status->ack = DL_ACK;
@@ -980,7 +980,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro
 
   harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack;
 
-  harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+  harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
   harq_status->send_harq_status = 1;
   harq_status->vDAI_DL = 1;
   harq_status->ack = DL_ACK;
@@ -1019,7 +1019,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro
 
   harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_SECOND].harq_ack;
 
-  harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+  harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
   harq_status->send_harq_status = 1;
   harq_status->vDAI_DL = 2;
   harq_status->ack = DL_ACK;
@@ -1094,7 +1094,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc)
 
   harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack;
 
-  harq_status->slot_for_feedback_ack  = proc->nr_tti_tx;
+  harq_status->slot_for_feedback_ack  = proc->nr_slot_tx;
   harq_status->send_harq_status = 1;
   harq_status->vDAI_DL = 1;
   harq_status->ack = DL_ACK;
@@ -1168,9 +1168,13 @@ int test_pucch(PHY_VARS_NR_UE *ue)
     assert(0);
   }
 
-  proc->frame_tx = 0;
-  proc->nr_tti_rx = 0;
-  proc->nr_tti_tx = (proc->nr_tti_rx + NR_UE_CAPABILITY_SLOT_RX_TO_TX)%(ue->frame_parms.ttis_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME);
+  proc->frame_rx   = 0;
+  proc->nr_slot_rx = 0;
+  proc->nr_tti_rx  = 0;
+
+  proc->frame_tx   = proc->frame_rx + (proc->nr_slot_rx + NR_UE_CAPABILITY_SLOT_RX_TO_TX) / ue->frame_parms.slots_per_frame;
+  proc->nr_slot_tx = (proc->nr_slot_rx + NR_UE_CAPABILITY_SLOT_RX_TO_TX) % ue->frame_parms.slots_per_frame;
+  proc->nr_tti_tx  = proc->nr_slot_tx % ue->frame_parms.slots_per_subframe;
 
   init_pucch_power_configuration( ue, gNB_id);
 
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c
index 0bbe7cac7fe4ef0d8fe7cd5add575f2cd2239822..8451e78fd6ae56ecc0b569620f5247b38cc25dfa 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c
@@ -223,12 +223,13 @@ int test_srs_periodicity(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc)
       }
       printf("srs period %d offset %d \n", srs_current_period, p_srs_resource->SRS_Offset);
 
-      int duration = (10 * srs_current_period)/(NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->ttis_per_subframe);
+      int duration = (10 * srs_current_period) / frame_parms->slots_per_frame;
 
       for (int frame_tx = 0; frame_tx < duration; frame_tx++) {
-        for (int slot_tx = 0; slot_tx < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->ttis_per_subframe); slot_tx++) {
-          proc->frame_tx = frame_tx;
-          proc->nr_tti_tx = slot_tx;
+        for (int slot_tx = 0; slot_tx < frame_parms->slots_per_frame; slot_tx++) {
+          proc->frame_tx   = frame_tx;
+          proc->nr_slot_tx = slot_tx;
+          proc->nr_tti_tx  = slot_tx % frame_parms->slots_per_subframe;
           if (ue_srs_procedure_nr( ue, proc, 0) == 0)  {
             printf("test_srs_periodicity srs at frame %d slot %d \n", frame_tx, slot_tx);
           }
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index d2372c944c945611155320ed3c2912ec119a1716..24240e5ae149491aa6be7d7f47b56d93a7143305 100644
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -96,6 +96,7 @@ typedef enum {
 #define CONFIG_STRING_RU_OTA_SYNC_ENABLE          "ota_sync_enabled"
 #define CONFIG_STRING_RU_BF_WEIGHTS_LIST          "bf_weights"
 #define CONFIG_STRING_RU_IF_FREQUENCY             "if_freq"
+#define CONFIG_STRING_RU_IF_FREQ_OFFSET           "if_offset"
 
 #define RU_LOCAL_IF_NAME_IDX          0
 #define RU_LOCAL_ADDRESS_IDX          1
@@ -124,6 +125,7 @@ typedef enum {
 #define RU_OTA_SYNC_ENABLE_IDX        24
 #define RU_BF_WEIGHTS_LIST_IDX        25
 #define RU_IF_FREQUENCY               26
+#define RU_IF_FREQ_OFFSET             27
 
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            RU configuration parameters                                                                  */
@@ -157,6 +159,7 @@ typedef enum {
     {CONFIG_STRING_RU_OTA_SYNC_ENABLE,             NULL,       0,       strptr:NULL,     defstrval:"no",          TYPE_STRING,      0}, \
     {CONFIG_STRING_RU_BF_WEIGHTS_LIST,             NULL,       0,       iptr:NULL,       defintarrayval:DEFBFW,   TYPE_INTARRAY,    0}, \
     {CONFIG_STRING_RU_IF_FREQUENCY,                NULL,       0,       u64ptr:NULL,     defuintval:0,            TYPE_UINT64,      0}, \
+    {CONFIG_STRING_RU_IF_FREQ_OFFSET,              NULL,       0,       iptr:NULL,     defintval:0,             TYPE_INT,         0}, \
   }
 
 /*---------------------------------------------------------------------------------------------------------------------------------------*/
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index bfe322b12216e963a83690a35362d18aac14c8d5..33b5101ef39292e7c714bc165d51d4fb456213cf 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -49,6 +49,7 @@ uint16_t NCS_restricted_TypeB_delta_f_RA_5[14]   = {36,57,60,63,65,68,71,77,81,8
 uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69};
 
 const char *prachfmt[]={"0","1","2","3", "A1","A2","A3","B1","B4","C0","C2","A1/B1","A2/B2","A3/B3"};
+const char *duplex_mode[]={"FDD","TDD"};
 
 uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) {
 
@@ -1418,7 +1419,7 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
     else {
       r = L_ra/NCS;
       found_sequences = (nb_preambles/r) + (nb_preambles%r!=0); //ceil(nb_preambles/r)
-      printf(" found_sequences %u\n", found_sequences);
+      LOG_D(MAC, "Computing NR root sequences: found %u sequences\n", found_sequences);
       return (found_sequences);
     }
   }
@@ -1456,12 +1457,17 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
         AssertFatal(1==0,"Procedure to find nb of sequences for restricted type B not implemented yet");
       }
     }
-    printf(" found_sequences %u\n", found_sequences);
+    LOG_D(MAC, "Computing NR root sequences: found %u sequences\n", found_sequences);
     return found_sequences;
   }
 }
 
-
+// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
+// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
+// Notes:
+// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL
+// - Frequencies are expressed in KHz
+// - col: NR_band ul_min  ul_max  dl_min  dl_max  step  N_OFFs_DL  deltaf_raster
 nr_bandentry_t nr_bandtable[] = {
   {1,   1920000, 1980000, 2110000, 2170000, 20, 422000, 100},
   {2,   1850000, 1910000, 1930000, 1990000, 20, 386000, 100},
@@ -1470,17 +1476,27 @@ nr_bandentry_t nr_bandtable[] = {
   {7,   2500000, 2570000, 2620000, 2690000, 20, 524000, 100},
   {8,    880000,  915000,  925000,  960000, 20, 185000, 100},
   {12,   698000,  716000,  729000,  746000, 20, 145800, 100},
+  {14,   788000,  798000,  758000,  768000, 20, 151600, 100},
+  {18,   815000,  830000,  860000,  875000, 20, 172000, 100},
   {20,   832000,  862000,  791000,  821000, 20, 158200, 100},
   {25,  1850000, 1915000, 1930000, 1995000, 20, 386000, 100},
+  {26,   814000,  849000,  859000,  894000, 20, 171800, 100},
   {28,   703000,  758000,  758000,  813000, 20, 151600, 100},
+  {29,      000,     000,  717000,  728000, 20, 143400, 100},
+  {30,  2305000, 2315000, 2350000, 2360000, 20, 470000, 100},
   {34,  2010000, 2025000, 2010000, 2025000, 20, 402000, 100},
   {38,  2570000, 2620000, 2570000, 2630000, 20, 514000, 100},
   {39,  1880000, 1920000, 1880000, 1920000, 20, 376000, 100},
   {40,  2300000, 2400000, 2300000, 2400000, 20, 460000, 100},
   {41,  2496000, 2690000, 2496000, 2690000,  3, 499200,  15},
   {41,  2496000, 2690000, 2496000, 2690000,  6, 499200,  30},
+  {47,  5855000, 5925000, 5855000, 5925000,  1, 790334,  15},
+  //{48,  3550000, 3700000, 3550000, 3700000,  1, 636667,  15},
+  //{48,  3550000, 3700000, 3550000, 3700000,  2, 636668,  30},
   {50,  1432000, 1517000, 1432000, 1517000, 20, 286400, 100},
   {51,  1427000, 1432000, 1427000, 1432000, 20, 285400, 100},
+  {53,  2483500, 2495000, 2483500, 2495000, 20, 496700, 100},
+  {65,  1920000, 2010000, 2110000, 2200000, 20, 422000, 100},
   {66,  1710000, 1780000, 2110000, 2200000, 20, 422000, 100},
   {70,  1695000, 1710000, 1995000, 2020000, 20, 399000, 100},
   {71,   663000,  698000,  617000,  652000, 20, 123400, 100},
@@ -1499,6 +1515,15 @@ nr_bandentry_t nr_bandtable[] = {
   {83,   703000,  748000,     000,     000, 20, 140600, 100},
   {84,  1920000, 1980000,     000,     000, 20, 384000, 100},
   {86,  1710000, 1785000,     000,     000, 20, 342000, 100},
+  {89,   824000,  849000,     000,     000, 20, 342000, 100},
+  {90,  2496000, 2690000, 2496000, 2690000, 3,  499200,  15},
+  {90,  2496000, 2690000, 2496000, 2690000, 6,  499200,  30},
+  {90,  2496000, 2690000, 2496000, 2690000, 20, 499200, 100},
+  {91,   832000,  862000, 1427000, 1432000, 20, 285400, 100},
+  {92,   832000,  862000, 1432000, 1517000, 20, 286400, 100},
+  {93,   880000,  915000, 1427000, 1432000, 20, 285400, 100},
+  {94,   880000,  915000, 1432000, 1517000, 20, 286400, 100},
+  {95,  2010000, 2025000,     000,     000, 20, 402000, 100},
   {257,26500020,29500000,26500020,29500000,  1,2054166,  60},
   {257,26500080,29500000,26500080,29500000,  2,2054167, 120},
   {258,24250080,27500000,24250080,27500000,  1,2016667,  60},
@@ -1552,46 +1577,58 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = {
 
 #define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t))
 
-void get_band(uint64_t downlink_frequency,
-              uint16_t *current_band,
-              int32_t *current_offset,
-              lte_frame_type_t *current_type)
-{
-    int ind;
-    uint64_t center_frequency_khz;
-    uint64_t center_freq_diff_khz;
-    uint64_t dl_freq_khz = downlink_frequency/1000;
+// Returns the corresponding row index of the NR table
+int get_nr_table_idx(int nr_bandP, uint8_t scs_index){
 
-    center_freq_diff_khz = 999999999999999999; // 2^64
-    *current_band = 0;
+  int i, j;
+  int scs_khz = 15 << scs_index;
+  int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95};
+  size_t s = sizeof(supplementary_bands)/sizeof(supplementary_bands[0]);
 
-    for ( ind=0;
-          ind < sizeof(nr_bandtable) / sizeof(nr_bandtable[0]);
-          ind++) {
+  for(j = 0; j < s; j++){
+    if (nr_bandP == supplementary_bands[j])
+      AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]);
+  }
 
-      LOG_I(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min,nr_bandtable[ind].ul_min);
+  AssertFatal(nr_bandP <= nr_bandtable[NR_BANDTABLE_SIZE-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[NR_BANDTABLE_SIZE-1].band);
+  for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++);
 
-      if ( nr_bandtable[ind].dl_min <= dl_freq_khz && nr_bandtable[ind].dl_max >= dl_freq_khz ) {
+  // selection of correct Deltaf raster according to SCS
+  if ((nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz))
+    i++;
 
-        center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min)/2;
-        if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){
-          *current_band = nr_bandtable[ind].band;
-	  *current_offset = (nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min)*1000;
-          center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz);
+  LOG_D(PHY, "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", i, nr_bandtable[i].band, nr_bandtable[i].dl_min,nr_bandtable[i].ul_min);
 
-	  if (*current_offset == 0)
-	    *current_type = TDD;
-	  else
-	    *current_type = FDD;
-        }
-      }
-    }
+  return i;
+
+}
+
+// Computes the duplex spacing (either positive or negative) in KHz
+void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex){
+
+  int nr_table_idx = get_nr_table_idx(nr_bandP, scs_index);
 
-    LOG_I( PHY, "DL frequency %"PRIu64": band %d, frame_type %d, UL frequency %"PRIu64"\n",
-         downlink_frequency, *current_band, *current_type, downlink_frequency+*current_offset);
+  *delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min);
+
+  LOG_D(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", *delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band);
+
+}
+
+void get_frame_type(uint16_t current_band,
+                    uint8_t scs_index,
+                    lte_frame_type_t *current_type){
+
+  int32_t current_offset;
+  get_delta_duplex(current_band, scs_index, &current_offset);
+
+  current_offset *= 1000;
+  if (current_offset == 0)
+    *current_type = TDD;
+  else
+    *current_type = FDD;
+
+  LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[*current_type], current_offset);
 
-    AssertFatal(*current_band != 0,
-	    "Can't find EUTRA band for frequency %lu\n", downlink_frequency);
 }
 
 uint16_t config_bandwidth(int mu, int nb_rb, int nr_band)
@@ -1707,6 +1744,15 @@ uint16_t config_bandwidth(int mu, int nb_rb, int nr_band)
 
 }
 
+void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs){
+
+  uint32_t delta_arfcn = nrarfcn - N_OFFs;
+
+  if(delta_arfcn%(nr_bandtable[i].step_size)!=0)
+    AssertFatal(1 == 0, "nrarfcn %u is not on the channel raster for step size %lu", nrarfcn, nr_bandtable[i].step_size);
+
+}
+
 uint32_t to_nrarfcn(int nr_bandP,
                     uint64_t dl_CarrierFreq,
                     uint8_t scs_index,
@@ -1714,17 +1760,10 @@ uint32_t to_nrarfcn(int nr_bandP,
 {
   uint64_t dl_CarrierFreq_by_1k = dl_CarrierFreq / 1000;
   int bw_kHz = bw / 1000;
-  int scs_khz = 15<<scs_index;
-  int i;
-  uint32_t nrarfcn, delta_arfcn;
+  uint32_t nrarfcn;
+  int i = get_nr_table_idx(nr_bandP, scs_index);
 
   LOG_I(MAC,"Searching for nr band %d DL Carrier frequency %llu bw %u\n",nr_bandP,(long long unsigned int)dl_CarrierFreq,bw);
-  AssertFatal(nr_bandP <= 261, "nr_band %d > 260\n", nr_bandP);
-  for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++);
-
-  // selection of correct Deltaf raster according to SCS
-  if ( (nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz))
-   i++;
 
   AssertFatal(dl_CarrierFreq_by_1k >= nr_bandtable[i].dl_min,
         "Band %d, bw %u : DL carrier frequency %llu kHz < %llu\n",
@@ -1753,70 +1792,73 @@ uint32_t to_nrarfcn(int nr_bandP,
   // This is equation before Table 5.4.2.1-1 in 38101-1-f30
   // F_REF=F_REF_Offs + deltaF_Global(N_REF-NREF_REF_Offs)
   nrarfcn =  (((dl_CarrierFreq_by_1k - F_REF_Offs_khz)/deltaFglobal)+N_REF_Offs);
-
-  delta_arfcn = nrarfcn - nr_bandtable[i].N_OFFs_DL;
-  if(delta_arfcn%(nr_bandtable[i].step_size)!=0)
-    AssertFatal(1==0,"dl_CarrierFreq %lu corresponds to %u which is not on the raster for step size %lu",
-                dl_CarrierFreq,nrarfcn,nr_bandtable[i].step_size);
+  get_delta_arfcn(i, nrarfcn, nr_bandtable[i].N_OFFs_DL);
 
   return nrarfcn;
 }
 
-
+// This function computes the RF reference frequency from the NR-ARFCN according to 5.4.2.1 of 3GPP TS 38.104
+// this function applies to both DL and UL
 uint64_t from_nrarfcn(int nr_bandP,
                       uint8_t scs_index,
-                      uint32_t dl_nrarfcn)
+                      uint32_t nrarfcn)
 {
-  int i;
   int deltaFglobal = 5;
   uint32_t N_REF_Offs = 0;
   uint64_t F_REF_Offs_khz = 0;
-  int scs_khz = 15<<scs_index;
-  uint32_t delta_arfcn;
+  int32_t delta_duplex;
+  uint64_t N_OFFs, frequency, freq_min;
+  int i = get_nr_table_idx(nr_bandP, scs_index);
 
-  if (dl_nrarfcn > 599999 && dl_nrarfcn < 2016667) {
+  if (nrarfcn > 599999 && nrarfcn < 2016667) {
     deltaFglobal = 15;
     N_REF_Offs = 600000;
     F_REF_Offs_khz = 3000000;
   }
-  if (dl_nrarfcn > 2016666 && dl_nrarfcn < 3279166) {
+  if (nrarfcn > 2016666 && nrarfcn < 3279166) {
     deltaFglobal = 60; 
     N_REF_Offs = 2016667;
     F_REF_Offs_khz = 24250080;
   }
-  
-  AssertFatal(nr_bandP <= 261, "nr_band %d > 260\n", nr_bandP);
-  for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++);
-  AssertFatal(dl_nrarfcn>=nr_bandtable[i].N_OFFs_DL,"dl_nrarfcn %u < N_OFFs_DL[%d] %llu\n",dl_nrarfcn, nr_bandtable[i].band,(long long unsigned int)nr_bandtable[i].N_OFFs_DL);
- 
-  // selection of correct Deltaf raster according to SCS
-  if ( (nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz))
-   i++;
 
-  delta_arfcn = dl_nrarfcn - nr_bandtable[i].N_OFFs_DL;
-  if(delta_arfcn%(nr_bandtable[i].step_size)!=0)
-    AssertFatal(1==0,"dl_nrarfcn %u is not on the raster for step size %lu",dl_nrarfcn,nr_bandtable[i].step_size);
+  get_delta_duplex(nr_bandP, scs_index, &delta_duplex);
 
-  LOG_I(PHY,"Computing dl_frequency (arfcn %llu => %llu)\n",
-	(unsigned long long)dl_nrarfcn,
-	(unsigned long long)(1000*(F_REF_Offs_khz + (dl_nrarfcn - N_REF_Offs) * deltaFglobal)));
+  if (delta_duplex <= 0){ // DL band >= UL band
+    if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL
+      N_OFFs = nr_bandtable[i].N_OFFs_DL;
+      freq_min = nr_bandtable[i].dl_min;
+    } else {// is FDD UL
+      N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal;
+      freq_min = nr_bandtable[i].ul_min;
+    }
+  } else { // UL band > DL band
+    if (nrarfcn >= nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal){ // is FDD UL
+      N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal;
+      freq_min = nr_bandtable[i].ul_min;
+    } else { // is FDD DL
+      N_OFFs = nr_bandtable[i].N_OFFs_DL;
+      freq_min = nr_bandtable[i].dl_min;
+    }
+  }
 
-  return 1000*(F_REF_Offs_khz + (dl_nrarfcn - N_REF_Offs) * deltaFglobal);
-}
+  LOG_D(MAC, "Frequency from NR-ARFCN for N_OFFs %lu, duplex spacing %d KHz, deltaFglobal %d KHz\n", N_OFFs, delta_duplex, deltaFglobal);
 
+  AssertFatal(nrarfcn >= N_OFFs,"nrarfcn %u < N_OFFs[%d] %llu\n", nrarfcn, nr_bandtable[i].band, (long long unsigned int)N_OFFs);
+  get_delta_arfcn(i, nrarfcn, N_OFFs);
 
-int32_t get_nr_uldl_offset(int nr_bandP)
-{
-  int i;
+  frequency = 1000*(F_REF_Offs_khz + (nrarfcn - N_REF_Offs) * deltaFglobal);
 
-  for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++);
+  LOG_I(MAC, "Computing frequency (pointA %llu => %llu KHz (freq_min %llu KHz, NR band %d N_OFFs %llu))\n",
+    (unsigned long long)nrarfcn,
+    (unsigned long long)frequency/1000,
+    (unsigned long long)freq_min,
+    nr_bandP,
+    (unsigned long long)N_OFFs);
 
-  AssertFatal(i < NR_BANDTABLE_SIZE, "i %d >= BANDTABLE_SIZE %ld\n", i, NR_BANDTABLE_SIZE);
+  return frequency;
 
-  return (nr_bandtable[i].dl_min - nr_bandtable[i].ul_min);
 }
 
-
 void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
 		   int x_overhead,
                    uint8_t numdmrscdmgroupnodata,
@@ -1897,7 +1939,7 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
     case 0:
       if (Imcs > 28) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
-        Imcs = 28;
+        return 0;
       }
       return (Table_51311[Imcs][0]);
     break;
@@ -1905,7 +1947,7 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
     case 1:
       if (Imcs > 27) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
-        Imcs = 27;
+        return 0;
       }
       return (Table_51312[Imcs][0]);
     break;
@@ -1913,13 +1955,14 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
     case 2:
       if (Imcs > 28) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
-        Imcs = 28;
+        return 0;
       }
       return (Table_51313[Imcs][0]);
     break;
 
     default:
-      AssertFatal(0, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx);
+      LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx);
+      return 0;
   }
 }
 
@@ -1928,7 +1971,7 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
     case 0:
       if (Imcs > 28) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
-        Imcs = 28;
+        return 0;
       }
       return (Table_51311[Imcs][1]);
     break;
@@ -1936,7 +1979,7 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
     case 1:
       if (Imcs > 27) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
-        Imcs = 27;
+        return 0;
       }
       return (Table_51312[Imcs][1]);
     break;
@@ -1944,13 +1987,14 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
     case 2:
       if (Imcs > 28) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
-        Imcs = 28;
+        return 0;
       }
       return (Table_51313[Imcs][1]);
     break;
 
     default:
-      AssertFatal(0, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx);
+      LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx);
+      return 0;
   }
 }
 
@@ -1959,7 +2003,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
     case 0:
       if (Imcs > 28) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
-        Imcs = 28;
+        return 0;
       }
       return (Table_51311[Imcs][0]);
     break;
@@ -1967,7 +2011,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
     case 1:
       if (Imcs > 27) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
-        Imcs = 27;
+        return 0;
       }
       return (Table_51312[Imcs][0]);
     break;
@@ -1975,7 +2019,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
     case 2:
       if (Imcs > 28) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
-        Imcs = 28;
+        return 0;
       }
       return (Table_51313[Imcs][0]);
     break;
@@ -1983,7 +2027,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
     case 3:
       if (Imcs > 27) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs);
-        Imcs = 27;
+        return 0;
       }
       return (Table_61411[Imcs][0]);
     break;
@@ -1991,13 +2035,14 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
     case 4:
       if (Imcs > 27) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs);
-        Imcs = 27;
+        return 0;
       }
       return (Table_61412[Imcs][0]);
     break;
 
     default:
-      AssertFatal(0, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx);
+      LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx);
+      return 0;
   }
 }
 
@@ -2006,7 +2051,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
     case 0:
       if (Imcs > 28) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
-        Imcs = 28;
+        return 0;
       }
       return (Table_51311[Imcs][1]);
     break;
@@ -2014,7 +2059,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
     case 1:
       if (Imcs > 27) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
-        Imcs = 27;
+        return 0;
       }
       return (Table_51312[Imcs][1]);
     break;
@@ -2022,7 +2067,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
     case 2:
       if (Imcs > 28) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
-        Imcs = 28;
+        return 0;
       }
       return (Table_51313[Imcs][1]);
     break;
@@ -2030,7 +2075,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
     case 3:
       if (Imcs > 27) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs);
-        Imcs = 27;
+        return 0;
       }
       return (Table_61411[Imcs][1]);
     break;
@@ -2038,13 +2083,14 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
     case 4:
       if (Imcs > 27) {
         LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs);
-        Imcs = 27;
+        return 0;
       }
       return (Table_61412[Imcs][1]);
     break;
 
     default:
-      AssertFatal(0, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx);
+      LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx);
+      return 0;
   }
 }
 
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index f65e68a26f39628c38c855623b4c48d462949d17..f31723a7d660dd25ac4008a2aea0070d00d913e7 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -96,7 +96,9 @@ typedef enum {
 
 uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
 
-void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type);
+void get_frame_type(uint16_t nr_bandP, uint8_t scs_index, lte_frame_type_t *current_type);
+
+void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex);
 
 uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
 
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index d8236c0df23afa83cee46e19cebee43e3d00e03f..7f98af2453867c86bb18cc1196e539f5abad073e 100755
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -147,13 +147,14 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
   fapi_nr_config_request_t        *cfg = &mac->phy_config.config_req;
   NR_ServingCellConfigCommon_t    *scc = mac->scc;
   int i;
+  lte_frame_type_t frame_type;
 
   mac->phy_config.Mod_id = module_id;
   mac->phy_config.CC_id = cc_idP;
   
   // carrier config
 
-  LOG_I(MAC,"UE Config Common\n");  
+  LOG_I(MAC, "Entering UE Config Common\n");
 
   cfg->carrier_config.dl_bandwidth = config_bandwidth(scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
                                                       scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
@@ -200,15 +201,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
     }
   }
 
-  lte_frame_type_t frame_type;
-  uint16_t band;
-  int32_t offset;
-
-  get_band((uint64_t)(cfg->carrier_config.dl_frequency)*1000,
-           &band,
-           &offset,
-           &frame_type);
-
+  get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
 
   // cell config
 
@@ -259,8 +252,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
 		"scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n");
     cfg->tdd_table.tdd_period = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
   }
-  LOG_I(MAC,"Setting TDD configuration period to %d\n",cfg->tdd_table.tdd_period);
   if(cfg->cell_config.frame_duplex_type == TDD){
+    LOG_I(MAC,"Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period);
     int return_tdd = set_tdd_config_nr_ue(cfg,
 		     scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
                      scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index fdee0e76d435fcec588ab7c92c3b62a05441d1a7..e97695e20185bcf536363c833b360d326979437c 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -252,7 +252,7 @@ typedef struct {
   uint8_t generate_nr_prach;
 
   ////	FAPI-like interface message
-  fapi_nr_ul_config_request_t ul_config_request;
+  fapi_nr_ul_config_request_t *ul_config_request;
   fapi_nr_dl_config_request_t dl_config_request;
 
   ///     Interface module instances
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 3844695222c02dc24d8a55600867dd1ac95c0b3a..ab6a04750038034eb9ced4c8e88e9e8df72eca1a 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -119,8 +119,8 @@ uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP,
 
 int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe);
 
-int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format);
-int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index,fapi_nr_dci_indication_pdu_t *dci);
+int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format);
+int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
 
 uint32_t get_ssb_frame(uint32_t test);
 uint32_t get_ssb_slot(uint32_t ssb_index);
diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
index bae8e0d3c0d61df06759242036e5dacf1cfa8246..20e73073b9b605e80fcccad687953545944bf059 100644
--- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
+++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
@@ -57,10 +57,21 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst)
       
       if (IS_SOFTMODEM_NOS1){
         if (rlc_module_init(0) != 0) {
-	  LOG_I(RLC, "Problem at RLC initiation \n");
-    	}
-    	pdcp_layer_init();
-    	nr_DRB_preconfiguration();
+          LOG_I(RLC, "Problem at RLC initiation \n");
+        }
+        pdcp_layer_init();
+        nr_DRB_preconfiguration();
+      }
+
+      // Allocate memory for ul_config_request in the mac instance. This is now a pointer and will
+      // point to a list of structures (one for each UL slot) to store PUSCH scheduling parameters
+      // received from UL DCI.
+      if (nr_ue_mac_inst->scc) {
+        int num_slots_ul = nr_ue_mac_inst->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+        if (nr_ue_mac_inst->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0)
+          num_slots_ul++;
+        LOG_D(MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul);
+        nr_ue_mac_inst->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t));
       }
     }
     else LOG_I(MAC,"Running without RRC instance\n");
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index ab78ec4f30a4a378bc506f3432da00f39005797d..a22291092bddf1bac1d135a2c1f054b2630078b7 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -1346,6 +1346,61 @@ uint32_t get_ssb_frame(uint32_t test){
   return test;
 }
 
+/*
+ * This function returns the slot offset K2 corresponding to a given time domain
+ * indication value from RRC configuration.
+ */
+long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) {
+  long k2 = -1;
+  // Get K2 from RRC configuration
+  NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
+  NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
+  if (pusch_config->pusch_TimeDomainAllocationList) {
+    pusch_TimeDomainAllocationList = pusch_config->pusch_TimeDomainAllocationList->choice.setup;
+  }
+  else if (mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
+    pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+  }
+  if (pusch_TimeDomainAllocationList) {
+    if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) {
+      LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n",
+            time_domain_ind, pusch_TimeDomainAllocationList->list.count);
+      return -1;
+    }
+    k2 = *pusch_TimeDomainAllocationList->list.array[time_domain_ind]->k2;
+  }
+  
+  LOG_D(MAC, "get_k2(): k2 is %ld\n", k2);
+  return k2;
+}
+
+/*
+ * This function returns the UL config corresponding to a given UL slot
+ * from MAC instance .
+ */
+fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) {
+  //Check if request to access ul_config is for a UL slot
+  if (is_nr_UL_slot(mac->scc, slot) == 0) {
+    LOG_W(MAC, "Slot %d is not a UL slot. get_ul_config_request() called for wrong slot!!!\n", slot);
+    return NULL;
+  }
+  
+  // Calculate the index of the UL slot in mac->ul_config_request list. This is
+  // based on the TDD pattern (slot configuration period) and number of UL+mixed
+  // slots in the period. TS 38.213 Sec 11.1
+  int mu = mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
+  NR_TDD_UL_DL_Pattern_t *tdd_pattern = &mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1;
+  const int num_slots_per_tdd = nr_slots_per_frame[mu] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity);
+  const int num_slots_ul = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
+  int index = slot + num_slots_ul - num_slots_per_tdd;
+  LOG_D(MAC, "nr_ue_procedures: get_ul_config_request() slots per tdd %d, num_slots_ul %d, index %d\n", 
+                num_slots_per_tdd,
+                num_slots_ul,
+                index);
+
+  return &mac->ul_config_request[index];
+}
+
 // Performs :
 // 1. TODO: Call RRC for link status return to PHY
 // 2. TODO: Perform SR/BSR procedures for scheduling feedback
@@ -1451,7 +1506,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
     }
   } else if (ul_info) {
 
-    if (get_softmodem_params()->phy_test && ul_info->slot_tx == 8) { // ULSCH is handled only in phy-test mode (consistently with OAI gNB)
+    // ULSCH is handled only in phy-test mode (consistently with OAI gNB)
+    if (get_softmodem_params()->phy_test) {
 
       uint8_t nb_dmrs_re_per_rb;
       uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
@@ -1470,168 +1526,141 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
       NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
       uint8_t access_mode   = SCHEDULED_ACCESS;
 
-      // program PUSCH with UL DCI parameters
-      nr_dcireq_t dcireq;
-      nr_scheduled_response_t scheduled_response;
-      fapi_nr_tx_request_t tx_req;
-      fapi_nr_tx_request_body_t tx_req_body;
-      fapi_nr_ul_config_request_t *ul_config = &dcireq.ul_config_req;
-      nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
-
-      fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &mac->ul_config_request.ul_config_list[0];
-
-      uint16_t rnti               = ulcfg_pdu->pusch_config_pdu.rnti;
-      uint32_t rb_size            = ulcfg_pdu->pusch_config_pdu.rb_size;
-      uint32_t rb_start           = ulcfg_pdu->pusch_config_pdu.rb_start;
-      uint8_t  nr_of_symbols      = ulcfg_pdu->pusch_config_pdu.nr_of_symbols;
-      uint8_t  start_symbol_index = ulcfg_pdu->pusch_config_pdu.start_symbol_index;
-      uint8_t  nrOfLayers         = 1;
-      uint8_t  mcs_index          = ulcfg_pdu->pusch_config_pdu.mcs_index;
-      uint8_t  mcs_table          = ulcfg_pdu->pusch_config_pdu.mcs_table;
-      uint8_t  harq_process_id    = ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id;
-      uint8_t  rv_index           = ulcfg_pdu->pusch_config_pdu.pusch_data.rv_index;
-      uint16_t l_prime_mask       = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
-      uint8_t  dmrs_config_type   = 0;
-      uint16_t pdu_bit_map        = PUSCH_PDU_BITMAP_PUSCH_DATA;
-      // These should come from RRC config!!!
-      uint8_t  ptrs_mcs1          = 2;
-      uint8_t  ptrs_mcs2          = 4;
-      uint8_t  ptrs_mcs3          = 10;
-      uint16_t n_rb0              = 25;
-      uint16_t n_rb1              = 75;
-      uint8_t  ptrs_time_density  = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table);
-      uint8_t  ptrs_freq_density  = get_K_ptrs(n_rb0, n_rb1, rb_size);
-      uint16_t number_dmrs_symbols = 0;
-      uint16_t ul_dmrs_symb_pos   = l_prime_mask << start_symbol_index;
-
-#ifdef DEBUG_DCI      
-      LOG_I(MAC, " UL config params \n rnti: %x \n rb_size: %d \n", 
-                rnti, rb_size);
-      LOG_I(MAC, "rb_start: %x \n nr_of_symbols: %d \n start_symbol_index: %d \n nrOfLayers: %d \n mcs_index: %d \n \
-                mcs_table: %d \n harq_process_id: %d \n ndi: %d \n num_cb: %d \n rv_index: %d \n", 
-                rb_start, nr_of_symbols, start_symbol_index, nrOfLayers, mcs_index,
-                mcs_table, harq_process_id, ndi, num_cb, rv_index);
-#endif
+      fapi_nr_ul_config_request_t *ul_config_req = get_ul_config_request(mac, slot_tx);
 
-      // PTRS ports configuration
-      // TbD: ptrs_dmrs_port and ptrs_port_index are not initialised!
-      ptrs_ports_list.ptrs_re_offset = 0;
+      // Schedule ULSCH only if the current frame and slot match those in ul_config_req
+      // AND if a UL DCI has been received (as indicated by num_pdus).
+      if ((frame_tx == ul_config_req->sfn && slot_tx == ul_config_req->slot) &&
+          ul_config_req->number_pdus > 0) {
+      
+        // program PUSCH with UL DCI parameters
+        nr_scheduled_response_t scheduled_response;
+        fapi_nr_tx_request_t tx_req;
+        nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
+
+        for (int j = 0; j < ul_config_req->number_pdus; j++) {
+          fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config_req->ul_config_list[j];
+
+          if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) {
+
+            // These should come from RRC config!!!
+            uint8_t  ptrs_mcs1          = 2;
+            uint8_t  ptrs_mcs2          = 4;
+            uint8_t  ptrs_mcs3          = 10;
+            uint16_t n_rb0              = 25;
+            uint16_t n_rb1              = 75;
+            uint8_t  ptrs_time_density  = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, ulcfg_pdu->pusch_config_pdu.mcs_index, ulcfg_pdu->pusch_config_pdu.mcs_table);
+            uint8_t  ptrs_freq_density  = get_K_ptrs(n_rb0, n_rb1, ulcfg_pdu->pusch_config_pdu.rb_size);
+            uint16_t l_prime_mask       = get_l_prime(ulcfg_pdu->pusch_config_pdu.nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
+            uint16_t ul_dmrs_symb_pos   = l_prime_mask << ulcfg_pdu->pusch_config_pdu.start_symbol_index;
+
+            uint8_t  dmrs_config_type   = 0;
+            uint16_t number_dmrs_symbols = 0;
+
+            // PTRS ports configuration
+            // TbD: ptrs_dmrs_port and ptrs_port_index are not initialised!
+            ptrs_ports_list.ptrs_re_offset = 0;
+
+            // Num PRB Overhead from PUSCH-ServingCellConfig
+            if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL)
+              N_PRB_oh = 0;
+            else
+              N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead;
+
+            ulcfg_pdu->pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos;
+            ulcfg_pdu->pusch_config_pdu.dmrs_config_type = dmrs_config_type;
+            ulcfg_pdu->pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
+            ulcfg_pdu->pusch_config_pdu.nrOfLayers = 1;
+            ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator = 0;
+            ulcfg_pdu->pusch_config_pdu.pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
+            ulcfg_pdu->pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
+            ulcfg_pdu->pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
+            ulcfg_pdu->pusch_config_pdu.pusch_ptrs.ptrs_ports_list   = &ptrs_ports_list;
+            //ulcfg_pdu->pusch_config_pdu.target_code_rate = nr_get_code_rate_ul(ulcfg_pdu->pusch_config_pdu.mcs_index, ulcfg_pdu->pusch_config_pdu.mcs_table);
+            //ulcfg_pdu->pusch_config_pdu.qam_mod_order = nr_get_Qm_ul(ulcfg_pdu->pusch_config_pdu.mcs_index, ulcfg_pdu->pusch_config_pdu.mcs_table);
+
+            if (1 << ulcfg_pdu->pusch_config_pdu.pusch_ptrs.ptrs_time_density >= ulcfg_pdu->pusch_config_pdu.nr_of_symbols) {
+              ulcfg_pdu->pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
+            }
 
-      // Num PRB Overhead from PUSCH-ServingCellConfig
-      if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL)
-        N_PRB_oh = 0;
-      else
-        N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead;
-
-      ul_config->slot = ul_info->slot_tx;
-      ul_config->number_pdus = 1;
-      ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
-      ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
-      ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
-      ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
-      ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
-      ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
-      ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos;
-      ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
-      ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
-      ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
-      ul_config->ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
-      ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
-      ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
-      ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
-      ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
-      ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
-      ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
-      ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
-      ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list   = &ptrs_ports_list;
-      ul_config->ul_config_list[0].pusch_config_pdu.target_code_rate = nr_get_code_rate_ul(mcs_index, mcs_table);
-      ul_config->ul_config_list[0].pusch_config_pdu.qam_mod_order = nr_get_Qm_ul(mcs_index, mcs_table);
-
-      if (1 << ptrs_time_density >= nr_of_symbols) {
-        ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
-      }
+            get_num_re_dmrs(&ulcfg_pdu->pusch_config_pdu,
+                            &nb_dmrs_re_per_rb,
+                            &number_dmrs_symbols);
+
+            TBS = nr_compute_tbs(ulcfg_pdu->pusch_config_pdu.qam_mod_order,
+                                ulcfg_pdu->pusch_config_pdu.target_code_rate,
+                                ulcfg_pdu->pusch_config_pdu.rb_size,
+                                ulcfg_pdu->pusch_config_pdu.nr_of_symbols,
+                                nb_dmrs_re_per_rb*number_dmrs_symbols,
+                                N_PRB_oh,
+                                0,
+                                ulcfg_pdu->pusch_config_pdu.nrOfLayers);
+            TBS_bytes = TBS/8;
+            ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size = TBS_bytes;
+
+            if (IS_SOFTMODEM_NOS1){
+              // Getting IP traffic to be transmitted
+              data_existing = nr_ue_get_sdu(mod_id,
+                                            cc_id,
+                                            frame_tx,
+                                            slot_tx,
+                                            0,
+                                            ulsch_input_buffer,
+                                            TBS_bytes,
+                                            &access_mode);
+            }
 
-      get_num_re_dmrs(&ul_config->ul_config_list[0].pusch_config_pdu,
-                      &nb_dmrs_re_per_rb,
-                      &number_dmrs_symbols);
-
-      TBS = nr_compute_tbs(ul_config->ul_config_list[0].pusch_config_pdu.qam_mod_order,
-                           ul_config->ul_config_list[0].pusch_config_pdu.target_code_rate,
-                           rb_size,
-                           nr_of_symbols,
-                           nb_dmrs_re_per_rb*number_dmrs_symbols,
-                           N_PRB_oh,
-                           0,
-                           nrOfLayers);
-      TBS_bytes = TBS/8;
-      ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS_bytes;
-
-        if (IS_SOFTMODEM_NOS1){
-          // Getting IP traffic to be transmitted
-          data_existing = nr_ue_get_sdu(mod_id,
-                                        cc_id,
-                                        frame_tx,
-                                        slot_tx,
-                                        0,
-                                        ulsch_input_buffer,
-                                        TBS_bytes,
-                                        &access_mode);
-        }
+            //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
+            if (!IS_SOFTMODEM_NOS1 || !data_existing) {
+              //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
+              //and block this traffic from being forwarded to the upper layers at the gNB
+              LOG_D(PHY, "Random data to be tranmsitted: \n");
 
-        //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
-        if (!IS_SOFTMODEM_NOS1 || !data_existing) {
-          //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
-          //and block this traffic from being forwarded to the upper layers at the gNB
-          LOG_D(PHY, "Random data to be tranmsitted: \n");
+              //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
+              //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
+              //have a valid LCID (nr_process_mac_pdu function)
+              ulsch_input_buffer[0] = 0x31;
 
-          //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
-          //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
-          //have a valid LCID (nr_process_mac_pdu function)
-          ulsch_input_buffer[0] = 0x31;
+              for (i = 1; i < TBS_bytes; i++) {
+                ulsch_input_buffer[i] = (unsigned char) rand();
+                //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
+              }
+            }
 
-          for (i = 1; i < TBS_bytes; i++) {
-            ulsch_input_buffer[i] = (unsigned char) rand();
-            //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
+    #ifdef DEBUG_MAC_PDU
+
+            LOG_D(PHY, "Is data existing ?: %d \n", data_existing);
+            LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS_bytes);
+            for (i = 0; i < TBS_bytes; i++) {
+              printf("%02x", ulsch_input_buffer[i]);
+            }
+            printf("\n");
+
+    #endif
+
+            // Config UL TX PDU
+            tx_req.slot = slot_tx;
+            tx_req.sfn = frame_tx;
+            // tx_req->tx_config // TbD
+            tx_req.number_of_pdus++;
+            tx_req.tx_request_body[j].pdu_length = TBS_bytes;
+            tx_req.tx_request_body[j].pdu_index = j;
+            tx_req.tx_request_body[j].pdu = ulsch_input_buffer;
           }
         }
 
-#ifdef DEBUG_MAC_PDU
-
-        LOG_D(PHY, "Is data existing ?: %d \n", data_existing);
-        LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS_bytes);
-        for (i = 0; i < TBS_bytes; i++) {
-          printf("%02x", ulsch_input_buffer[i]);
+        fill_scheduled_response(&scheduled_response, NULL, ul_config_req, &tx_req, mod_id, cc_id, rx_frame, rx_slot);
+        if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
+          mac->if_module->scheduled_response(&scheduled_response);
         }
-        printf("\n");
-
-#endif
 
-      dcireq.module_id = mod_id;
-      dcireq.gNB_index = gNB_index;
-      dcireq.cc_id     = cc_id;
-      dcireq.frame     = rx_frame;
-      dcireq.slot      = rx_slot;
+        // TODO: expand
+        // Note: Contention resolution is currently not active
+        if (mac->RA_contention_resolution_timer_active == 1)
+          ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx);
 
-      // Config UL TX PDU
-      tx_req.slot = slot_tx;
-      tx_req.sfn = frame_tx;
-      // tx_req->tx_config // TbD
-      tx_req.number_of_pdus = 1;
-      tx_req_body.pdu_length = TBS_bytes;
-      tx_req_body.pdu_index = 0;
-      tx_req_body.pdu = ulsch_input_buffer;
-      tx_req.tx_request_body = &tx_req_body;
-
-      fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot);
-      if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
-        mac->if_module->scheduled_response(&scheduled_response);
       }
 
-      // TODO: expand
-      // Note: Contention resolution is currently not active
-      if (mac->RA_contention_resolution_timer_active == 1)
-        ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx);
-
     } else if (get_softmodem_params()->do_ra){
 
       NR_UE_MAC_INST_t *mac = get_mac_inst(ul_info->module_id);
@@ -1641,8 +1670,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
         uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
         nr_scheduled_response_t scheduled_response;
         fapi_nr_tx_request_t tx_req;
-        fapi_nr_tx_request_body_t tx_req_body;
-        fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
+        //fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx);
+        fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0];
         fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus];
         uint16_t TBS_bytes = ul_config_list->pusch_config_pdu.pusch_data.tb_size;
 
@@ -1683,10 +1712,9 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
         tx_req.slot = ul_info->slot_tx;
         tx_req.sfn = ul_info->frame_tx;
         tx_req.number_of_pdus = 1;
-        tx_req_body.pdu_length = TBS_bytes;
-        tx_req_body.pdu_index = 0;
-        tx_req_body.pdu = ulsch_input_buffer;
-        tx_req.tx_request_body = &tx_req_body;
+        tx_req.tx_request_body[0].pdu_length = TBS_bytes;
+        tx_req.tx_request_body[0].pdu_index = 0;
+        tx_req.tx_request_body[0].pdu = ulsch_input_buffer;
         ul_config_list->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
         ul_config->number_pdus++;
         // scheduled_response
@@ -1753,7 +1781,8 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
 
-  fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
+  //fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
+  fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0];
   fapi_nr_ul_config_prach_pdu *prach_config_pdu;
   fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
   fapi_nr_prach_config_t *prach_config = &cfg->prach_config;
@@ -3087,7 +3116,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
   return 0;
 }
 //////////////
-int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index,fapi_nr_dci_indication_pdu_t *dci) {
+int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) {
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
 
@@ -3095,16 +3124,19 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
 	dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits);
 
   int dci_format = nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,def_dci_pdu_rel15);
-  return (nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci_format));
+  return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci->rnti, dci_format));
 }
 
-int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){
+int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){
 
   int bwp_id = 1;
+  int mu = 0;
+  long k2 = 0;
+  uint16_t frame_tx = 0, slot_tx = 0;
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
   fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
-  fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
+  fapi_nr_ul_config_request_t *ul_config = NULL;
     
   //const uint16_t n_RB_DLBWP = dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP; //make sure this has been set
   AssertFatal(mac->DLbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n");
@@ -3134,6 +3166,28 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
      *    49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space
      *    50 SUL_IND_0_0:
      */
+    // Calculate the slot in which ULSCH should be scheduled. This is current slot + K2,
+    // where K2 is the offset between the slot in which UL DCI is received and the slot
+    // in which ULSCH should be scheduled. K2 is configured in RRC configuration.  
+    
+    // Get the numerology to calculate the Tx frame and slot
+    mu = mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
+    // Get slot offset K2 which will be used to calculate TX slot
+    k2 = get_k2(mac, dci->time_domain_assignment.val);
+    if (k2 < 0)           // This can happen when a false DCI is received
+      return -1;
+    // Calculate TX slot and frame
+    slot_tx = (slot + k2) % nr_slots_per_frame[mu];
+    frame_tx = ((slot + k2) > nr_slots_per_frame[mu]) ? (frame + 1) % 1024 : frame;
+    
+    // Get UL config request corresponding slot_tx 
+    ul_config = get_ul_config_request(mac, slot_tx);
+    //AssertFatal(ul_config != NULL, "nr_ue_process_dci(): ul_config is NULL\n");
+    if (!ul_config) {
+      LOG_W(MAC, "nr_ue_process_dci(): ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n",frame,slot);
+      return -1;
+    }
+
     ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
     ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rnti = rnti;
     nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu_0_0 = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
@@ -3172,7 +3226,10 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
     }
     /* SUL_IND_0_0 */ // To be implemented, FIXME!!!
 
+    ul_config->slot = slot_tx;
+    ul_config->sfn = frame_tx;
     ul_config->number_pdus = ul_config->number_pdus + 1;
+    LOG_D(MAC, "nr_ue_process_dci(): Calculated frame and slot for pusch Tx: %d.%d, number of pdus %d\n", ul_config->sfn, ul_config->slot, ul_config->number_pdus);
     break;
 
   case NR_UL_DCI_FORMAT_0_1:
@@ -3204,6 +3261,28 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
      *    48 UL_SCH_IND
      *    49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space
      */
+    // Calculate the slot in which ULSCH should be scheduled. This is current slot + K2,
+    // where K2 is the offset between the slot in which UL DCI is received and the slot
+    // in which ULSCH should be scheduled. K2 is configured in RRC configuration.  
+    
+    // Get the numerology to calculate the Tx frame and slot
+    mu = mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
+    // Get slot offset K2 which will be used to calculate TX slot
+    k2 = get_k2(mac, dci->time_domain_assignment.val);
+    if (k2 < 0)           // This can happen when a false DCI is received
+      return -1;
+    // Calculate TX slot and frame
+    slot_tx = (slot + k2) % nr_slots_per_frame[mu];
+    frame_tx = ((slot + k2) > nr_slots_per_frame[mu]) ? (frame + 1) % 1024 : frame;
+    
+    // Get UL config request corresponding slot_tx 
+    ul_config = get_ul_config_request(mac, slot_tx);
+    //AssertFatal(ul_config != NULL, "nr_ue_process_dci(): ul_config is NULL\n");
+    if (!ul_config) {
+      LOG_W(MAC, "nr_ue_process_dci(): ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n",frame,slot);
+      return -1;
+    }
+
     ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
     ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rnti = rnti;
     nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu_0_1 = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
@@ -3240,6 +3319,13 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
       pusch_config_pdu_0_1->mcs_table = get_pusch_mcs_table(pusch_config->mcs_TableTransformPrecoder, 1,
                                                  dci_format, NR_RNTI_C, NR_SearchSpace__searchSpaceType_PR_ue_Specific, false);
     
+    pusch_config_pdu_0_1->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu_0_1->mcs_index, pusch_config_pdu_0_1->mcs_table);
+    pusch_config_pdu_0_1->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu_0_1->mcs_index, pusch_config_pdu_0_1->mcs_table);
+    if (pusch_config_pdu_0_1->target_code_rate == 0 || pusch_config_pdu_0_1->qam_mod_order == 0) {
+      LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected UL DCI. Ignoring DCI! \n");
+      return -1;
+    }
+
     /* NDI */
     pusch_config_pdu_0_1->pusch_data.new_data_indicator = dci->ndi;
     /* RV */
@@ -3497,8 +3583,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
     /* UL_SCH_IND */
     // A value of "1" indicates UL-SCH shall be transmitted on the PUSCH and
     // a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH
-
+    
+    ul_config->slot = slot_tx;
+    ul_config->sfn = frame_tx;
     ul_config->number_pdus = ul_config->number_pdus + 1;
+    LOG_D(MAC, "nr_ue_process_dci(): Calculated frame and slot for pusch Tx: %d.%d, number of pdus %d\n", ul_config->sfn, ul_config->slot, ul_config->number_pdus);
     break;
 
   case NR_DL_DCI_FORMAT_1_0:
diff --git a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c
index c81a1f79115a13a8c8ebbd68a82f4d3916aa8c8a..3fbd5a16b0df0919dda5b671551510e8c0c2060f 100644
--- a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c
+++ b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c
@@ -77,7 +77,7 @@ void nr_config_Msg3_pdu(NR_UE_MAC_INST_t *mac,
   uint8_t nb_dmrs_re_per_rb;
   uint16_t number_dmrs_symbols = 0;
   int N_PRB_oh;
-  fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
+  fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0];
   nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
   NR_ServingCellConfigCommon_t *scc = mac->scc;
   NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 0860c459e243033ee9a43dde15d614625f355fc8..ab49fcdc8c8947950999ba463f5cce45ddc8b447 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -125,14 +125,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
   }
 
   lte_frame_type_t frame_type;
-  uint16_t band;
-  int32_t offset;
-
-  get_band(((uint64_t)cfg->carrier_config.dl_frequency.value)*1000,
-           &band,
-           &offset,
-           &frame_type);
-
+  get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
   RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type;
 
   // Cell configuration
@@ -297,8 +290,8 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
 		"scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n");
     cfg->tdd_table.tdd_period.value = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
   }
-  LOG_I(MAC,"Setting TDD configuration period to %d\n",cfg->tdd_table.tdd_period.value);
   if(cfg->cell_config.frame_duplex_type.value == TDD){
+    LOG_I(MAC,"Setting TDD configuration period to %d\n",cfg->tdd_table.tdd_period.value);
     int return_tdd = set_tdd_config_nr(cfg,
 		    scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
                     scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
@@ -306,10 +299,10 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
                     scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
                     scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols);
 
-  if (return_tdd !=0){
-     LOG_E(PHY,"TDD configuration can not be done\n");
-  }
-  else LOG_I(PHY,"TDD has been properly configurated\n");
+    if (return_tdd != 0)
+      LOG_E(MAC,"TDD configuration can not be done\n");
+    else 
+      LOG_I(MAC,"TDD has been properly configurated\n");
   }
 
 }
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index 148f77c76841d0487a63c9247e974470bc870827..8e49403c71c8d2cd3bb98837968d494300d4b491 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -449,7 +449,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
       break;
 
     default:
-      AssertFatal(1==0,"Undefined tdd period %d\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
+      AssertFatal(1==0,"Undefined tdd period %ld\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
   }
 
   int num_slots_per_tdd = (slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame;
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 079e745ebbcb26e742a962ff721f35fb909405f1..b3cd91fd0102fbab56489f1fccab9978b322a9d6 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -334,8 +334,6 @@ int get_ulscs(nfapi_nr_config_request_t *cfg);
 
 int get_symbolsperslot(nfapi_nr_config_request_t *cfg);
 
-int32_t get_nr_uldl_offset(int nr_bandP);
-
 void config_nr_mib(int Mod_idP, 
                    int CC_idP,
                    int p_gNBP,
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index 5d620181d158b3ea06ce8a779d942452715a2ae4..d680e454e88690ae746900dbcc4ef05161d373b0 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -64,10 +64,10 @@ int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index,
   return 0;
 }
 //  L2 Abstraction Layer
-int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, fapi_nr_dci_indication_pdu_t *dci){
+int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci){
 
   //printf("handle_dci: rnti %x,dci_type %d\n",rnti,dci_type);
-  return nr_ue_process_dci_indication_pdu(module_id, cc_id, gNB_index, dci);
+  return nr_ue_process_dci_indication_pdu(module_id, cc_id, gNB_index, frame, slot, dci);
 
 }
 //  L2 Abstraction Layer
@@ -135,8 +135,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
   module_id_t module_id = dl_info->module_id;
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
   fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
-  fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
-
+  
   if (!dl_info->dci_ind && !dl_info->rx_ind) {
     // UL indication to schedule DCI reception
     nr_ue_scheduler(dl_info, NULL);
@@ -150,13 +149,15 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
         int8_t ret = handle_dci(dl_info->module_id,
                                 dl_info->cc_id,
                                 dl_info->gNB_index,
+                                dl_info->frame,
+                                dl_info->slot,
                                 dl_info->dci_ind->dci_list+i);
 
         ret_mask |= (ret << FAPI_NR_DCI_IND);
         if (ret >= 0) {
           AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is NULL!\n" );
           AssertFatal( nr_ue_if_module_inst[module_id]->scheduled_response != NULL, "scheduled_response is NULL!\n" );
-          fill_scheduled_response(&scheduled_response, dl_config, ul_config, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot);
+          fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot);
           nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response);
         }
       }
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
index df2d78f0cb35ef7e6a9564f38f6226e839fe863a..aba67674653c8152cffff8896438fe5aa8f5f51a 100755
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
@@ -224,7 +224,7 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, ui
    \param pduP      pointer to pdu*/
 int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len);
 
-int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, fapi_nr_dci_indication_pdu_t *dci);
+int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
 
 #endif
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
new file mode 100644
index 0000000000000000000000000000000000000000..9e13d493a8acc095e27d134e2b6d6e0dbaf0ca8b
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -0,0 +1,284 @@
+Active_gNBs = ( "gNB-Eurecom-5GNRBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_GNB";
+
+    gNB_name  =  "gNB-Eurecom-5GNRBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  1;
+
+    plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 2150 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 433096;
+      dl_frequencyBand                                                 = 66;
+      # this is 2150 MHz
+      dl_absoluteFrequencyPointA                                       = 430000;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=0,L=50 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 13475;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 12;
+        initialDLBWPsearchSpaceZero                                             = 0;
+      #pdsch-ConfigCommon
+        #pdschTimeDomainAllocationList (up to 16 entries)
+             initialDLBWPk0_0                    = 0;
+             #initialULBWPmappingType
+       #0=typeA,1=typeB
+             initialDLBWPmappingType_0           = 0;
+             #this is SS=1,L=13
+             initialDLBWPstartSymbolAndLength_0  = 40;
+
+             initialDLBWPk0_1                    = 0;
+             initialDLBWPmappingType_1           = 0;
+             #this is SS=2,L=12
+             initialDLBWPstartSymbolAndLength_1  = 53;
+
+             initialDLBWPk0_2                    = 0;
+             initialDLBWPmappingType_2           = 0;
+             #this is SS=1,L=12
+             initialDLBWPstartSymbolAndLength_2  = 54;
+
+             initialDLBWPk0_3                    = 0;
+             initialDLBWPmappingType_3           = 0;
+             #this is SS=1,L=4
+             initialDLBWPstartSymbolAndLength_3  = 57;
+  #uplinkConfigCommon
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 66;
+      ul_absoluteFrequencyPointA                                       = 350000;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      ul_subcarrierSpacing                                           = 1;
+      ul_carrierBandwidth                                            = 106;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 13475;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialULBWPsubcarrierSpacing                                           = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 13;
+          preambleReceivedTargetPower                               = -118;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 15;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #
+        msg1_SubcarrierSpacing                                      = 1,
+
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+      # pusch-ConfigCommon (up to 16 elements)
+        initialULBWPk2_0                      = 6;
+        initialULBWPmappingType_0             = 1
+        # this is SS=0 L=11
+        initialULBWPstartSymbolAndLength_0    = 55;
+
+  initialULBWPk2_1                      = 6;
+        initialULBWPmappingType_1             = 1;
+        # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 7;
+        initialULBWPmappingType_2             = 1;
+        # this is SS=10 L=4
+        initialULBWPstartSymbolAndLength_2    = 52;
+        msg3_DeltaPreamble                                          = 1;
+        p0_NominalWithGrant                                         =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        p0_nominal                                                  = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
+      ssb_periodicityServingCell                                    = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+      dmrs_TypeA_Position                                           = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      subcarrierSpacing                                             = 1;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      referenceSubcarrierSpacing                                    = 1;
+      # pattern1
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 6;
+      nrofDownlinkSlots                                             = 7;
+      nrofDownlinkSymbols                                           = 6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4;
+
+  ssPBCH_BlockPower                                             = 10;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "192.168.12.26";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        GNB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        GNB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.111/24";
+        GNB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        GNB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.111/24";
+        GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+  }
+);
+
+MACRLCs = (
+  {
+  num_cc = 1;
+  tr_s_preference = "local_L1";
+  tr_n_preference = "local_RRC";
+        }
+);
+
+L1s = (
+      {
+  num_cc = 1;
+  tr_n_preference = "local_mac";
+        }
+);
+
+RUs = (
+    {
+       local_rf       = "yes"
+         nb_tx          = 1;
+         nb_rx          = 1;
+         att_tx         = 0;
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 75;
+         eNB_instances  = [0];
+         #beamforming 1x4 matrix:
+         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+         sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
+         clock_src = "external";
+         # if_freq = 3700000000L;
+         # if_offset = 1000000;
+    }
+);
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
new file mode 100644
index 0000000000000000000000000000000000000000..831f9c7978f738041d2e7242e04b63efd1cf4ac0
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
@@ -0,0 +1,284 @@
+Active_gNBs = ( "gNB-Eurecom-5GNRBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+    ////////// Identification parameters:
+    gNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_GNB";
+
+    gNB_name  =  "gNB-Eurecom-5GNRBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  1;
+
+    plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    ssb_SubcarrierOffset                                      = 0;
+    pdsch_AntennaPorts                                        = 1;
+
+    servingCellConfigCommon = (
+    {
+ #spCellConfigCommon
+
+      physCellId                                                    = 0;
+
+#  downlinkConfigCommon
+    #frequencyInfoDL
+      # this is 2150 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+      absoluteFrequencySSB                                          = 433096;
+      dl_frequencyBand                                                 = 66;
+      # this is 2150 MHz
+      dl_absoluteFrequencyPointA                                       = 430000;
+      #scs-SpecificCarrierList
+        dl_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        dl_subcarrierSpacing                                           = 1;
+        dl_carrierBandwidth                                            = 106;
+     #initialDownlinkBWP
+      #genericParameters
+        # this is RBstart=0,L=50 (275*(L-1))+RBstart
+        initialDLBWPlocationAndBandwidth                                        = 13475;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialDLBWPsubcarrierSpacing                                           = 1;
+      #pdcch-ConfigCommon
+        initialDLBWPcontrolResourceSetZero                                      = 12;
+        initialDLBWPsearchSpaceZero                                             = 0;
+      #pdsch-ConfigCommon
+        #pdschTimeDomainAllocationList (up to 16 entries)
+             initialDLBWPk0_0                    = 0;
+             #initialULBWPmappingType
+       #0=typeA,1=typeB
+             initialDLBWPmappingType_0           = 0;
+             #this is SS=1,L=13
+             initialDLBWPstartSymbolAndLength_0  = 40;
+
+             initialDLBWPk0_1                    = 0;
+             initialDLBWPmappingType_1           = 0;
+             #this is SS=2,L=12
+             initialDLBWPstartSymbolAndLength_1  = 53;
+
+             initialDLBWPk0_2                    = 0;
+             initialDLBWPmappingType_2           = 0;
+             #this is SS=1,L=12
+             initialDLBWPstartSymbolAndLength_2  = 54;
+
+             initialDLBWPk0_3                    = 0;
+             initialDLBWPmappingType_3           = 0;
+             #this is SS=1,L=4
+             initialDLBWPstartSymbolAndLength_3  = 57;
+  #uplinkConfigCommon
+     #frequencyInfoUL
+      ul_frequencyBand                                                 = 66;
+      ul_absoluteFrequencyPointA                                       = 350000;
+      #scs-SpecificCarrierList
+      ul_offstToCarrier                                              = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      ul_subcarrierSpacing                                           = 1;
+      ul_carrierBandwidth                                            = 106;
+      pMax                                                          = 20;
+     #initialUplinkBWP
+      #genericParameters
+        initialULBWPlocationAndBandwidth                                        = 13475;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+        initialULBWPsubcarrierSpacing                                           = 1;
+      #rach-ConfigCommon
+        #rach-ConfigGeneric
+          prach_ConfigurationIndex                                  = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+          prach_msg1_FDM                                            = 0;
+          prach_msg1_FrequencyStart                                 = 0;
+          zeroCorrelationZoneConfig                                 = 13;
+          preambleReceivedTargetPower                               = -118;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+          preambleTransMax                                          = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+        powerRampingStep                                            = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+        ra_ResponseWindow                                           = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR                = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+        ssb_perRACH_OccasionAndCB_PreamblesPerSSB                   = 15;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+        ra_ContentionResolutionTimer                                = 7;
+        rsrp_ThresholdSSB                                           = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+        prach_RootSequenceIndex_PR                                  = 2;
+        prach_RootSequenceIndex                                     = 1;
+        # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+        #
+        msg1_SubcarrierSpacing                                      = 1,
+
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+        restrictedSetConfig                                         = 0,
+      # pusch-ConfigCommon (up to 16 elements)
+        initialULBWPk2_0                      = 6;
+        initialULBWPmappingType_0             = 1
+        # this is SS=0 L=11
+        initialULBWPstartSymbolAndLength_0    = 55;
+
+  initialULBWPk2_1                      = 6;
+        initialULBWPmappingType_1             = 1;
+        # this is SS=0 L=12
+        initialULBWPstartSymbolAndLength_1    = 69;
+
+        initialULBWPk2_2                      = 7;
+        initialULBWPmappingType_2             = 1;
+        # this is SS=10 L=4
+        initialULBWPstartSymbolAndLength_2    = 52;
+        msg3_DeltaPreamble                                          = 1;
+        p0_NominalWithGrant                                         =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+        pucchGroupHopping                                           = 0;
+        hoppingId                                                   = 40;
+        p0_nominal                                                  = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+      ssb_PositionsInBurst_PR                                       = 2;
+      ssb_PositionsInBurst_Bitmap                                   = 1;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
+      ssb_periodicityServingCell                                    = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+      dmrs_TypeA_Position                                           = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      subcarrierSpacing                                             = 1;
+
+
+  #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+      referenceSubcarrierSpacing                                    = 1;
+      # pattern1
+      # dl_UL_TransmissionPeriodicity
+      # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+      dl_UL_TransmissionPeriodicity                                 = 6;
+      nrofDownlinkSlots                                             = 7;
+      nrofDownlinkSymbols                                           = 6;
+      nrofUplinkSlots                                               = 2;
+      nrofUplinkSymbols                                             = 4;
+
+  ssPBCH_BlockPower                                             = 10;
+  }
+
+  );
+
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "192.168.12.26";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        GNB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        GNB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.111/24";
+        GNB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        GNB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.111/24";
+        GNB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+  }
+);
+
+MACRLCs = (
+  {
+  num_cc = 1;
+  tr_s_preference = "local_L1";
+  tr_n_preference = "local_RRC";
+        }
+);
+
+L1s = (
+      {
+  num_cc = 1;
+  tr_n_preference = "local_mac";
+        }
+);
+
+RUs = (
+    {
+       local_rf       = "yes"
+         nb_tx          = 1;
+         nb_rx          = 1;
+         att_tx         = 0;
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 114;
+         eNB_instances  = [0];
+         #beamforming 1x4 matrix:
+         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+         sdr_addrs = "type=x300";
+         clock_src = "external";
+         # if_freq = 3700000000L;
+         # if_offset = 1000000;
+    }
+);
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
index 884ab771e6359f2015eddb7feccd2046e97310de..6f081fa24ffe87cb61054bcaed03011724e0b5f4 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -126,10 +126,10 @@ gNBs =
         # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
         #  
         msg1_SubcarrierSpacing                                      = 1,
-
 # restrictedSetConfig
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
+
       # pusch-ConfigCommon (up to 16 elements)
         initialULBWPk2_0                      = 6;
         initialULBWPmappingType_0             = 1
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
index 0b04dc82d1741148aa38a192c5397682e3b073d3..d38fff42419efb95e1f4ecdee4ce4bc0d66ab98a 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
@@ -46,7 +46,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
         # this is RBstart=0,L=50 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 13475;
+        initialDLBWPlocationAndBandwidth                                        = 6366;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialDLBWPsubcarrierSpacing                                           = 1;
@@ -74,8 +74,9 @@ gNBs =
 
              initialDLBWPk0_3                    = 0;
              initialDLBWPmappingType_3           = 0;
-             #this is SS=1,L=5 
+             #this is SS=1,L=4
              initialDLBWPstartSymbolAndLength_3  = 57;
+
   #uplinkConfigCommon 
      #frequencyInfoUL
       ul_frequencyBand                                                 = 78;
@@ -88,7 +89,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 13475;
+        initialULBWPlocationAndBandwidth                                        = 6366;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120  
         initialULBWPsubcarrierSpacing                                           = 1;
@@ -125,21 +126,26 @@ gNBs =
         # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
         #  
         msg1_SubcarrierSpacing                                      = 1,
-
 # restrictedSetConfig
 # 0=unrestricted, 1=restricted type A, 2=restricted type B
         restrictedSetConfig                                         = 0,
+
       # pusch-ConfigCommon (up to 16 elements)
-        initialULBWPk2_0                      = 2;
+        initialULBWPk2_0                      = 6;
         initialULBWPmappingType_0             = 1
         # this is SS=0 L=11
         initialULBWPstartSymbolAndLength_0    = 55;
  	
-	initialULBWPk2_1                      = 2;
+	initialULBWPk2_1                      = 6;
         initialULBWPmappingType_1             = 1;
         # this is SS=0 L=12
         initialULBWPstartSymbolAndLength_1    = 69;
 
+	initialULBWPk2_2                      = 7;
+        initialULBWPmappingType_2             = 1;
+        # this is SS=10 L=4
+        initialULBWPstartSymbolAndLength_2    = 52;
+
 
         msg3_DeltaPreamble                                          = 1;
         p0_NominalWithGrant                                         =-90;
@@ -242,6 +248,8 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 114;
          eNB_instances  = [0];
+         #beamforming 1x4 matrix:
+         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
          sdr_addrs = "type=x300";
          clock_src = "external";
     }