From 5e9da7c54c68921e0dc7916d730c3e49df11971b Mon Sep 17 00:00:00 2001
From: Raymond Knopp <raymond.knopp@eurecom.fr>
Date: Thu, 18 Oct 2018 23:32:51 +0200
Subject: [PATCH] temporary commit

---
 openair1/PHY/INIT/nr_init.c                   |  12 +-
 openair1/PHY/INIT/nr_init_ue.c                |  28 +--
 openair1/PHY/INIT/nr_parms.c                  | 191 ++++--------------
 openair1/PHY/INIT/phy_init.h                  |   3 +-
 openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c  |   1 +
 openair1/PHY/MODULATION/ofdm_mod.c            |   6 +-
 openair1/PHY/MODULATION/slot_fep_nr.c         |  10 +-
 openair1/PHY/NR_REFSIG/pss_nr.h               |   9 +-
 openair1/PHY/NR_TRANSPORT/nr_pss.c            |   8 +-
 openair1/PHY/NR_TRANSPORT/nr_sss.c            |   3 +-
 .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c     |  67 +++---
 .../NR_UE_TRANSPORT/nr_transport_proto_ue.h   |   1 +
 openair1/PHY/NR_UE_TRANSPORT/pss_nr.c         | 138 ++++++++-----
 openair1/PHY/NR_UE_TRANSPORT/sss_nr.c         |  75 ++++---
 openair1/PHY/TOOLS/cdot_prod.c                | 122 +++++++++++
 openair1/PHY/TOOLS/dB_routines.c              |   8 +
 openair1/PHY/TOOLS/lte_dfts.c                 |   4 +-
 openair1/PHY/TOOLS/tools_defs.h               |   5 +
 openair1/PHY/defs_nr_UE.h                     |   2 +
 openair1/PHY/defs_nr_common.h                 |   4 +-
 openair1/SCHED_NR/phy_procedures_nr_gNB.c     |   3 +-
 openair1/SIMULATION/NR_PHY/pbchsim.c          |  60 ++++--
 22 files changed, 435 insertions(+), 325 deletions(-)

diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 547e5a5bca..28581b664e 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -365,7 +365,7 @@ void install_schedule_handlers(IF_Module_t *if_inst)
 
 /// this function is a temporary addition for NR configuration
 
-void nr_phy_config_request_sim(PHY_VARS_gNB *gNB)
+void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu)
 {
   NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
   nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config;
@@ -373,14 +373,14 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB)
   //overwrite for new NR parameters
   gNB_config->nfapi_config.rf_bands.rf_band[0] = 22;
   gNB_config->nfapi_config.earfcn.value = 6600;
-  gNB_config->subframe_config.numerology_index_mu.value = 1;
-  gNB_config->subframe_config.duplex_mode.value = FDD;
+  gNB_config->subframe_config.numerology_index_mu.value = mu;
+  gNB_config->subframe_config.duplex_mode.value = TDD;
   gNB_config->rf_config.tx_antenna_ports.value = 1;
-  gNB_config->rf_config.dl_carrier_bandwidth.value = 106;
-  gNB_config->rf_config.ul_carrier_bandwidth.value = 106;
+  gNB_config->rf_config.dl_carrier_bandwidth.value = N_RB_DL;
+  gNB_config->rf_config.ul_carrier_bandwidth.value = N_RB_UL;
   gNB_config->sch_config.half_frame_index.value = 0;
   gNB_config->sch_config.ssb_subcarrier_offset.value = 0;
-  gNB_config->sch_config.n_ssb_crb.value = 86;
+  gNB_config->sch_config.n_ssb_crb.value = N_RB_DL-20;
   gNB_config->sch_config.ssb_subcarrier_offset.value = 0;
 
 
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 34d40d17b9..5e3e72d259 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -660,12 +660,11 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   fp->nb_antennas_tx = 1;
   fp->nb_antennas_rx=1;
 
-  init_dfts();
 
   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_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
   
-  nr_init_frame_parms_ue(&ue->frame_parms);
+  nr_init_frame_parms_ue(&ue->frame_parms,NR_MU_1,NORMAL);
   phy_init_nr_top(ue);
 
   // many memory allocation sizes are hard coded
@@ -943,28 +942,13 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) {
 
 void phy_init_nr_top(PHY_VARS_NR_UE *ue)
 {
-	NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
-	NR_UE_DLSCH_t *dlsch0 = ue->dlsch[0][0][0];
-	dlsch0 =(NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));
-
+  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  NR_UE_DLSCH_t *dlsch0 = ue->dlsch[0][0][0];
+  dlsch0 =(NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));
+  
   crcTableInit();
 
-  ccodedot11_init();
-  ccodedot11_init_inv();
-
-  ccodelte_init();
-  ccodelte_init_inv();
-
-  //treillis_table_init();
-
-  phy_generate_viterbi_tables();
-  phy_generate_viterbi_tables_lte();
-
-  //init_td8();
-  //init_td16();
-#ifdef __AVX2__
-  //init_td16avx2();
-#endif
+  init_dfts();
 
   init_context_synchro_nr(frame_parms);
 
diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c
index 978b8a3ae7..0c1539835a 100644
--- a/openair1/PHY/INIT/nr_parms.c
+++ b/openair1/PHY/INIT/nr_parms.c
@@ -26,18 +26,20 @@
 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, 16, 32};
 
-int nr_init_frame_parms(nfapi_nr_config_request_t* config,
-                        NR_DL_FRAME_PARMS *frame_parms)
+
+int nr_init_frame_parms0(
+			 NR_DL_FRAME_PARMS *frame_parms,
+			 int mu,
+			 int Ncp)
+
 {
 
-  int N_RB = config->rf_config.dl_carrier_bandwidth.value;
-  int Ncp = config->subframe_config.dl_cyclic_prefix_type.value;
-  int mu = config->subframe_config.numerology_index_mu.value;
+
 
 #if DISABLE_LOG_X
-  printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp);
+  printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, frame_parms->N_RB_DL, Ncp);
 #else
-  LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp);
+  LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, frame_parms->N_RB_DL, Ncp);
 #endif
 
   if (Ncp == NFAPI_CP_EXTENDED)
@@ -54,7 +56,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
       frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1];
       frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_1];
 
-      switch(N_RB){
+      switch(frame_parms->N_RB_DL){
         case 11:
         case 24:
         case 38:
@@ -88,18 +90,30 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
             frame_parms->nb_prefix_samples0 = 264;
             frame_parms->nb_prefix_samples = 216;
           }
-          else {
-            frame_parms->ofdm_symbol_size = 4096;
-            frame_parms->first_carrier_offset = 2794; //4096 - 1302
-            frame_parms->nb_prefix_samples0 = 352;
-            frame_parms->nb_prefix_samples = 288;
-          }
+	  else {
+	    frame_parms->ofdm_symbol_size = 4096;
+	    frame_parms->first_carrier_offset = 2794; //4096 - 1302
+	    frame_parms->nb_prefix_samples0 = 352;
+	    frame_parms->nb_prefix_samples = 288;
+	  }
           break;
 
         case 245:
+	  AssertFatal(frame_parms->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",frame_parms->N_RB_DL,mu); 
+	  frame_parms->ofdm_symbol_size = 4096;
+	  frame_parms->first_carrier_offset = 2626; //4096 - 1478
+	  frame_parms->nb_prefix_samples0 = 352;
+	  frame_parms->nb_prefix_samples = 288;
+	  break;
         case 273:
+	  AssertFatal(frame_parms->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",frame_parms->N_RB_DL,mu); 
+	  frame_parms->ofdm_symbol_size = 4096;
+	  frame_parms->first_carrier_offset = 2458; //4096 - 1638
+	  frame_parms->nb_prefix_samples0 = 352;
+	  frame_parms->nb_prefix_samples = 288;
+	  break;
       default:
-        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB, mu, frame_parms);
+        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", frame_parms->N_RB_DL, mu, frame_parms);
       }
       break;
 
@@ -107,7 +121,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
       frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2];
       frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_2];
 
