diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 2bb4ce31eefd7a1b17b0807dffac3921579a7cb3..02f8c1757cc626d2e87332fb931239721a6c646d 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1261,8 +1261,8 @@ set(PHY_SRC_UE
   # actual source
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c
-  ${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
-  ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c
+  #${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
+  #${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c
   ${OPENAIR1_DIR}/PHY/INIT/nr_parms.c
   ${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
   ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
@@ -2145,6 +2145,7 @@ add_executable(nr-softmodem
   ${OPENAIR_BIN_DIR}/messages_xml.h
   ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
   ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
+  ${OPENAIR_TARGETS}/RT/USER/nr-softmodem.c
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
   ${OPENAIR_TARGETS}/COMMON/create_tasks.c
   ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
diff --git a/openair1/PHY/INIT/defs_NR.h b/openair1/PHY/INIT/defs_NR.h
index f4915401ddf2252afe5b8efb7a5d2ddeb17c4e99..074acf567d7d7286e2c0d97be81ab7a45daf2b27 100644
--- a/openair1/PHY/INIT/defs_NR.h
+++ b/openair1/PHY/INIT/defs_NR.h
@@ -24,4 +24,15 @@
 
 #include "PHY/defs.h"
 
+typedef enum {
+  NR_MU_0=0,
+  NR_MU_1,
+  NR_MU_2,
+  NR_MU_3,
+  NR_MU_4,
+} nr_numerology_index_e;
+
+/// Subcarrier spacings in Hz indexed by numerology index
+uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
+
 #endif
diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c
index 76ca0f043da0c35648e59dade46177e58b918e40..5416e9444af06380af4013beaa8ba5fab62adc4c 100644
--- a/openair1/PHY/INIT/nr_parms.c
+++ b/openair1/PHY/INIT/nr_parms.c
@@ -22,3 +22,107 @@
 #include "defs.h"
 #include "defs_NR.h"
 #include "log.h"
+
+
+int nr_init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms)
+{
+
+#if DISABLE_LOG_X
+  printf("Initializing frame parms for mu %d, N_RB_DL %d, Ncp %d, osf %d\n",frame_parms->N_RB_DL,frame_parms->Ncp,osf);
+#else
+  LOG_I(PHY,"Initializing frame parms for mu %d, N_RB_DL %d, Ncp %d, osf %d\n",frame_parms->N_RB_DL,frame_parms->Ncp,osf);
+#endif
+
+  if (frame_parms->Ncp == EXTENDED)
+    AssertFatal(frame_parms->mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", frame_parms->Ncp, frame_parms->mu);
+
+  switch(frame_parms->mu) {
+
+    case NR_MU_0: //15kHz scs
+      frame_parms->scs = nr_subcarrier_spacing[NR_MU_0];
+      break;
+
+    case NR_MU_1: //30kHz scs
+      frame_parms->scs = nr_subcarrier_spacing[NR_MU_1];
+
+      switch(frame_parms->N_RB_DL){
+        case 11:
+        case 24:
+        case 38:
+        case 78:
+        case 51:
+        case 65:
+
+        case 106: //40 MHz
+          frame_parms->ofdm_symbol_size = 2048;
+          frame_parms->samples_per_tti = 30720;
+          frame_parms->first_carrier_offset = 1412; //2048 - 636
+          frame_parms->nb_prefix_samples0 = 160;
+          frame_parms->nb_prefix_samples = 144;
+          break;
+
+        case 133:
+        case 162:
+        case 189:
+
+        case 217: //80 MHz
+          frame_parms->ofdm_symbol_size = 4096;
+          frame_parms->samples_per_tti = 61440;
+          frame_parms->first_carrier_offset = 2794; //4096 - 1302
+          frame_parms->nb_prefix_samples0 = 320;
+          frame_parms->nb_prefix_samples = 288;
+          break;
+
+        case 245:
+        case 273:
+      default:
+        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", frame_parms->N_RB_DL, frame_parms->mu, frame_parms);
+      }
+      break;
+
+    case NR_MU_2: //60kHz scs
+      frame_parms->scs = nr_subcarrier_spacing[NR_MU_2];
+
+      switch(frame_parms->N_RB_DL){ //FR1 bands only
+        case 11:
+        case 18:
+        case 38:
+        case 24:
+        case 31:
+        case 51:
+        case 65:
+        case 79:
+        case 93:
+        case 107:
+        case 121:
+        case 135:
+      default:
+        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", frame_parms->N_RB_DL, frame_parms->mu, frame_parms);
+      }
+      break;
+
+    case NR_MU_3:
+      frame_parms->scs = nr_subcarrier_spacing[NR_MU_3];
+      break;
+
+    case NR_MU_4:
+      frame_parms->scs = nr_subcarrier_spacing[NR_MU_4];
+      break;
+
+  default:
+    AssertFatal(1==0,"Invalid numerology index %d", frame_parms->mu);
+  }
+
+  return 0;
+}
+
+void nr_dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms)
+{
+  LOG_I(PHY,"frame_parms->mu=%d\n",frame_parms->mu);
+  LOG_I(PHY,"frame_parms->scs=%d\n",frame_parms->scs);
+  LOG_I(PHY,"frame_parms->N_RB_DL=%d\n",frame_parms->N_RB_DL);
+  LOG_I(PHY,"frame_parms->ofdm_symbol_size=%d\n",frame_parms->ofdm_symbol_size);
+  LOG_I(PHY,"frame_parms->samples_per_tti=%d\n",frame_parms->samples_per_tti);
+  LOG_I(PHY,"frame_parms->nb_prefix_samples0=%d\n",frame_parms->nb_prefix_samples0);
+  LOG_I(PHY,"frame_parms->nb_prefix_samples=%d\n",frame_parms->nb_prefix_samples);
+}