-      switch(N_RB){ //FR1 bands only
+      switch(frame_parms->N_RB_DL){ //FR1 bands only
         case 11:
         case 18:
         case 38:
@@ -121,7 +135,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
         case 121:
         case 135:
       default:
-        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB, mu, frame_parms);
+        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", frame_parms->N_RB_DL, mu, frame_parms);
       }
       break;
 
@@ -152,146 +166,27 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
   frame_parms->initial_bwp_dl.bwp_id = 0;
   frame_parms->initial_bwp_dl.scs = frame_parms->subcarrier_spacing;
   frame_parms->initial_bwp_dl.location = 0;
-  frame_parms->initial_bwp_dl.N_RB = N_RB;
+  frame_parms->initial_bwp_dl.N_RB = frame_parms->N_RB_DL;
   frame_parms->initial_bwp_dl.cyclic_prefix = Ncp;
   frame_parms->initial_bwp_dl.ofdm_symbol_size = frame_parms->ofdm_symbol_size;
 
   return 0;
 }
 
-int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms)
-{
-
-  int N_RB = 106;
-  int Ncp = 0;
-  int mu = 1;
-
-#if DISABLE_LOG_X
-  printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp);
-#else
-  LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp);
-#endif
-
-
-  if (Ncp == EXTENDED)
-    AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu);
-
-  switch(mu) {
-
-    case NR_MU_0: //15kHz scs
-      frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0];
-      frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_0];
-      break;
-
-    case NR_MU_1: //30kHz scs
-      frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1];
-      frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_1];
-
-      switch(N_RB){
-        case 11:
-        case 24:
-        case 38:
-        case 78:
-        case 51:
-        case 65:
-
-        case 106: //40 MHz
-          if (frame_parms->threequarter_fs) {
-            frame_parms->ofdm_symbol_size = 1536;
-            frame_parms->first_carrier_offset = 900; //1536 - 636
-            frame_parms->nb_prefix_samples0 = 132;
-            frame_parms->nb_prefix_samples = 108;
-          }
-          else {
-            frame_parms->ofdm_symbol_size = 2048;
-            frame_parms->first_carrier_offset = 1412; //2048 - 636
-            frame_parms->nb_prefix_samples0 = 176;
-            frame_parms->nb_prefix_samples = 144;
-          }
-          break;
-
-        case 133:
-        case 162:
-        case 189:
-
-        case 217: //80 MHz
-          if (frame_parms->threequarter_fs) {
-            frame_parms->ofdm_symbol_size = 3072;
-            frame_parms->first_carrier_offset = 1770; //3072 - 1302
-            frame_parms->nb_prefix_samples0 = 264;
-            frame_parms->nb_prefix_samples = 216;
-          }
-          else {
-            frame_parms->ofdm_symbol_size = 4096;
-            frame_parms->first_carrier_offset = 2794; //4096 - 1302
-            frame_parms->nb_prefix_samples0 = 352;
-            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", N_RB, mu, frame_parms);
-      }
-      break;
-
-    case NR_MU_2: //60kHz scs
-      frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2];
-      frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_2];
-
-      switch(N_RB){ //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", N_RB, mu, frame_parms);
-      }
-      break;
-
-    case NR_MU_3:
-      frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
-      frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
-      break;
-
-    case NR_MU_4:
-      frame_parms->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4];
-      frame_parms->slots_per_subframe = nr_slots_per_subframe[NR_MU_4];
-      break;
-
-  default:
-    AssertFatal(1==0,"Invalid numerology index %d", mu);
-  }
+int nr_init_frame_parms(nfapi_nr_config_request_t* config,
+                        NR_DL_FRAME_PARMS *frame_parms) {
 
-    frame_parms->nb_prefix_samples0 = 160;
-    frame_parms->nb_prefix_samples = 144;
-    frame_parms->symbols_per_tti = 14;
-    frame_parms->numerology_index = 0;
-    frame_parms->ttis_per_subframe = 1;
-    frame_parms->slots_per_tti = 2; //only slot config 1 is supported     
+  nr_init_frame_parms0(frame_parms,
+                       config->subframe_config.numerology_index_mu.value,
+                       config->subframe_config.dl_cyclic_prefix_type.value);
+}
 
-    frame_parms->ofdm_symbol_size = 2048;
-    frame_parms->samples_per_tti = 30720;
-    frame_parms->samples_per_subframe = 30720 * frame_parms->ttis_per_subframe;
-    //frame_parms->first_carrier_offset = 2048-600;
+int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,
+			   int mu, 
+			   int Ncp) 
+{
 
-  frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe;
-  frame_parms->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
-  frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe;
-  frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP;
-  //frame_parms->samples_per_subframe = (frame_parms->samples_per_subframe_wCP + (frame_parms->nb_prefix_samples0 * frame_parms->slots_per_subframe) +
-  //                                    (frame_parms->nb_prefix_samples * frame_parms->slots_per_subframe * (frame_parms->symbols_per_slot - 1)));
-  frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe;
-  frame_parms->freq_range = (frame_parms->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
+  nr_init_frame_parms0(frame_parms,mu,Ncp);
 
   return 0;
 }
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index 84a2925a82..bdee72bd2a 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -377,11 +377,12 @@ void phy_config_request(PHY_Config_t *phy_config);
 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_init_frame_parms(nfapi_nr_config_request_t* config, NR_DL_FRAME_PARMS *frame_parms);
-int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms);
+int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,int mu,int Ncp);
 int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
 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);
+void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu);
 void phy_free_nr_gNB(PHY_VARS_gNB *gNB);
 int l1_north_init_gNB(void);
 
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c
index 2fa57d0e14..594a10da95 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c
@@ -285,6 +285,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
   init_frame_parms(frame_parms,1);
   /*
   LOG_M("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
+
   exit(-1);
   */
   sync_pos = lte_sync_time(ue->common_vars.rxdata,
diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c
index f8b058935c..ddbc4af930 100644
--- a/openair1/PHY/MODULATION/ofdm_mod.c
+++ b/openair1/PHY/MODULATION/ofdm_mod.c
@@ -36,7 +36,7 @@ This section deals with basic functions for OFDM Modulation.
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "modulation_common.h"
 #include "PHY/LTE_TRANSPORT/transport_common_proto.h"
-//#define DEBUG_OFDM_MOD
+#define DEBUG_OFDM_MOD
 
 
 void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms)
@@ -122,10 +122,10 @@ void PHY_ofdm_mod(int *input,                       /// pointer to complex input
 
   case 3072:
     idft = idft3072;
-
+    break;
   case 4096:
     idft = idft4096;
-
+    break;
   default:
     idft = idft512;
     break;
diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index 5ad1648490..84d400a670 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -61,7 +61,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
   int uespec_pilot[9][1200];*/
 
   void (*dft)(int16_t *,int16_t *, int);
-  int tmp_dft_in[2048] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
+  int tmp_dft_in[8192] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
 
   switch (frame_parms->ofdm_symbol_size) {
   case 128:
@@ -88,6 +88,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
     dft = dft2048;
     break;
 
+  case 4096:
+    dft = dft4096;
+    break;
+
+  case 8192:
+    dft = dft8192;
+    break;
+
   default:
     dft = dft512;
     break;
diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h
index 2d7d11cb70..2f39f26ee4 100644
--- a/openair1/PHY/NR_REFSIG/pss_nr.h
+++ b/openair1/PHY/NR_REFSIG/pss_nr.h
@@ -63,7 +63,7 @@
 
 /* PSS configuration */
 
-#define SYNCHRO_FFT_SIZE_MAX           (2048)                       /* maximum size of fft for synchronisation */
+#define SYNCHRO_FFT_SIZE_MAX           (8192)                       /* maximum size of fft for synchronisation */
 
 #define  NO_RATE_CHANGE                (1)
 
@@ -102,13 +102,18 @@ EXTERN int16_t *primary_synchro_nr[NUMBER_PSS_SEQUENCE]
 = { NULL, NULL, NULL}
 #endif
 ;
+EXTERN int16_t *primary_synchro_nr2[NUMBER_PSS_SEQUENCE]
+#ifdef INIT_VARIABLES_PSS_NR_H
+= { NULL, NULL, NULL}
+#endif
+;
 EXTERN int16_t *primary_synchro_time_nr[NUMBER_PSS_SEQUENCE]
 #ifdef INIT_VARIABLES_PSS_NR_H
 = { NULL, NULL, NULL}
 #endif
 ;
 
-EXTERN int *pss_corr_ue[NUMBER_PSS_SEQUENCE]
+EXTERN int64_t *pss_corr_ue[NUMBER_PSS_SEQUENCE]
 #ifdef INIT_VARIABLES_PSS_NR_H
 = { NULL, NULL, NULL}
 #endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_pss.c b/openair1/PHY/NR_TRANSPORT/nr_pss.c
index 1f653038a6..4b71e79a6c 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_pss.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_pss.c
@@ -53,6 +53,7 @@ int nr_generate_pss(  int16_t *d_pss,
 
 #ifdef NR_PSS_DEBUG
   write_output("d_pss.m", "d_pss", (void*)d_pss, NR_PSS_LENGTH, 1, 0);
+  printf("PSS: ofdm_symbol_size %d, first_carrier_offset %d\n",frame_parms->ofdm_symbol_size,frame_parms->first_carrier_offset);
 #endif
 
   /// Resource mapping
@@ -63,9 +64,12 @@ int nr_generate_pss(  int16_t *d_pss,
 
     // PSS occupies a predefined position (subcarriers 56-182, symbol 0) within the SSB block starting from
     k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; //and
+    if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
+
     l = ssb_start_symbol;
 
     for (m = 0; m < NR_PSS_LENGTH; m++) {
+      printf("pss: writing position k %d / %d\n",k,frame_parms->ofdm_symbol_size);
       ((int16_t*)txdataF[aa])[2*(l*frame_parms->ofdm_symbol_size + k)] = (a * d_pss[m]) >> 15;
       k++;
 
@@ -75,7 +79,9 @@ int nr_generate_pss(  int16_t *d_pss,
   }
 
 #ifdef NR_PSS_DEBUG
-  write_output("pss_0.m", "pss_0", (void*)&txdataF[0][2*l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1);
+  LOG_M("pss_0.m", "pss_0", 
+	(void*)&txdataF[0][ssb_start_symbol*frame_parms->ofdm_symbol_size], 
+	frame_parms->ofdm_symbol_size, 1, 1);
 #endif
 
   return 0;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_sss.c b/openair1/PHY/NR_TRANSPORT/nr_sss.c
index 865e14465e..023279f39e 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_sss.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_sss.c
@@ -21,7 +21,7 @@
 
 #include "PHY/NR_TRANSPORT/nr_transport.h"
 
-#define NR_SSS_DEBUG
+//#define NR_SSS_DEBUG
 
 int nr_generate_sss(  int16_t *d_sss,
                       int32_t **txdataF,
@@ -76,7 +76,6 @@ int nr_generate_sss(  int16_t *d_sss,
 
     for (int m = 0; m < NR_SSS_LENGTH; m++) {
       ((int16_t*)txdataF[aa])[2*(l*frame_parms->ofdm_symbol_size + k)] = (a * d_sss[m]) >> 15;
-      printf("sss %d: %d\n",m,((int16_t*)txdataF[aa])[2*(l*frame_parms->ofdm_symbol_size + k)]);
       k++;
 
       if (k >= frame_parms->ofdm_symbol_size)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index 53599671fd..dde080bba8 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -145,26 +145,19 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
 {
 
   int32_t sync_pos, sync_pos2, sync_pos_slot; // k_ssb, N_ssb_crb,
-  int32_t metric_fdd_ncp=0;
-  uint8_t phase_fdd_ncp;
+  int32_t metric_tdd_ncp=0;
+  uint8_t phase_tdd_ncp;
 
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   int ret=-1;
   int rx_power=0; //aarx,
   //nfapi_nr_config_request_t* config;
 
-  /*offset parameters to be updated from higher layer */
-  //k_ssb =0;
-  //N_ssb_crb = 0;
 
-  /*#ifdef OAI_USRP
-  __m128i *rxdata128;
-  #endif*/
-  //  LOG_I(PHY,"**************************************************************\n");
-  // First try FDD normal prefix
+  // First try TDD normal prefix, mu 1
   frame_parms->Ncp=NORMAL;
   frame_parms->frame_type=TDD;
-  nr_init_frame_parms_ue(frame_parms);
+  nr_init_frame_parms_ue(frame_parms,NR_MU_1,NORMAL);
   LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", ue->frame_parms.N_RB_DL);
   /*
   write_output("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
@@ -183,6 +176,8 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
   *                     --------------------------
   *          sync_pos            SS/PBCH block
   */
+
+
   cnt++;
   if (1){ // (cnt>100)
     cnt =0;
@@ -190,22 +185,13 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
   /* process pss search on received buffer */
   sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE);
 
-  sync_pos_slot = (frame_parms->samples_per_tti>>1) - 3*(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
-
-  sync_pos = sync_pos_slot+frame_parms->nb_prefix_samples;
-
+  
   if (sync_pos >= frame_parms->nb_prefix_samples)
-      sync_pos2 = sync_pos - frame_parms->nb_prefix_samples;
-    else
-      sync_pos2 = sync_pos + FRAME_LENGTH_COMPLEX_SAMPLES - frame_parms->nb_prefix_samples;
-
-  /* offset is used by sss serach as it is returned from pss search */
-  if (sync_pos2 >= sync_pos_slot)
-      ue->rx_offset = sync_pos2 - sync_pos_slot;
-    else
-      ue->rx_offset = FRAME_LENGTH_COMPLEX_SAMPLES + sync_pos2 - sync_pos_slot;
-
-  LOG_D(PHY,"sync_pos %d sync_pos_slot %d rx_offset %d\n",sync_pos,sync_pos_slot, ue->rx_offset);
+      ue->ssb_offset = sync_pos - frame_parms->nb_prefix_samples;
+  else
+    ue->ssb_offset = sync_pos + FRAME_LENGTH_COMPLEX_SAMPLES - frame_parms->nb_prefix_samples;
+  
+  LOG_D(PHY,"sync_pos %d ssb_offset %d\n",sync_pos,ue->ssb_offset);
 
 
   //  write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
@@ -221,19 +207,20 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
     LOG_I(PHY,"Calling sss detection (normal CP)\n");
 #endif
 
-    rx_sss_nr(ue,&metric_fdd_ncp,&phase_fdd_ncp);
+    rx_sss_nr(ue,&metric_tdd_ncp,&phase_tdd_ncp);
 
-    nr_init_frame_parms_ue(&ue->frame_parms);
+    nr_init_frame_parms_ue(&ue->frame_parms,NR_MU_1,NORMAL);
 
     nr_gold_pbch(ue);
     ret = nr_pbch_detection(ue,mode);
     
     nr_gold_pdcch(ue,0, 2);
+    /*
     int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
-	frame_parms->nb_prefix_samples0 = 0;
-  
-    nr_slot_fep(ue,0, 0, ue->rx_offset, 0, 1, NR_PDCCH_EST);
-    nr_slot_fep(ue,1, 0, ue->rx_offset, 0, 1, NR_PDCCH_EST);
+    frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples.
+	  
+    nr_slot_fep(ue,0, 0, ue->ssb_offset, 0, 1, NR_PDCCH_EST);
+    nr_slot_fep(ue,1, 0, ue->ssb_offset, 0, 1, NR_PDCCH_EST);
     frame_parms->nb_prefix_samples0 = nb_prefix_samples0;	
 
     LOG_I(PHY,"[UE  %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
@@ -241,18 +228,16 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
               ue->proc.proc_rxtx[0].frame_rx,
               ue->rx_offset,
               ue->common_vars.freq_offset );
-
-    //ret = -1;  //to be deleted
-    //   write_output("rxdata2.m","rxd2",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
+    */
 
 #ifdef DEBUG_INITIAL_SYNCH
-    LOG_I(PHY,"FDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
-          frame_parms->Nid_cell,metric_fdd_ncp,phase_fdd_ncp,flip_fdd_ncp,ret);
+    LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
+          frame_parms->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,flip_tdd_ncp,ret);
 #endif
   }
   else {
 #ifdef DEBUG_INITIAL_SYNCH
-    LOG_I(PHY,"FDD Normal prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot);
+    LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot);
 #endif
   }
   }
@@ -370,12 +355,6 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
 #ifdef DEBUG_INITIAL_SYNC
     LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id);
     LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n",ue->Mod_id,sync_pos,ue->common_vars.eNb_id);
-    /*      LOG_I(PHY,"[UE%d] Initial sync: (metric fdd_ncp %d (%d), metric fdd_ecp %d (%d), metric_tdd_ncp %d (%d), metric_tdd_ecp %d (%d))\n",
-          ue->Mod_id,
-          metric_fdd_ncp,Nid_cell_fdd_ncp,
-          metric_fdd_ecp,Nid_cell_fdd_ecp,
-          metric_tdd_ncp,Nid_cell_tdd_ncp,
-          metric_tdd_ecp,Nid_cell_tdd_ecp);*/
     LOG_I(PHY,"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d\n",ue->Mod_id,
           frame_parms->Nid_cell,frame_parms->frame_type);
 #endif
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 954099410f..c361daab01 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -1362,6 +1362,7 @@ void generate_RIV_tables(void);
   N_RB_DL, PHICH_CONFIG and Nid_cell) and the UE can begin decoding PDCCH and DLSCH SI to retrieve the rest.  Once these
   parameters are know, the routine calls some basic initialization routines (cell-specific reference signals, etc.)
   @param phy_vars_ue Pointer to UE variables
+  @param mode current running mode
 */
 int nr_initial_sync(PHY_VARS_NR_UE *phy_vars_ue, runmode_t mode);
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index 8c1f96b6ee..fc0cf87e6c 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -88,6 +88,14 @@ void *get_idft(int ofdm_symbol_size)
       idft = idft2048;
       break;
 
+    case 4096:
+      idft = idft4096;
+      break;
+
+    case 8192:
+      idft = idft8192;
+      break;
+
     default:
       printf("function get_idft : unsupported ofdm symbol size \n");
       assert(0);
@@ -137,6 +145,14 @@ void *get_dft(int ofdm_symbol_size)
       dft = dft2048;
       break;
 
+    case 4096:
+      dft = dft4096;
+      break;
+
+    case 8192:
+      dft = dft8192;
+      break;
+
     default:
       printf("function get_dft : unsupported ofdm symbol size \n");
       assert(0);
@@ -161,12 +177,15 @@ void *get_dft(int ofdm_symbol_size)
 
 void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
 {
+  AssertFatal(ofdm_symbol_size > 127,"Illegal ofdm_symbol_size %d\n",ofdm_symbol_size);
+  AssertFatal(N_ID_2>=0 && N_ID_2 <=2,"Illegal N_ID_2 %d\n",N_ID_2);
   int16_t d_pss[LENGTH_PSS_NR];
   int16_t x[LENGTH_PSS_NR];
   int16_t *primary_synchro_time = primary_synchro_time_nr[N_ID_2];
   unsigned int length = ofdm_symbol_size;
   unsigned int size = length * IQ_SIZE; /* i & q */
   int16_t *primary_synchro = primary_synchro_nr[N_ID_2]; /* pss in complex with alternatively i then q */
+  int16_t *primary_synchro2 = primary_synchro_nr2[N_ID_2]; /* pss in complex with alternatively i then q */
   void (*idft)(int16_t *,int16_t *, int);
 
   #define INITIAL_PSS_NR    (7)
@@ -197,9 +216,11 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
 #if 1
     primary_synchro[2*i] = (d_pss[i] * SHRT_MAX)>>SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */
     primary_synchro[2*i+1] = 0;
+    primary_synchro2[i] = d_pss[i];
 #else
     primary_synchro[2*i] = d_pss[i] * AMP;
     primary_synchro[2*i+1] = 0;
+    primary_synchro2[i] = d_pss[i];
 #endif
   }
 
@@ -212,7 +233,7 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
     sprintf(sequence_name, "pss_seq_%d_%d", N_ID_2, length);
     printf("file %s sequence %s\n", output_file, sequence_name);
 
-    write_output(output_file, sequence_name, primary_synchro, LENGTH_PSS_NR, 1, 1);
+    LOG_M(output_file, sequence_name, primary_synchro, LENGTH_PSS_NR, 1, 1);
   }
 
 #endif
@@ -247,10 +268,8 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
 
     k++;
 
-    if (k >= length) {
-      k++;
-      k-=length;
-    }
+    if (k == length) k=0;
+    
   }
 
   /* IFFT will give temporal signal of Pss */
@@ -269,8 +288,6 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
 #ifdef DBG_PSS_NR
 
   if (N_ID_2 == 0) {
-    for (int i=0;i<16;i++) printf("f %d: %d,%d\n",i,synchroF_tmp[i<<1],synchroF_tmp[1+(i<<1)]);
-    for (int i=0;i<16;i++) printf("t %d: %d,%d\n",i,primary_synchro_time[i<<1],primary_synchro_time[1+(i<<1)]);
     char output_file[255];
     char sequence_name[255];
     sprintf(output_file, "%s%d_%d%s","pss_seq_t_", N_ID_2, length, ".m");
@@ -278,10 +295,10 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
 
     printf("file %s sequence %s\n", output_file, sequence_name);
 
-    write_output(output_file, sequence_name, primary_synchro_time, length, 1, 1);
+    LOG_M(output_file, sequence_name, primary_synchro_time, length, 1, 1);
     sprintf(output_file, "%s%d_%d%s","pss_seq_f_", N_ID_2, length, ".m");
     sprintf(sequence_name, "%s%d_%d","pss_seq_f_", N_ID_2, length);
-    write_output(output_file, sequence_name, synchroF_tmp, length, 1, 1);
+    LOG_M(output_file, sequence_name, synchroF_tmp, length, 1, 1);
   }
 
 #endif
@@ -293,7 +310,7 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
 
   if ((N_ID_2 == 0) && (length == 256)) {
 
-    write_output("pss_f00.m","pss_f00",synchro_tmp,length,1,1);
+    LOG_M("pss_f00.m","pss_f00",synchro_tmp,length,1,1);
 
 
     bzero(synchroF_tmp, size);
@@ -306,7 +323,7 @@ void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
         1);                 /* scaling factor */
 
     if ((N_ID_2 == 0) && (length == 256)) {
-      write_output("pss_f_0.m","pss_f_0",synchroF_tmp,length,1,1);
+      LOG_M("pss_f_0.m","pss_f_0",synchroF_tmp,length,1,1);
     }
 
     /* check Pss */
@@ -352,8 +369,9 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
   int sizePss = LENGTH_PSS_NR * IQ_SIZE;  /* complex value i & q signed 16 bits */
   int size = ofdm_symbol_size * IQ_SIZE; /* i and q samples signed 16 bits */
   int16_t *p = NULL;
-  int *q = NULL;
+  int64_t *q = NULL;
 
+  AssertFatal(ofdm_symbol_size > 127, "illegal ofdm_symbol_size %d\n",ofdm_symbol_size);
   for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
 
     p = malloc16(sizePss); /* pss in complex with alternatively i then q */
@@ -365,7 +383,11 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
      msg("Fatal memory allocation problem \n");
      assert(0);
     }
-
+    p = malloc(LENGTH_PSS_NR*2);
+    if (p != NULL) {
+      primary_synchro_nr2[i] = p;
+      bzero( primary_synchro_nr2[i],LENGTH_PSS_NR*2);
+    }
     p = malloc16(size);
     if (p != NULL) {
       primary_synchro_time_nr[i] = p;
@@ -376,8 +398,8 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
      assert(0);
     }
 
-    size = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms_ue->samples_per_subframe;
-    q = malloc16(size);
+    size = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int64_t)*frame_parms_ue->samples_per_subframe;
+    q = (int64_t*)malloc16(size);
     if (q != NULL) {
       pss_corr_ue[i] = q;
       bzero( pss_corr_ue[i], size);
@@ -587,6 +609,8 @@ 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 = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti;
 
+  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;
@@ -640,7 +664,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
 
   int samples_for_frame = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
 
-  write_output("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], samples_for_frame, 1, 1);
+  LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], samples_for_frame, 1, 1);
 
 #endif
 
@@ -649,7 +673,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
     rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
 
     for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) {
-      rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_subframe*10+2048)*sizeof(int32_t));
+      rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_subframe*10+8192)*sizeof(int32_t));
     }
 #ifdef SYNCHRO_DECIMAT
 
@@ -664,7 +688,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
 
 #ifdef DBG_PSS_NR
 
-  write_output("rxdata0_des.m","rxd0_des", &rxdata[0][0], samples_for_frame,1,1);
+  LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], samples_for_frame,1,1);
 
 #endif
 
@@ -719,6 +743,11 @@ static inline int abs32(int x)
   return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1]));
 }
 
+static inline int64_t abs64(int64_t x)
+{
+  return (((int64_t)((int32_t*)&x)[0])*((int64_t)((int32_t*)&x)[0]) + ((int64_t)((int32_t*)&x)[1])*((int64_t)((int32_t*)&x)[1]));
+}
+
 /*******************************************************************
 *
 * NAME :         pss_search_time_nr
@@ -775,14 +804,16 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
                        NR_DL_FRAME_PARMS *frame_parms,
                        int *eNB_id)
 {
-  unsigned int n, ar, peak_position, peak_value, pss_source;
-  int result;
-  int synchro_out;
-  unsigned int tmp[NUMBER_PSS_SEQUENCE];
-  unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->ttis_per_subframe*frame_parms->samples_per_tti);  /* 1 frame for now, it should be 2 TODO_NR */
+  unsigned int n, ar, peak_position, pss_source;
+  int64_t peak_value;
+  int64_t result;
+  int64_t avg[NUMBER_PSS_SEQUENCE];
 
+
+  unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe);  /* 1 frame for now, it should be 2 TODO_NR */
+
+  AssertFatal(length>0,"illegal length %d\n",length);
   for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
-	  tmp[i] = 0;
     if (pss_corr_ue[i] == NULL) {
       msg("[SYNC TIME] pss_corr_ue[%d] not yet allocated! Exiting.\n", i);
       return(-1);
@@ -793,57 +824,73 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
   peak_position = 0;
   pss_source = 0;
 
+  int maxval=0;
+  for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) {
+    maxval = max(maxval,primary_synchro_time_nr[0][i]);
+    maxval = max(maxval,-primary_synchro_time_nr[0][i]);
+    maxval = max(maxval,primary_synchro_time_nr[1][i]);
+    maxval = max(maxval,-primary_synchro_time_nr[1][i]);
+    maxval = max(maxval,primary_synchro_time_nr[2][i]);
+    maxval = max(maxval,-primary_synchro_time_nr[2][i]);
+
+  }
+  int shift = log2_approx(maxval);//*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*2);
+
   /* Search pss in the received buffer each 4 samples which ensures a memory alignment on 128 bits (32 bits x 4 ) */
   /* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */
   /* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
+  for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) avg[pss_index]=0;
+
   for (n=0; n < length; n+=4) {
 
     for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
 
       pss_corr_ue[pss_index][n] = 0; /* clean correlation for position n */
 
-      synchro_out = 0;
-
       if ( n < (length - frame_parms->ofdm_symbol_size)) {
 
         /* calculate dot product of primary_synchro_time_nr and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n]; */
         for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
 
           /* perform correlation of rx data and pss sequence ie it is a dot product */
-          result  = dot_product((short*)primary_synchro_time_nr[pss_index], (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, DOT_PRODUCT_SCALING_SHIFT);
+          result  = dot_product64((short*)primary_synchro_time_nr[pss_index], 
+				  (short*) &(rxdata[ar][n]), 
+				  frame_parms->ofdm_symbol_size, 
+				  shift);
+	  pss_corr_ue[pss_index][n] += abs64(result);
+	  
+          //((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0];   /* real part */
+          //((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
+          //((short*)&synchro_out)[0] += ((short*) &result)[0];               /* real part */
+          //((short*)&synchro_out)[1] += ((short*) &result)[1];               /* imaginary part */
 
-          ((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0];   /* real part */
-          ((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
-          ((short*)&synchro_out)[0] += ((short*) &result)[0];               /* real part */
-          ((short*)&synchro_out)[1] += ((short*) &result)[1];               /* imaginary part */
         }
       }
 
-      pss_corr_ue[pss_index][n] = abs32(pss_corr_ue[pss_index][n]);
-
       /* calculate the absolute value of sync_corr[n] */
-      tmp[pss_index] = (abs32(synchro_out)) ;
-
-      if (tmp[pss_index] > peak_value) {
-        peak_value = tmp[pss_index];
+      avg[pss_index]+=pss_corr_ue[pss_index][n];
+      if (pss_corr_ue[pss_index][n] > peak_value) {
+        peak_value = pss_corr_ue[pss_index][n];
         peak_position = n;
         pss_source = pss_index;
 
-        //printf("pss_index %d: n %6d peak_value %10d, synchro_out (% 6d,% 6d) \n", pss_index, n, abs32(synchro_out),((int16_t*)&synchro_out)[0],((int16_t*)&synchro_out)[1]);
+        printf("pss_index %d: n %6d peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[pss_index][n]);
       }
     }
   }
 
+  for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) avg[pss_index]/=(length/4);
+
   *eNB_id = pss_source;
 
-  LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n", pss_source, peak_position, peak_value, dB_fixed(peak_value)/2);
+  LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB\n", pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]));
 
 //#ifdef DEBUG_PSS_NR
 
 #define  PSS_DETECTION_FLOOR_NR     (31)
-  if ((dB_fixed(peak_value)/2) > PSS_DETECTION_FLOOR_NR) {
+  if (peak_value > 5*avg[pss_source]) { //PSS_DETECTION_FLOOR_NR)
 
-    printf("[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n", pss_source, peak_position, peak_value,dB_fixed(peak_value)/2);
+    printf("[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB\n", pss_source, peak_position, (unsigned long long)peak_value,dB_fixed64(peak_value),dB_fixed64(avg[pss_source]));
   }
 //#endif
 
@@ -852,10 +899,11 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
   static debug_cnt = 0;
 
   if (debug_cnt == 0) {
-    write_output("pss_corr_ue0.m","pss_corr_ue0",pss_corr_ue[0],length,1,2);
-    write_output("pss_corr_ue1.m","pss_corr_ue1",pss_corr_ue[1],length,1,2);
-    write_output("pss_corr_ue2.m","pss_corr_ue2",pss_corr_ue[2],length,1,2);
-    write_output("rxdata0.m","rxd0",rxdata[0],length,1,1);
+    LOG_M("pss_corr_ue0.m","pss_corr_ue0",pss_corr_ue[0],length,1,6);
+    LOG_M("pss_corr_ue1.m","pss_corr_ue1",pss_corr_ue[1],length,1,6);
+    LOG_M("pss_corr_ue2.m","pss_corr_ue2",pss_corr_ue[2],length,1,6);
+    LOG_M("rxdata0.m","rxd0",rxdata[0],length,1,1);
+    exit(-1);
   } else {
     debug_cnt++;
   }
diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
index a29b676330..9d1fb40a22 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
@@ -213,10 +213,14 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
   uint8_t aarx,i;
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
 
-  pss = primary_synchro_nr[ue->common_vars.eNb_id];
+  pss = primary_synchro_nr2[ue->common_vars.eNb_id];
 
   sss_ext3 = (int16_t*)&sss_ext[0][0];
 
+#if 0
+  int16_t chest[2*LENGTH_PSS_NR];
+#endif
+
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
     sss_ext2 = (int16_t*)&sss_ext[aarx][0];
@@ -243,18 +247,28 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
 
 #endif
 
+  int32_t amp;
+  int shift;
     for (i = 0; i < LENGTH_PSS_NR; i++) {
 
       // This is H*(PSS) = R* \cdot PSS
-      tmp_re = (int16_t)(((pss_ext2[i*2] * (int32_t)pss[i*2])>>SCALING_CE_PSS_NR)   + ((pss_ext2[i*2+1] * (int32_t)pss[i*2+1])>>SCALING_CE_PSS_NR));
-      tmp_im = (int16_t)(((pss_ext2[i*2] * (int32_t)pss[i*2+1])>>SCALING_CE_PSS_NR) - ((pss_ext2[i*2+1] * (int32_t)pss[i*2])>>SCALING_CE_PSS_NR));
-      //printf("H*(%d,%d) : (%d,%d)\n",aarx,i,tmp_re,tmp_im);
-      //printf("pss(%d,%d) : (%d,%d)\n",aarx,i,pss[2*i],pss[2*i+1]);
-      //printf("pss_ext(%d,%d) : (%d,%d)\n",aarx,i,pss_ext2[2*i],pss_ext2[2*i+1]);
-
+      tmp_re = pss_ext2[i*2] * pss[i];
+      tmp_im = -pss_ext2[i*2+1] * pss[i];
+      
+      amp = (((int32_t)tmp_re)*tmp_re) + ((int32_t)tmp_im)*tmp_im;
+      shift = log2_approx(amp)/2;
+#if 0
+      printf("H*(%d,%d) : (%d,%d)\n",aarx,i,tmp_re,tmp_im);
+      printf("pss(%d,%d) : (%d,%d)\n",aarx,i,pss[2*i],pss[2*i+1]);
+      printf("pss_ext(%d,%d) : (%d,%d)\n",aarx,i,pss_ext2[2*i],pss_ext2[2*i+1]);
+      if (aarx==0) {
+       chest[i<<1]=tmp_re;
+       chest[1+(i<<1)]=tmp_im;
+      }
+#endif      
       // This is R(SSS) \cdot H*(PSS)
-      tmp_re2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2])>>SCALING_CE_PSS_NR)    - ((tmp_im * (int32_t)sss_ext2[i*2+1]>>SCALING_CE_PSS_NR)));
-      tmp_im2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2+1])>>SCALING_CE_PSS_NR)  + ((tmp_im * (int32_t)sss_ext2[i*2]>>SCALING_CE_PSS_NR)));
+      tmp_re2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2])>>shift)    - ((tmp_im * (int32_t)sss_ext2[i*2+1]>>shift)));
+      tmp_im2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2+1])>>shift)  + ((tmp_im * (int32_t)sss_ext2[i*2]>>shift)));
 
       // printf("SSSi(%d,%d) : (%d,%d)\n",aarx,i,sss_ext2[i<<1],sss_ext2[1+(i<<1)]);
       // printf("SSSo(%d,%d) : (%d,%d)\n",aarx,i,tmp_re2,tmp_im2);
@@ -268,7 +282,11 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
       }
     }
   }
-
+#if 0
+  LOG_M("pssrx.m","pssrx",pss,LENGTH_PSS_NR,1,1);
+  LOG_M("pss_ext.m","pssext",pss_ext2,LENGTH_PSS_NR,1,1);
+  LOG_M("psschest.m","pssch",chest,LENGTH_PSS_NR,1,1);
+#endif
 #if 0
 
   for (int i = 0; i < LENGTH_PSS_NR; i++) {
@@ -336,10 +354,8 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
 
       k++;
 
-      if (k >= ofdm_symbol_size) {
-	    k++;
-        k-=ofdm_symbol_size;
-      }
+      if (k == ofdm_symbol_size) k=0;
+      
     }
   }
 
@@ -423,23 +439,24 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
   /* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
 
   int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
-  frame_parms->nb_prefix_samples0 = 0;
+  // For now, symbol 0 = PSS/PBCH and it is never in symbol 0 or 7*2^mu (i.e. always shorter prefix)
+  frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples;
 
   // Do FFTs for SSS/PSS
   // SSS
   nr_slot_fep(ue,
-	      SSS_SYMBOL_NB,      // symbol number
+	      SSS_SYMBOL_NB-PSS_SYMBOL_NB,      // symbol number w.r.t. PSS
 	      0,                  // Ns slot number
-	      ue->rx_offset,      // sample_offset of int16_t
+	      ue->ssb_offset,      // sample_offset of int16_t
 	      0,                  // no_prefix
 	      1,                  // reset frequency estimation
 	      NR_SSS_EST);
 
   // PSS
   nr_slot_fep(ue,
-	      PSS_SYMBOL_NB,
 	      0,
-	      ue->rx_offset,
+	      0,
+	      ue->ssb_offset,
 	      0,
 	      1,
 	      NR_SSS_EST);
@@ -455,7 +472,7 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
 #ifdef DEBUG_PLOT_SSS
 
   write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_tti,1,1);
-  write_output("rxdataF0.m","rxF0",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[0]].rxdataF[0][frame_parms->ofdm_symbol_size*SSS_SYMBOL_NB],frame_parms->ofdm_symbol_size,2,1);
+  write_output("rxdataF0.m","rxF0",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[0]].rxdataF[0][frame_parms->ofdm_symbol_size*PSS_SYMBOL_NB],frame_parms->ofdm_symbol_size,2,1);
   write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1);
 
 #endif
@@ -469,7 +486,7 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
     printf("sss ref  [%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]);
     printf("sss ext  [%i] : %d %d \n", i, p[2*i], p[2*i+1]);
 
-    printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr[0][2*i], primary_synchro_nr[0][2*i+1]);
+    printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr2[0][2*i], primary_synchro_nr2[0][2*i+1]);
     printf("pss ext [%i] : %d %d \n", i, p2[2*i], p2[2*i+1]);
   }
 #endif
@@ -504,14 +521,14 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
 
 #endif
 
-#if 1
+#if 0
         int16_t *ps = (int16_t *)pss_ext;
 
         for (int i = 0; i < LENGTH_SSS_NR; i++) {
           printf("sss ref  [%i] : %d \n", i, d_sss[0][0][i]);
           printf("sss ext  [%i] : %d %d \n", i, sss[2*i], sss[2*i+1]);
 
-          printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr[0][2*i], primary_synchro_nr[0][2*i+1]);
+          printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr2[0][2*i], primary_synchro_nr2[0][2*i+1]);
           printf("pss ext [%i] : %d %d \n", i, ps[2*i], ps[2*i+1]);
         }
 #endif
@@ -522,8 +539,9 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
   /* cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */
   /* sinus   sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */
 
-  for (phase=0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) {  // phase offset between PSS and SSS
-    for (Nid1 = 0 ; Nid1 < N_ID_1_NUMBER; Nid1++) {          // all possible Nid1 values
+   for (Nid1 = 0 ; Nid1 < N_ID_1_NUMBER; Nid1++) {          // all possible Nid1 values
+      for (phase=0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) {  // phase offset between PSS and SSS
+
 
       metric = 0;
       metric_re = 0;
@@ -534,10 +552,11 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
       for (i=0; i < LENGTH_SSS_NR; i++) {
 
 	
-        metric_re += d[i]*(((phase_re_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR))
-                   + d[i]*(((phase_im_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) + ((phase_re_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR));
-	if (Nid1 ==0 && phase==3)
+        metric_re += d[i]*(((phase_re_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR));
+                   
+#if 0
 	  printf("i %d, phase %d/%d: metric %d, phase (%d,%d) sss (%d,%d) d %d\n",i,phase,PHASE_HYPOTHESIS_NUMBER,metric_re,phase_re_nr[phase],phase_im_nr[phase],sss[2*i],sss[1+(2*i)],d[i]);
+#endif
       }
 
       metric = metric_re;
diff --git a/openair1/PHY/TOOLS/cdot_prod.c b/openair1/PHY/TOOLS/cdot_prod.c
index 60bdcf45dd..63b74afe6d 100644
--- a/openair1/PHY/TOOLS/cdot_prod.c
+++ b/openair1/PHY/TOOLS/cdot_prod.c
@@ -158,6 +158,128 @@ int32_t dot_product(int16_t *x,
 #endif
 }
 
+int64_t dot_product64(int16_t *x,
+		      int16_t *y,
+		      uint32_t N, //must be a multiple of 8
+		      uint8_t output_shift)
+{
+
+  uint32_t n;
+
+#if defined(__x86_64__) || defined(__i386__)
+  __m128i *x128,*y128,mmtmp1,mmtmp2,mmtmp3,mmcumul,mmcumul_re,mmcumul_im;
+  __m128i minus_i = _mm_set_epi16(-1,1,-1,1,-1,1,-1,1);
+  int32_t result;
+
+  x128 = (__m128i*) x;
+  y128 = (__m128i*) y;
+
+  mmcumul_re = _mm_setzero_si128();
+  mmcumul_im = _mm_setzero_si128();
+
+  for (n=0; n<(N>>2); n++) {
+
+//    printf("n=%d, x128=%p, y128=%p\n",n,x128,y128);
+  //      print_shorts("x",&x128[0]);
+    //    print_shorts("y",&y128[0]);
+
+    // this computes Re(z) = Re(x)*Re(y) + Im(x)*Im(y)
+    mmtmp1 = _mm_madd_epi16(x128[0],y128[0]);
+      //  print_ints("retmp",&mmtmp1);
+    // mmtmp1 contains real part of 4 consecutive outputs (32-bit)
+
+    // shift and accumulate results
+    mmtmp1 = _mm_srai_epi32(mmtmp1,output_shift);
+    mmcumul_re = _mm_add_epi32(mmcumul_re,mmtmp1);
+        //print_ints("re",&mmcumul_re);
+
+
+    // this computes Im(z) = Re(x)*Im(y) - Re(y)*Im(x)
+    mmtmp2 = _mm_shufflelo_epi16(y128[0],_MM_SHUFFLE(2,3,0,1));
+        //print_shorts("y",&mmtmp2);
+    mmtmp2 = _mm_shufflehi_epi16(mmtmp2,_MM_SHUFFLE(2,3,0,1));
+        //print_shorts("y",&mmtmp2);
+    mmtmp2 = _mm_sign_epi16(mmtmp2,minus_i);
+          //  print_shorts("y",&mmtmp2);
+
+    mmtmp3 = _mm_madd_epi16(x128[0],mmtmp2);
+            //print_ints("imtmp",&mmtmp3);
+    // mmtmp3 contains imag part of 4 consecutive outputs (32-bit)
+
+    // shift and accumulate results
+    mmtmp3 = _mm_srai_epi32(mmtmp3,output_shift);
+    mmcumul_im = _mm_add_epi32(mmcumul_im,mmtmp3);
+        //print_ints("im",&mmcumul_im);
+
+    x128++;
+    y128++;
+  }
+
+  // this gives Re Re Im Im
+  mmcumul = _mm_hadd_epi32(mmcumul_re,mmcumul_im);
+    //print_ints("cumul1",&mmcumul);
+
+  // this gives Re Im Re Im
+  mmcumul = _mm_hadd_epi32(mmcumul,mmcumul);
+
+    //print_ints("cumul2",&mmcumul);
+
+
+  //mmcumul = _mm_srai_epi32(mmcumul,output_shift);
+  // extract the lower half
+  result = _mm_extract_epi64(mmcumul,0);
+  //printf("result: (%d,%d)\n",((int32_t*)&result)[0],((int32_t*)&result)[1]); 
+  _mm_empty();
+  _m_empty();
+ 
+  return(result);
+
+#elif defined(__arm__)
+  int16x4_t *x_128=(int16x4_t*)x;
+  int16x4_t *y_128=(int16x4_t*)y;
+  int32x4_t tmp_re,tmp_im;
+  int32x4_t tmp_re1,tmp_im1;
+  int32x4_t re_cumul,im_cumul;
+  int32x2_t re_cumul2,im_cumul2;
+  int32x4_t shift = vdupq_n_s32(-output_shift); 
+  int32x2x2_t result2;
+  int16_t conjug[4]__attribute__((aligned(16))) = {-1,1,-1,1} ;
+
+  re_cumul = vdupq_n_s32(0);
+  im_cumul = vdupq_n_s32(0); 
+
+  for (n=0; n<(N>>2); n++) {
+
+    tmp_re  = vmull_s16(*x_128++, *y_128++);
+    //tmp_re = [Re(x[0])Re(y[0]) Im(x[0])Im(y[0]) Re(x[1])Re(y[1]) Im(x[1])Im(y[1])] 
+    tmp_re1 = vmull_s16(*x_128++, *y_128++);
+    //tmp_re1 = [Re(x1[1])Re(x2[1]) Im(x1[1])Im(x2[1]) Re(x1[1])Re(x2[2]) Im(x1[1])Im(x2[2])] 
+    tmp_re  = vcombine_s32(vpadd_s32(vget_low_s32(tmp_re),vget_high_s32(tmp_re)),
+                           vpadd_s32(vget_low_s32(tmp_re1),vget_high_s32(tmp_re1)));
+    //tmp_re = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2]) Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] 
+
+    tmp_im  = vmull_s16(vrev32_s16(vmul_s16(*x_128++,*(int16x4_t*)conjug)),*y_128++);
+    //tmp_im = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
+    tmp_im1 = vmull_s16(vrev32_s16(vmul_s16(*x_128++,*(int16x4_t*)conjug)),*y_128++);
+    //tmp_im1 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
+    tmp_im  = vcombine_s32(vpadd_s32(vget_low_s32(tmp_im),vget_high_s32(tmp_im)),
+                           vpadd_s32(vget_low_s32(tmp_im1),vget_high_s32(tmp_im1)));
+    //tmp_im = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
+
+    re_cumul = vqaddq_s32(re_cumul,vqshlq_s32(tmp_re,shift));
+    im_cumul = vqaddq_s32(im_cumul,vqshlq_s32(tmp_im,shift));
+  }
+  
+  re_cumul2 = vpadd_s32(vget_low_s32(re_cumul),vget_high_s32(re_cumul));
+  im_cumul2 = vpadd_s32(vget_low_s32(im_cumul),vget_high_s32(im_cumul));
+  re_cumul2 = vpadd_s32(re_cumul2,re_cumul2);
+  im_cumul2 = vpadd_s32(im_cumul2,im_cumul2);
+  result2   = vzip_s32(re_cumul2,im_cumul2);
+  return(vget_lane_s32(result2.val[0],0));
+#endif
+}
+
+
 
 #ifdef MAIN
 void print_bytes(char *s,__m128i *x)
diff --git a/openair1/PHY/TOOLS/dB_routines.c b/openair1/PHY/TOOLS/dB_routines.c
index 572759a68c..5826640b1f 100644
--- a/openair1/PHY/TOOLS/dB_routines.c
+++ b/openair1/PHY/TOOLS/dB_routines.c
@@ -624,6 +624,14 @@ int8_t dB_fixed(uint32_t x)
   return dB_power;
 }
 
+uint8_t dB_fixed64(uint64_t x)
+{
+
+  if (x<(((uint64_t)1)<<32)) return(dB_fixed((uint32_t)x));
+  else                       return(4*dB_table[255] + dB_fixed(x>>32)); 
+ 
+}
+
 int8_t dB_fixed2(uint32_t x, uint32_t y)
 {
 
diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c
index 5c44e156fd..0b2884995c 100644
--- a/openair1/PHY/TOOLS/lte_dfts.c
+++ b/openair1/PHY/TOOLS/lte_dfts.c
@@ -4803,7 +4803,7 @@ void dft4096(int16_t *x,int16_t *y,int scale)
 
 }
 
-
+ 
 
 void idft4096(int16_t *x,int16_t *y,int scale)
 {
@@ -4853,7 +4853,7 @@ void idft4096(int16_t *x,int16_t *y,int scale)
 
       y128+=16;
     }
-
+ 
   }
 
   _mm_empty();
diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h
index fd68a53c1d..a44ac92467 100644
--- a/openair1/PHY/TOOLS/tools_defs.h
+++ b/openair1/PHY/TOOLS/tools_defs.h
@@ -350,6 +350,11 @@ int32_t dot_product(int16_t *x,
                     uint32_t N, //must be a multiple of 8
                     uint8_t output_shift);
 
+int64_t dot_product64(int16_t *x,
+		      int16_t *y,
+		      uint32_t N, //must be a multiple of 8
+		      uint8_t output_shift);
+
 void dft12(int16_t *x,int16_t *y);
 void dft24(int16_t *x,int16_t *y,uint8_t scale_flag);
 void dft36(int16_t *x,int16_t *y,uint8_t scale_flag);
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 67f51ad7cd..3b13cf4bc7 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -1129,6 +1129,8 @@ typedef struct {
   //  uint8_t               prach_timer;
   uint8_t               decode_SIB;
   uint8_t               decode_MIB;
+  /// temporary offset during cell search prior to MIB decoding
+  int              ssb_offset;
   int              rx_offset; /// Timing offset
   int              rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP
   int              time_sync_cell;
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index d6c089ebb1..b1f054bb1c 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -138,9 +138,9 @@ typedef struct NR_DL_FRAME_PARMS {
   /// frequency range
   nr_frequency_range_e freq_range;
   /// Number of resource blocks (RB) in DL
-  uint8_t N_RB_DL;
+  int N_RB_DL;
   /// Number of resource blocks (RB) in UL
-  uint8_t N_RB_UL;
+  int N_RB_UL;
   ///  total Number of Resource Block Groups: this is ceil(N_PRB/P)
   uint8_t N_RBG;
   /// Total Number of Resource Block Groups SubSets: this is P
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index a5a111c26d..b1ac7a1b00 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -113,7 +113,7 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PAR
 {
   int start_rb = cfg->sch_config.n_ssb_crb.value / pow(2,cfg->subframe_config.numerology_index_mu.value);
   fp->ssb_start_subcarrier = 12 * start_rb + cfg->sch_config.ssb_subcarrier_offset.value;
-  LOG_D(PHY, "SSB first subcarrier %d\n", fp->ssb_start_subcarrier);
+  LOG_I(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,start_rb,cfg->sch_config.ssb_subcarrier_offset.value);
 }
 
 void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) {
@@ -141,6 +141,7 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) {
     nr_generate_sss(gNB->d_sss, txdataF, AMP_OVER_2, ssb_start_symbol, cfg, fp);
 
     if (!(frame&7)){
+      LOG_I(PHY,"%d.%d : pbch_configured %d\n",frame,subframe,gNB->pbch_configured);
       if (gNB->pbch_configured != 1)return;
       gNB->pbch_configured = 0;
     }
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 1d91510304..a19f890bc0 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -101,13 +101,12 @@ int main(int argc, char **argv)
   char input_val_str[50],input_val_str2[50];
 
   uint8_t frame_mod4,num_pdcch_symbols = 0;
-  uint16_t NB_RB=25;
 
   SCM_t channel_model=AWGN;//Rayleigh1_anticorr;
 
   double pbch_sinr;
   int pbch_tx_ant;
-  uint8_t N_RB_DL=106,mu=1;
+  int N_RB_DL=273,mu=1;
 
   unsigned char frame_type = 0;
   unsigned char pbch_phase = 0;
@@ -314,19 +313,8 @@ int main(int argc, char **argv)
   if (snr1set==0)
     snr1 = snr0+10;
 
-  gNB2UE = new_channel_desc_scm(n_tx,
-                                n_rx,
-                                channel_model,
- 				61.44e6, //N_RB2sampling_rate(N_RB_DL),
-				40e6, //N_RB2channel_bandwidth(N_RB_DL),
-                                0,
-                                0,
-                                0);
 
-  if (gNB2UE==NULL) {
-    msg("Problem generating channel model. Exiting.\n");
-    exit(-1);
-  }
+  printf("Initializing gNodeB for mu %d, N_RB_DL %d\n",mu,N_RB_DL);
 
   RC.gNB = (PHY_VARS_gNB***) malloc(sizeof(PHY_VARS_gNB **));
   RC.gNB[0] = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *));
@@ -337,10 +325,45 @@ int main(int argc, char **argv)
   frame_parms->nb_antennas_tx = n_tx;
   frame_parms->nb_antennas_rx = n_rx;
   frame_parms->N_RB_DL = N_RB_DL;
+  frame_parms->N_RB_UL = N_RB_DL;
 
-  nr_phy_config_request_sim(gNB);
+  nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu);
   phy_init_nr_gNB(gNB,0,0);
 
+  double fs,bw;
+
+  if (mu == 1 && N_RB_DL == 217) { 
+    fs = 122.88e6;
+    bw = 80e6;
+  }					       
+  else if (mu == 1 && N_RB_DL == 245) {
+    fs = 122.88e6;
+    bw = 90e6;
+  }
+  else if (mu == 1 && N_RB_DL == 273) {
+    fs = 122.88e6;
+    bw = 100e6;
+  }
+  else if (mu == 1 && N_RB_DL == 106) { 
+    fs = 61.44e6;
+    bw = 40e6;
+  }
+  else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
+
+  gNB2UE = new_channel_desc_scm(n_tx,
+                                n_rx,
+                                channel_model,
+ 				fs, 
+				bw, 
+                                0,
+                                0,
+                                0);
+
+  if (gNB2UE==NULL) {
+    msg("Problem generating channel model. Exiting.\n");
+    exit(-1);
+  }
+
   frame_length_complex_samples = frame_parms->samples_per_subframe;
   frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
 
@@ -362,6 +385,7 @@ int main(int argc, char **argv)
     r_im[i] = malloc(frame_length_complex_samples*sizeof(double));
     bzero(r_im[i],frame_length_complex_samples*sizeof(double));
 
+    printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
     txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
     bzero(r_re[i],frame_length_complex_samples*sizeof(int));
   
@@ -375,7 +399,7 @@ int main(int argc, char **argv)
   //configure UE
   UE = malloc(sizeof(PHY_VARS_NR_UE));
   memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
-  phy_init_nr_top(frame_parms);
+  phy_init_nr_top(UE);
   if (init_nr_ue_signal(UE, 1, 0) != 0)
   {
     printf("Error at UE NR initialisation\n");
@@ -385,9 +409,11 @@ int main(int argc, char **argv)
 
   // generate signal
   if (input_fd==NULL) {
+    gNB->pbch_configured = 1;
     nr_common_signal_procedures (gNB,frame,subframe);
   }
 
+  
   LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
   if (gNB->frame_parms.nb_antennas_tx>1)
     LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
@@ -418,8 +444,8 @@ int main(int argc, char **argv)
     for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
       r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
       r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
-      }
     }
+  }
   
   for (SNR=snr0; SNR<snr1; SNR+=.2) {
 
-- 
2.26.2