diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py
index ee9f726c1187a238ed5d24efa71e8ca8da6ff50f..8092febe39666ada6ac15a5c49a8e8af8e69708e 100644
--- a/ci-scripts/cls_containerize.py
+++ b/ci-scripts/cls_containerize.py
@@ -757,9 +757,13 @@ class Containerize():
 		cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml config | grep com.docker.network.bridge.name | sed -e "s@^.*name: @@"'
 		networkNames = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
 		if re.search('4g.*rfsimulator', self.yamlPath[0]) is not None:
+			# Excluding any traffic from LTE-UE container (192.168.61.30)
+			# From the trf-gen, keeping only PING traffic
 			cmd = 'sudo nohup tshark -f "(host 192.168.61.11 and icmp) or (not host 192.168.61.11 and not host 192.168.61.30 and not arp and not port 53 and not port 2152)"'
 		elif re.search('5g.*rfsimulator', self.yamlPath[0]) is not None:
-			cmd = 'sudo nohup tshark -f "(host 192.168.72.135 and icmp) or (not host 192.168.72.135 and not host 192.168.71.150 and not arp and not port 53 and not port 2152 and not port 2153)"'
+			# Excluding any traffic from NR-UE containers (192.168.71.150 and 192.168.71.151)
+			# From the ext-dn, keeping only PING traffic
+			cmd = 'sudo nohup tshark -f "(host 192.168.72.135 and icmp) or (not host 192.168.72.135 and not host 192.168.71.150 and not host 192.168.71.151 and not arp and not port 53 and not port 2152 and not port 2153)"'
 		elif re.search('5g_l2sim', self.yamlPath[0]) is not None:
 			cmd = 'sudo nohup tshark -f "(host 192.168.72.135 and icmp) or (not host 192.168.72.135 and not arp and not port 53 and not port 2152 and not port 2153)"'
 		else:
@@ -817,46 +821,48 @@ class Containerize():
 			# Analyzing log file(s)!
 			listOfPossibleRanContainers = ['enb', 'gnb', 'cu', 'du']
 			for container in listOfPossibleRanContainers:
-				filename = self.yamlPath[0] + '/*-oai-' + container + '.log'
-				cmd = 'ls ' + filename
+				filenames = self.yamlPath[0] + '/*-oai-' + container + '.log'
+				cmd = 'ls ' + filenames
 				containerStatus = True
 				try:
 					lsStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
-					filename = str(lsStatus).strip()
+					filenames = str(lsStatus).strip()
 				except:
 					containerStatus = False
 				if not containerStatus:
 					continue
 
-				logging.debug('\u001B[1m Analyzing xNB logfile ' + filename + ' \u001B[0m')
-				logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers)
-				if (logStatus < 0):
-					fullStatus = False
-					self.exitStatus = 1
-					HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus)
-				else:
-					HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
+				for filename in filenames.split('\n'):
+					logging.debug('\u001B[1m Analyzing xNB logfile ' + filename + ' \u001B[0m')
+					logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers)
+					if (logStatus < 0):
+						fullStatus = False
+						self.exitStatus = 1
+						HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus)
+					else:
+						HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
 
 			listOfPossibleUeContainers = ['lte-ue*', 'nr-ue*']
 			for container in listOfPossibleUeContainers:
-				filename = self.yamlPath[0] + '/*-oai-' + container + '.log'
-				cmd = 'ls ' + filename
+				filenames = self.yamlPath[0] + '/*-oai-' + container + '.log'
+				cmd = 'ls ' + filenames
 				containerStatus = True
 				try:
 					lsStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10)
-					filename = str(lsStatus).strip()
+					filenames = str(lsStatus).strip()
 				except:
 					containerStatus = False
 				if not containerStatus:
 					continue
 
-				logging.debug('\u001B[1m Analyzing UE logfile ' + filename + ' \u001B[0m')
-				logStatus = UE.AnalyzeLogFile_UE(filename, HTML, RAN)
-				if (logStatus < 0):
-					fullStatus = False
-					HTML.CreateHtmlTestRow('UE log Analysis', 'KO', logStatus)
-				else:
-					HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK)
+				for filename in filenames.split('\n'):
+					logging.debug('\u001B[1m Analyzing UE logfile ' + filename + ' \u001B[0m')
+					logStatus = UE.AnalyzeLogFile_UE(filename, HTML, RAN)
+					if (logStatus < 0):
+						fullStatus = False
+						HTML.CreateHtmlTestRow('UE log Analysis', 'KO', logStatus)
+					else:
+						HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK)
 
 			cmd = 'rm ' + self.yamlPath[0] + '/*.log'
 			logging.debug(cmd)
diff --git a/ci-scripts/conf_files/gNB_SA_CU.conf b/ci-scripts/conf_files/gNB_SA_CU.conf
index 39c9a43ad44a86f92f9c78f8edc5d45b6fbed730..9d64ae1976f9ab49720ba9aa338f97af2c69404a 100644
--- a/ci-scripts/conf_files/gNB_SA_CU.conf
+++ b/ci-scripts/conf_files/gNB_SA_CU.conf
@@ -45,10 +45,7 @@ gNBs =
     remote_s_portc  = 500;
     remote_s_portd  = 2152;
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
-    sib1_tda                                                  = 0;
 
      pdcch_ConfigSIB1 = (
       {
diff --git a/ci-scripts/conf_files/gNB_SA_DU.conf b/ci-scripts/conf_files/gNB_SA_DU.conf
index 256d724f3ff9898e942244b2cdc8443de355e515..f95bdf91aee97e2c4c02f8b89db251622bacaf0c 100644
--- a/ci-scripts/conf_files/gNB_SA_DU.conf
+++ b/ci-scripts/conf_files/gNB_SA_DU.conf
@@ -38,7 +38,6 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     min_rxtxtime                                              = 6;
-    sib1_tda                                                  = 0;
 
     pdcch_ConfigSIB1 = (
       {
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf
index 0feb0bb8119446d2dec442ba037648c789e1850a..60fb16318fc9011e69007a08364aae58b021c525 100644
--- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf
@@ -42,7 +42,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
     pusch_AntennaPorts                                        = 2;
     ul_prbblacklist                                           = "51,52,53,54"
     do_SRS                                                    = 1;
diff --git a/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf
index 7f5a9d434371e4eeee7c56a5835d93b021141ff3..e26fc3030db87abba05336f1c8e012138909ff22 100644
--- a/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf
@@ -33,10 +33,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
-    sib1_tda                                                  = 0;
 
      pdcch_ConfigSIB1 = (
       {
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 1551c1ea9a906bd6cf5e73c784363050736d29a7..287a0a3c09b0af23497254827aa193603a20fe2f 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -997,8 +997,18 @@ class RANManagement():
 			for k in keys:
 				result = re.search(k, line)
 				if result is not None:
+					ue_prefix = 'ue0'
+					ue_res = re.search('UE ID 1|UE 1:', line)
+					if ue_res is not None:
+						ue_prefix = 'ue1'
+					ue_res = re.search('UE ID 2|UE 2:', line)
+					if ue_res is not None:
+						ue_prefix = 'ue2'
+					ue_res = re.search('UE ID 3|UE 3:', line)
+					if ue_res is not None:
+						ue_prefix = 'ue3'
 					#remove 1- all useless char before relevant info (ulsch or dlsch) 2- trailing char
-					dlsch_ulsch_stats[k]=re.sub(r'^.*\]\s+', r'' , line.rstrip())
+					dlsch_ulsch_stats[ue_prefix+k]=re.sub(r'^.*\]\s+', r'' , line.rstrip())
 
 			result = re.search('Received NR_RRCReconfigurationComplete from UE', str(line))
 			if result is not None:
diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml
index bab7f9637ad3ef6b187cec5e9edfd80deefca6d4..a1f50948a501baa6e5fe316e335333a55b7f2ba0 100644
--- a/ci-scripts/xml_files/container_5g_rfsim.xml
+++ b/ci-scripts/xml_files/container_5g_rfsim.xml
@@ -31,8 +31,11 @@
  000001
  000002
  000003
+ 000004
  020001
  020002
+ 020003
+ 020004
  030001
  030002
  100001
@@ -71,6 +74,14 @@
                 <nb_healthy>8</nb_healthy>
         </testCase>
 
+        <testCase id="000004">
+                <class>DeployGenObject</class>
+                <desc>Deploy Second OAI 5G NR-UE RF sim SA</desc>
+                <yaml_path>yaml_files/5g_rfsimulator</yaml_path>
+                <services>oai-nr-ue2</services>
+                <nb_healthy>9</nb_healthy>
+        </testCase>
+
         <testCase id="020001">
                 <class>PingFromContainer</class>
                 <desc>Ping ext-dn from NR-UE</desc>
@@ -87,6 +98,22 @@
                 <loss_threshold>5</loss_threshold>
         </testCase>
 
+        <testCase id="020003">
+                <class>PingFromContainer</class>
+                <desc>Ping ext-dn from Second NR-UE</desc>
+                <container_name>rfsim5g-oai-nr-ue2</container_name>
+                <options>-I oaitun_ue1 -c 20 192.168.72.135</options>
+                <loss_threshold>5</loss_threshold>
+        </testCase>
+
+        <testCase id="020004">
+                <class>PingFromContainer</class>
+                <desc>Ping Second NR-UE from ext-dn</desc>
+		<container_name>rfsim5g-oai-ext-dn</container_name>
+                <options>-c 20 12.1.1.3</options>
+                <loss_threshold>5</loss_threshold>
+        </testCase>
+
         <testCase id="030001">
                 <class>IperfFromContainer</class>
                 <desc>Iperf UDP Downlink</desc>
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 45e5db41e463ab96ff3ac536821c5a976673ba80..80c0408e1398821f09275f7909eef8ba68295dee 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1868,6 +1868,7 @@ set(NR_L2_SRC_UE
   ${NR_RRC_DIR}/nr_rrc_config.c
   ${NR_UE_RRC_DIR}/rrc_UE.c
   ${NR_UE_RRC_DIR}/rrc_nsa.c
+  ${NR_RRC_DIR}/nr_rrc_config.c
   )
 
 set (MAC_SRC
diff --git a/doc/TESTING_5GSA_setup.md b/doc/TESTING_5GSA_setup.md
index f8c85bf2ca51f012ed578fd99cf145d12f6b649c..9b27549df438ffda963222e04c23435aecbba53c 100644
--- a/doc/TESTING_5GSA_setup.md
+++ b/doc/TESTING_5GSA_setup.md
@@ -36,6 +36,8 @@ At the moment of writing this document interoperability with the following COTS
  - [Quectel RM500Q-GL](https://www.quectel.com/product/5g-rm500q-gl/)
  - [Simcom SIMCOM8200EA](https://www.simcom.com/product/SIM8200EA_M2.html)
  - Huawei Mate 30 Pro
+ - Oneplus 8
+ - Google Pixel 5
 
  End-to-end control plane signaling to achieve a 5G SA connection, UE registration and PDU session establishment with the CN, as well as some basic user-plane traffic tests have been validated so far using SIMCOM/Quectel modules and Huawei Mate 30 pro. In terms of interoperability with different 5G Core Networks, so far this setup has been tested with:
  
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 65b74a0218a539c504b83b506c6ea7c80e491fa1..845c4f4b7d6cd58b9d041dba75b7b5f2a6791e9f 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -663,6 +663,7 @@ void processSlotRX(void *arg) {
   int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_slot_rx);
   int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx);
   uint8_t gNB_id = 0;
+  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
 
   if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
     /* send tick to RLC and PDCP every ms */
@@ -678,7 +679,7 @@ void processSlotRX(void *arg) {
 
     if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
       nr_downlink_indication_t dl_indication;
-      nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id);
+      nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id, &phy_pdcch_config);
       UE->if_inst->dl_indication(&dl_indication, NULL);
     }
 
@@ -687,7 +688,7 @@ void processSlotRX(void *arg) {
     phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
 #else
     uint64_t a=rdtsc_oai();
-    phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel, &rxtxD->txFifo);
+    phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel, &phy_pdcch_config, &rxtxD->txFifo);
     LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
 #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 284ef22fc4c8fe9f72007c82aee0e3a63d49930e..5f8a856028ca212a2aa612da244d3af67988e555 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
@@ -464,7 +464,8 @@ typedef struct {
   uint8_t nEpreRatioOfPDSCHToPTRS;
   /// MCS table for this DLSCH
   uint8_t mcs_table;
-
+  uint8_t nscid;
+  uint16_t dlDmrsScramblingId;
   uint16_t pduBitmap;
 } fapi_nr_dl_config_dlsch_pdu_rel15_t;
 
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 6a8faa6669a13cb6a9f2550d981a953a57871b0c..9ffc0f75ad345c7e2b12f77c62fca1885d4025a6 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -536,6 +536,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   }
 
   nr_generate_modulation_table();
+  gNB->pdcch_gold_init = cfg->cell_config.phy_cell_id.value;
   nr_init_pdcch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
   nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
 
@@ -549,28 +550,30 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
     AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
 
-    int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
     for (int symb=0; symb<fp->symbols_per_slot; symb++) {
-      pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(nb_codewords*sizeof(uint32_t *));
+      pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_NB_NSCID*sizeof(uint32_t *));
       AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
 
-      for (int q=0; q<nb_codewords; q++) {
+      for (int q=0; q<NR_NB_NSCID; q++) {
         pdsch_dmrs[slot][symb][q] = (uint32_t *)malloc16(pdsch_dmrs_init_length*sizeof(uint32_t));
-        AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d codeword %d - malloc failed\n", slot, symb, q);
+        AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
       }
     }
   }
 
-  nr_init_pdsch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
+
+  for (int nscid = 0; nscid < NR_NB_NSCID; nscid++) {
+    gNB->pdsch_gold_init[nscid] = cfg->cell_config.phy_cell_id.value;
+    nr_init_pdsch_dmrs(gNB, nscid, cfg->cell_config.phy_cell_id.value);
+  }
 
   //PUSCH DMRS init
-  gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(2*sizeof(uint32_t ***));
+  gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(NR_NB_NSCID*sizeof(uint32_t ***));
 
   uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs;
 
-  // ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK)
   int pusch_dmrs_init_length =  ((fp->N_RB_UL*12)>>5)+1;
-  for(int nscid=0; nscid<2; nscid++) {
+  for(int nscid=0; nscid<NR_NB_NSCID; nscid++) {
     pusch_dmrs[nscid] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
     AssertFatal(pusch_dmrs[nscid]!=NULL, "NR init: pusch_dmrs for nscid %d - malloc failed\n", nscid);
 
@@ -585,9 +588,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     }
   }
 
-  uint32_t Nid_pusch[2] = {cfg->cell_config.phy_cell_id.value,cfg->cell_config.phy_cell_id.value};
-  LOG_D(PHY,"Initializing PUSCH DMRS Gold sequence with (%x,%x)\n",Nid_pusch[0],Nid_pusch[1]);
-  nr_gold_pusch(gNB, &Nid_pusch[0]);
+  for (int nscid=0; nscid<NR_NB_NSCID; nscid++) {
+    gNB->pusch_gold_init[nscid] = cfg->cell_config.phy_cell_id.value;
+    nr_gold_pusch(gNB, nscid, gNB->pusch_gold_init[nscid]);
+  }
 
   //CSI RS init
   gNB->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
@@ -607,6 +611,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     }
   }
 
+  gNB->csi_gold_init = cfg->cell_config.phy_cell_id.value;
   nr_init_csi_rs(gNB, cfg->cell_config.phy_cell_id.value);
 
   for (int id=0; id<NUMBER_OF_NR_SRS_MAX; id++) {
@@ -644,12 +649,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   common_vars->beam_id = (uint8_t **)malloc16(Ptx*sizeof(uint8_t*));
 
   for (i=0;i<Ptx;i++){
-      common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
-      LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
-	    i,common_vars->txdataF[i],
-	    fp->samples_per_frame_wCP*sizeof(int32_t));
-      common_vars->beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
-      memset(common_vars->beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
+    common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
+    LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
+          i,common_vars->txdataF[i],
+          fp->samples_per_frame_wCP*sizeof(int32_t));
+    common_vars->beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
+    memset(common_vars->beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
   }
   for (i=0;i<Prx;i++){
     common_vars->rxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t));
@@ -740,10 +745,9 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
   free_and_zero(pdcch_dmrs);
 
   uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
-  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
   for (int slot = 0; slot < fp->slots_per_frame; slot++) {
     for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
-      for (int q = 0; q < nb_codewords; q++)
+      for (int q = 0; q < NR_NB_NSCID; q++)
         free_and_zero(pdsch_dmrs[slot][symb][q]);
       free_and_zero(pdsch_dmrs[slot][symb]);
     }
@@ -771,7 +775,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
   free_and_zero(csi_rs);
 
   for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) {
-    for (int i = 0; i < Prx; i++){
+    for (int i = 0; i < Prx; i++) {
       free_and_zero(gNB->nr_srs_info[id]->srs_received_signal[i]);
       free_and_zero(gNB->nr_srs_info[id]->srs_ls_estimated_channel[i]);
       free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_freq[i]);
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index bf3bdf3f128f087343f029cf13930c64b84be412..9927085a921d8919d11049cd37a3874a375ad8de 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -159,7 +159,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   NR_UE_COMMON *const common_vars        = &ue->common_vars;
   NR_UE_PBCH  **const pbch_vars          = ue->pbch_vars;
   NR_UE_PRACH **const prach_vars         = ue->prach_vars;
-  int i,j,slot,symb, gNB_id, th_id;
+  int i,slot,symb, gNB_id, th_id;
 
   NR_UE_SRS **const srs_vars             = ue->srs_vars;
 
@@ -210,18 +210,21 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
 
   // ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK)
   int pusch_dmrs_init_length =  ((fp->N_RB_UL*12)>>5)+1;
-
-  ue->nr_gold_pusch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
-  uint32_t ***pusch_dmrs = ue->nr_gold_pusch_dmrs;
+  ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
+  uint32_t ****pusch_dmrs = ue->nr_gold_pusch_dmrs;
 
   for (slot=0; slot<fp->slots_per_frame; slot++) {
-    pusch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
+    pusch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
     AssertFatal(pusch_dmrs[slot]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d - malloc failed\n", slot);
 
     for (symb=0; symb<fp->symbols_per_slot; symb++) {
-      pusch_dmrs[slot][symb] = (uint32_t *)malloc16(pusch_dmrs_init_length*sizeof(uint32_t));
+      pusch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_NB_NSCID*sizeof(uint32_t *));
       AssertFatal(pusch_dmrs[slot][symb]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
 
+      for (int q=0; q<NR_NB_NSCID; q++) {
+        pusch_dmrs[slot][symb][q] = (uint32_t *)malloc16(pusch_dmrs_init_length*sizeof(uint32_t));
+        AssertFatal(pusch_dmrs[slot][symb][q]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
+      }
     }
   }
 
@@ -298,24 +301,38 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
     pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
     AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
 
-    int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
     for (int symb=0; symb<fp->symbols_per_slot; symb++) {
-      pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(nb_codewords*sizeof(uint32_t *));
+      pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_NB_NSCID*sizeof(uint32_t *));
       AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
 
-      for (int q=0; q<nb_codewords; q++) {
+      for (int q=0; q<NR_NB_NSCID; q++) {
         pdsch_dmrs[slot][symb][q] = (uint32_t *)malloc16(pdsch_dmrs_init_length*sizeof(uint32_t));
-        AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d codeword %d - malloc failed\n", slot, symb, q);
+        AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
       }
     }
   }
 
   // DLSCH
-  for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
+  for (gNB_id = 0; gNB_id < ue->n_connected_gNB+1; gNB_id++) {
     for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
       ue->pdsch_vars[th_id][gNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH));
     }
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      phy_init_nr_ue_PDSCH( ue->pdsch_vars[th_id][gNB_id], fp );
+    }
 
+    int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      for (i=0; i<nb_codewords; i++) {
+        ue->pdsch_vars[th_id][gNB_id]->llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448
+      }
+      for (i=0; i<NR_MAX_NB_LAYERS; i++) {
+        ue->pdsch_vars[th_id][gNB_id]->layer_llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448
+      }
+    }
+  }
+
+  for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
     for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
       ue->pdcch_vars[th_id][gNB_id] = (NR_UE_PDCCH *)malloc16_clear(sizeof(NR_UE_PDCCH));
     }
@@ -343,49 +360,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
     }
 
 
-    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-      phy_init_nr_ue_PDSCH( ue->pdsch_vars[th_id][gNB_id], fp );
-    }
-
-    int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
-    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-      for (i=0; i<nb_codewords; i++) {
-        ue->pdsch_vars[th_id][gNB_id]->llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448
-      }
-      for (i=0; i<NR_MAX_NB_LAYERS; i++) {
-        ue->pdsch_vars[th_id][gNB_id]->layer_llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448
-      }
-    }
-
-    // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
-    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-      ue->pdcch_vars[th_id][gNB_id]->llr                 = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      ue->pdcch_vars[th_id][gNB_id]->llr16               = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      ue->pdcch_vars[th_id][gNB_id]->wbar                = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp        = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-      ue->pdcch_vars[th_id][gNB_id]->rho                 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-      ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext         = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-      ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-      // Channel estimates
-      ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates      = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
-      ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
-
-      for (i=0; i<fp->nb_antennas_rx; i++) {
-        ue->pdcch_vars[th_id][gNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4));
-
-        for (j=0; j<4; j++) {
-          int idx = (j*fp->nb_antennas_rx)+i;
-          ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
-          ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
-          //  size_t num = 7*2*fp->N_RB_DL*12;
-          size_t num = 4*273*12;  // 4 symbols, 100 PRBs, 12 REs per PRB
-          ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp[idx]        = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
-          ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext[idx]         = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
-          ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
-        }
-      }
-    }
-
     // RACH
     prach_vars[gNB_id]->prachF             = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
     prach_vars[gNB_id]->prach              = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
@@ -423,6 +397,8 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
 
   for (int slot = 0; slot < fp->slots_per_frame; slot++) {
     for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
+      for (int q=0; q<NR_NB_NSCID; q++)
+        free_and_zero(ue->nr_gold_pusch_dmrs[slot][symb][q]);
       free_and_zero(ue->nr_gold_pusch_dmrs[slot][symb]);
     }
     free_and_zero(ue->nr_gold_pusch_dmrs[slot]);
@@ -456,10 +432,9 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   }
   free_and_zero(ue->nr_gold_pdcch[0]);
 
-  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
   for (int slot=0; slot<fp->slots_per_frame; slot++) {
     for (int symb=0; symb<fp->symbols_per_slot; symb++) {
-      for (int q=0; q<nb_codewords; q++) 
+      for (int q=0; q<NR_NB_NSCID; q++)
         free_and_zero(ue->nr_gold_pdsch[0][slot][symb][q]);
       free_and_zero(ue->nr_gold_pdsch[0][slot][symb]);
     }
@@ -467,38 +442,20 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   }
   free_and_zero(ue->nr_gold_pdsch[0]);
 
-  for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
+  for (int gNB_id = 0; gNB_id < ue->n_connected_gNB+1; gNB_id++) {
 
     // PDSCH
     for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
-
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr_shifts);
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream);
       phy_term_nr_ue__PDSCH(ue->pdsch_vars[th_id][gNB_id], fp);
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]);
     }
+  }
+  
+  for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
 
     for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
-      for (int i = 0; i < fp->nb_antennas_rx; i++) {
-        for (int j = 0; j < 4; j++) {
-          int idx = j * fp->nb_antennas_rx + i;
-          free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx]);
-          free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx]);
-          free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp[idx]);
-          free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext[idx]);
-          free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext[idx]);
-        }
-        free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rho[i]);
-      }
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->llr);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->llr16);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->wbar);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rho);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time);
 
       free_and_zero(ue->pdcch_vars[th_id][gNB_id]);
     }
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h
index 6b84a5f9693981e816767a68a8e09704d83895c3..b4ae44f6eab8b663a98de22b151338385c76bf33 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h
+++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h
@@ -155,8 +155,6 @@ typedef struct {
   uint8_t h[MAX_NUM_CHANNEL_BITS];
   /// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
   uint8_t b_tilde[MAX_NUM_CHANNEL_BITS];
-  /// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
-  int32_t d[MAX_NUM_RE];
   /// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15)
   int32_t z[MAX_NUM_RE];
   /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c
index 7ec3e7bfb684dac869dc84bc04e4bb924995117b..6a663e89404e5a91a0187a20f52c4bf152863d16 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c
@@ -42,7 +42,7 @@
 
 //#define DEBUG_ULSCH_MODULATION
 
-void dft_lte(int32_t *z,int32_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
+void dft_lte(int32_t *z,struct complex16 *input, int32_t Msc_PUSCH, uint8_t Nsymb)
 {
 
 #if defined(__x86_64__) || defined(__i386__)
@@ -66,7 +66,7 @@ void dft_lte(int32_t *z,int32_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
 #endif
   //  printf("Doing lte_dft for Msc_PUSCH %d\n",Msc_PUSCH);
 
-  d0 = (uint32_t *)d;
+  d0 = (uint32_t *)input;
   d1 = d0+Msc_PUSCH;
   d2 = d1+Msc_PUSCH;
   d3 = d2+Msc_PUSCH;
@@ -476,7 +476,8 @@ void ulsch_modulation(int32_t **txdataF,
   // Modulation
 
   ulsch_Msymb = G/Q_m;
-
+  /// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
+  struct complex16 d[MAX_NUM_RE] __attribute__((aligned(32)));
   if(ulsch->cooperation_flag == 2)
     // For Distributed Alamouti Scheme in Collabrative Communication
   {
@@ -488,14 +489,14 @@ void ulsch_modulation(int32_t **txdataF,
 
 
         //UE1, -x1*
-        ((int16_t*)&ulsch->d[i])[0] = (ulsch->b_tilde[j] == 1)  ? (gain_lin_QPSK) : -gain_lin_QPSK;
-        ((int16_t*)&ulsch->d[i])[1] = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
+        d[i].r = (ulsch->b_tilde[j] == 1)  ? (gain_lin_QPSK) : -gain_lin_QPSK;
+        d[i].i = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
         //      if (i<Msc_PUSCH)
         //  printf("input %d (%p): %d,%d\n", i,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
 
         // UE1, x0*
-        ((int16_t*)&ulsch->d[i+1])[0] = (ulsch->b_tilde[j-2] == 1)  ? (-gain_lin_QPSK) : gain_lin_QPSK;
-        ((int16_t*)&ulsch->d[i+1])[1] = (ulsch->b_tilde[j-1] == 1)? (gain_lin_QPSK) : -gain_lin_QPSK;
+        d[i+1].r = (ulsch->b_tilde[j-2] == 1)  ? (-gain_lin_QPSK) : gain_lin_QPSK;
+        d[i+1].i = (ulsch->b_tilde[j-1] == 1)? (gain_lin_QPSK) : -gain_lin_QPSK;
 
         break;
 
@@ -521,8 +522,8 @@ void ulsch_modulation(int32_t **txdataF,
           qam16_table_offset_im+=1;
 
 
-        ((int16_t*)&ulsch->d[i])[0]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+        d[i].r =-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+        d[i].i =(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
 
         //UE1,x0*
         qam16_table_offset_re = 0;
@@ -544,8 +545,8 @@ void ulsch_modulation(int32_t **txdataF,
 
         //    ((int16_t*)&ulsch->d[i+1])[0]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
         //    ((int16_t*)&ulsch->d[i+1])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
-        ((int16_t*)&ulsch->d[i+1])[0]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i+1])[1]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+        d[i+1].r=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+        d[i+1].i=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
 
 
         break;
@@ -578,8 +579,8 @@ void ulsch_modulation(int32_t **txdataF,
           qam64_table_offset_im+=1;
 
 
-        ((int16_t*)&ulsch->d[i])[0]=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+        d[i].r=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+        d[i].i=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
         //UE1,x0*
         qam64_table_offset_re = 0;
@@ -605,8 +606,8 @@ void ulsch_modulation(int32_t **txdataF,
           qam64_table_offset_im+=1;
 
 
-        ((int16_t*)&ulsch->d[i+1])[0]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i+1])[1]=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+        d[i+1].r=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+        d[i+1].i=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
         break;
 
@@ -621,8 +622,8 @@ void ulsch_modulation(int32_t **txdataF,
       case 2:
         // TODO: this has to be updated!!!
 
-        ((int16_t*)&ulsch->d[i])[0] = (ulsch->b_tilde[j] == 1)  ? (-gain_lin_QPSK) : gain_lin_QPSK;
-        ((int16_t*)&ulsch->d[i])[1] = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
+        d[i].r = (ulsch->b_tilde[j] == 1)  ? (-gain_lin_QPSK) : gain_lin_QPSK;
+        d[i].i = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
         //        if (i<Msc_PUSCH)
         //    printf("input %d/%d Msc_PUSCH %d (%p): %d,%d\n", i,Msymb,Msc_PUSCH,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
 
@@ -646,8 +647,8 @@ void ulsch_modulation(int32_t **txdataF,
           qam16_table_offset_im+=1;
 
 
-        ((int16_t*)&ulsch->d[i])[0]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+        d[i].r=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+        d[i].i=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
         //      printf("input(16qam) %d (%p): %d,%d\n", i,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
         break;
 
@@ -676,8 +677,8 @@ void ulsch_modulation(int32_t **txdataF,
           qam64_table_offset_im+=1;
 
 
-        ((int16_t*)&ulsch->d[i])[0]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
-        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+        d[i].r=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+        d[i].i=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
         break;
 
@@ -688,7 +689,7 @@ void ulsch_modulation(int32_t **txdataF,
 
   // Transform Precoding
 
-  dft_lte(ulsch->z,ulsch->d,Msc_PUSCH,ulsch->Nsymb_pusch);
+  dft_lte(ulsch->z,d,Msc_PUSCH,ulsch->Nsymb_pusch);
 
   DevAssert(txdataF);
 
diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c
index 8f41735f10cfa5fd4a915a7d8cb825b2305c03ba..b2c7d934c6583c88acaf82f38a8f61d543b76b02 100644
--- a/openair1/PHY/MODULATION/slot_fep.c
+++ b/openair1/PHY/MODULATION/slot_fep.c
@@ -91,7 +91,7 @@ int slot_fep(PHY_VARS_UE *ue,
   }
 
   //  subframe_offset_F = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
-
+ 
   if (l<0 || l>=7-frame_parms->Ncp) {
     printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
     return(-1);
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index 9aaba7fb66789bcda3d29103ff383a4aa944c40d..4a6f8ef9af1b4a5f7d314bbc9ddb7969aaf2216c 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -165,6 +165,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
 
   //------------------generate DMRS------------------//
 
+  if(pusch_pdu->ul_dmrs_scrambling_id != gNB->pusch_gold_init[pusch_pdu->scid])  {
+    gNB->pusch_gold_init[pusch_pdu->scid] = pusch_pdu->ul_dmrs_scrambling_id;
+    nr_gold_pusch(gNB, pusch_pdu->scid, pusch_pdu->ul_dmrs_scrambling_id);
+  }
+
   // transform precoding = 1 means disabled
   if (pusch_pdu->transform_precoding == 1) {
     nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch,
@@ -1247,4 +1252,4 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB,
 #endif
 
   return 0;
-}
\ No newline at end of file
+}
diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c
index b593dcbb477506d7a547e51eb4c65747e676fa2e..279afc8110c215a33e8fcde415a1964c17e6db79 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold.c
@@ -78,57 +78,47 @@ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
 }
 
 
-void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
-{
+void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid) {
   
   uint32_t x1, x2;
   uint8_t reset;
   NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
   uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
   int pdsch_dmrs_init_length =  ((fp->N_RB_DL*12)>>5)+1;
-  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
-  uint16_t N_n_scid[2]={Nid, Nid};
-  uint8_t n_scid=0; // again works only for 1_0
+
   for (uint8_t slot=0; slot<fp->slots_per_frame; slot++) {
 
     for (uint8_t symb=0; symb<fp->symbols_per_slot; symb++) {
-        reset = 1;
-        x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
-	      LOG_D(PHY,"PDSCH DMRS slot %d, symb %d x2 %x, N_n_scid %d,n_scid %d\n",slot,symb,x2,N_n_scid[n_scid],n_scid);
-        for (uint32_t n=0; n<pdsch_dmrs_init_length; n++) {
-          pdsch_dmrs[slot][symb][0][n] = lte_gold_generic(&x1, &x2, reset);
-          reset = 0;
-        }
-
-        if(nb_codewords>1)
-          memcpy(pdsch_dmrs[slot][symb][1],pdsch_dmrs[slot][symb][0],sizeof(uint32_t)*pdsch_dmrs_init_length);
+      reset = 1;
+      x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) +((Nid<<1)+nscid));
+      LOG_D(PHY,"PDSCH DMRS slot %d, symb %d x2 %x, Nid %d,nscid %d\n",slot,symb,x2,Nid,nscid);
+      for (uint32_t n=0; n<pdsch_dmrs_init_length; n++) {
+        pdsch_dmrs[slot][symb][nscid][n] = lte_gold_generic(&x1, &x2, reset);
+        reset = 0;
+      }
     }
   }
 }
 
 
-void nr_gold_pusch(PHY_VARS_gNB* gNB, uint32_t *Nid) {
+void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid) {
 
   unsigned char ns;
   unsigned int n,x1,x2;
-  int nscid, reset;
-  unsigned int nid;
+  int reset;
   NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
   unsigned short l;
   int pusch_dmrs_init_length =  ((fp->N_RB_UL*12)>>5)+1;
 
-  for (nscid=0; nscid<2; nscid++) {
-    nid = Nid[nscid];
-    for (ns=0; ns<fp->slots_per_frame; ns++) {
-      for (l=0; l<fp->symbols_per_slot; l++) {
-        reset = 1;
-        x2 = ((1<<17) * (fp->symbols_per_slot*ns+l+1) * ((nid<<1)+1) +((nid<<1)+nscid));
-        LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",ns,l,x2);
-
-        for (n=0; n<pusch_dmrs_init_length; n++) {
-          gNB->nr_gold_pusch_dmrs[nscid][ns][l][n] = lte_gold_generic(&x1, &x2, reset);
-          reset = 0;
-        }
+  for (ns=0; ns<fp->slots_per_frame; ns++) {
+    for (l=0; l<fp->symbols_per_slot; l++) {
+      reset = 1;
+      x2 = ((1<<17) * (fp->symbols_per_slot*ns+l+1) * ((nid<<1)+1) +((nid<<1)+nscid));
+      LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",ns,l,x2);
+
+      for (n=0; n<pusch_dmrs_init_length; n++) {
+        gNB->nr_gold_pusch_dmrs[nscid][ns][l][n] = lte_gold_generic(&x1, &x2, reset);
+        reset = 0;
       }
     }
   }
diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c
index 932cdba538a2d8c34f7d1a42ce64aaa5a94ecffe..203d6c8625213a24d64e47bcaaff196af9a16158 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c
@@ -76,46 +76,38 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
 }
 
 void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
-                   unsigned short *n_idDMRS)
-{
+                   int nscid,
+                   uint32_t nid) {
 
   unsigned int x1,x2,x2tmp0;
-  unsigned int nid;
   uint8_t reset;
   int pdsch_dmrs_init_length =  ((ue->frame_parms.N_RB_DL*12)>>5)+1;
-  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
-  /// to be updated from higher layer
-  //unsigned short lbar = 0;
-
-  for (int nscid=0; nscid<nb_codewords; nscid++) {
-    for (int ns=0; ns<ue->frame_parms.slots_per_frame; ns++) {
 
-      nid = n_idDMRS[nscid];
+  for (int ns=0; ns<ue->frame_parms.slots_per_frame; ns++) {
 
-      for (int l=0; l<ue->frame_parms.symbols_per_slot; l++) {
+    for (int l=0; l<ue->frame_parms.symbols_per_slot; l++) {
 
-        reset = 1;
-        x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17;
-        x2 = (x2tmp0+(nid<<1)+nscid)%(1U<<31);  //cinit
-        LOG_D(PHY,"UE DMRS slot %d, symb %d, x2 %x, nscid %d\n",ns,l,x2,nscid);
+      reset = 1;
+      x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17;
+      x2 = (x2tmp0+(nid<<1)+nscid)%(1U<<31);  //cinit
+      LOG_D(PHY,"UE DMRS slot %d, symb %d, x2 %x, nscid %d\n",ns,l,x2,nscid);
 
-        for (int n=0; n<pdsch_dmrs_init_length; n++) {
-          ue->nr_gold_pdsch[0][ns][l][nscid][n] = lte_gold_generic(&x1, &x2, reset);
-          reset = 0;
-        }
+      for (int n=0; n<pdsch_dmrs_init_length; n++) {
+        ue->nr_gold_pdsch[0][ns][l][nscid][n] = lte_gold_generic(&x1, &x2, reset);
+        reset = 0;
       }
     }
   }
 }
 
 void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
-                        uint16_t *N_n_scid,
+                        uint16_t N_n_scid,
                         uint8_t n_scid)
 {
   uint32_t x1, x2, n;
   uint8_t reset, slot, symb;
   NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
-  uint32_t ***pusch_dmrs = ue->nr_gold_pusch_dmrs;
+  uint32_t ****pusch_dmrs = ue->nr_gold_pusch_dmrs;
   int pusch_dmrs_init_length =  ((fp->N_RB_UL*12)>>5)+1;
 
   for (slot=0; slot<fp->slots_per_frame; slot++) {
@@ -123,10 +115,10 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
     for (symb=0; symb<fp->symbols_per_slot; symb++) {
 
       reset = 1;
-      x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
-
+      x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid<<1)+1) +((N_n_scid<<1)+n_scid));
+      LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",slot,symb,x2);
       for (n=0; n<pusch_dmrs_init_length; n++) {
-        pusch_dmrs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
+        pusch_dmrs[slot][symb][n_scid][n] = lte_gold_generic(&x1, &x2, reset);
         reset = 0;
       }
     }
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index aedc535c29868a34859e238d61bbc912d3ced356..df3dad1e5903eacc09002fec93eb9b826ca0f212 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -37,10 +37,10 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
 @param Nid is used for the initialization of x2, Physical cell Id by default or upper layer configured pdcch_scrambling_ID
  */
 void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
-void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
+void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid);
 void nr_init_csi_rs(PHY_VARS_gNB* gNB, uint32_t Nid);
 
-void nr_gold_pusch(PHY_VARS_gNB* gNB, uint32_t *Nid);
+void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid);
 
 int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
                      unsigned int Ns,
diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
index 1fca2be2a187dd7643d7898ccfba7bd71b09e94c..cd19e5ebcac29ea805d33270419f825251acb224 100644
--- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
+++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
@@ -61,10 +61,11 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
                    unsigned short n_idDMRS);
 
 void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
-                   unsigned short *n_idDMRS);
+                   int nscid,
+                   uint32_t nid);
 
 void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
-                        uint16_t *N_n_scid,
+                        uint16_t N_n_scid,
                         uint8_t n_scid);
 
 #endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
index b530dcf4823b012e82927da75b81ffff633a599b..694617c4441019c8a00b3bbb21907178b9d197db 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
@@ -30,7 +30,6 @@
 void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
                         int16_t amp,
                         nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params,
-                        uint16_t cell_id,
                         int slot){
 
   NR_DL_FRAME_PARMS frame_parms=gNB->frame_parms;
@@ -52,20 +51,10 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
 
   AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
 
-  // pre-computed for scrambling id equel to cell id
-  // if the scrambling id is not the cell id we need to re-initialize the rs
-  if (csi_params.scramb_id != cell_id) {
-    uint8_t reset;
-    uint32_t x1, x2;
-    uint32_t Nid = csi_params.scramb_id;
-    for (uint8_t symb=0; symb<frame_parms.symbols_per_slot; symb++) {
-      reset = 1;
-      x2 = ((1<<10) * (frame_parms.symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid));
-      for (uint32_t n=0; n<(csi_rs_length>>5)+1; n++) {
-        gold_csi_rs[symb][n] = lte_gold_generic(&x1, &x2, reset);
-        reset = 0;
-      }
-    }
+  // if the scrambling id is not the one previously used to initialize we need to re-initialize the rs
+  if (csi_params.scramb_id != gNB->csi_gold_init) {
+    gNB->csi_gold_init = csi_params.scramb_id;
+    nr_init_csi_rs(gNB, csi_params.scramb_id);
   }
 
   switch (csi_params.row) {
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index 9876dfca86fad34cd5e9eeccced11765c5828adc..47961640369f80d19d5f0a74f6d7e8bb8f479c71 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -66,11 +66,12 @@ void nr_pdcch_scrambling(uint32_t *in,
   }
 }
 
-void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
-                     uint32_t **gold_pdcch_dmrs,
+void nr_generate_dci(PHY_VARS_gNB *gNB,
+                     nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
                      int32_t *txdataF,
                      int16_t amp,
-                     NR_DL_FRAME_PARMS *frame_parms) {
+                     NR_DL_FRAME_PARMS *frame_parms,
+                     int slot) {
 
   int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1] __attribute__((aligned(16))); // 3 for the max coreset duration
   uint16_t cset_start_sc;
@@ -81,7 +82,7 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
     
   int rb_offset;
   int n_rb;
-  
+
   // compute rb_offset and n_prb based on frequency allocation
   nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
   nr_fill_cce_list(cce_list,0,pdcch_pdu_rel15);
@@ -95,6 +96,13 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
      * in time: by its first slot and its first symbol*/
     const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d];
 
+    if(dci_pdu->ScramblingId != gNB->pdcch_gold_init) {
+      gNB->pdcch_gold_init = dci_pdu->ScramblingId;
+      nr_init_pdcch_dmrs(gNB, dci_pdu->ScramblingId);
+    }
+
+    uint32_t **gold_pdcch_dmrs = gNB->nr_gold_pdcch_dmrs[slot];
+
     cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
     cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
     dci_idx = 0;
@@ -104,8 +112,8 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
     uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE)
     uint32_t encoded_length = dci_pdu->AggregationLevel*108; //2(QPSK)*9(per RB)*6(REG per CCE)
     LOG_D(PHY, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d),Scrambling_Id %d,ScramblingRNTI %x,PayloadSizeBits %d\n",
-    rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType,
-    dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
+          rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType,
+          dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
     dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
       
     /// DMRS QPSK modulation
@@ -115,10 +123,10 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
       
 #ifdef DEBUG_PDCCH_DMRS
        if(dci_pdu->RNTI!=0xFFFF) {      
-      for (int i=0; i<dmrs_length>>1; i++)
-	printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
-	       &gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
-    }  
+         for (int i=0; i<dmrs_length>>1; i++)
+	   printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
+	          &gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
+       }
 #endif
     }
     
@@ -249,15 +257,16 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
 }
 
 void nr_generate_dci_top(processingData_L1tx_t *msgTx,
-                         uint32_t **gold_pdcch_dmrs,
+                         int slot,
                          int32_t *txdataF,
                          int16_t amp,
                          NR_DL_FRAME_PARMS *frame_parms) {
 
+
   for (int i=0; i<msgTx->num_ul_pdcch; i++)
-    nr_generate_dci(&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
+    nr_generate_dci(msgTx->gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
   for (int i=0; i<msgTx->num_dl_pdcch; i++)
-    nr_generate_dci(&msgTx->pdcch_pdu[i].pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
+    nr_generate_dci(msgTx->gNB,&msgTx->pdcch_pdu[i].pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
 
 }
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h
index bdc8509d12a2768b033370bede1b0da97b589c90..490a8b528682fa3d64b7a8d0de5f7a8f223372cb 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h
@@ -30,7 +30,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
                          uint16_t N_RB);
 
 void nr_generate_dci_top(processingData_L1tx_t *msgTx,
-                         uint32_t **gold_pdcch_dmrs,
+                         int slot,
                          int32_t *txdataF,
                          int16_t amp,
                          NR_DL_FRAME_PARMS *frame_parms);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index 3182464c20ea515eb7346affba94f68a7ed7eb98..2c4fb26c5adab7508063f45ab6f18da919d82254 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -58,7 +58,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
 
   PHY_VARS_gNB *gNB = msgTx->gNB;
   NR_gNB_DLSCH_t *dlsch;
-  uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot];
   int32_t** txdataF = gNB->common_vars.txdataF;
   int16_t amp = AMP;
   int xOverhead = 0;
@@ -93,6 +92,12 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
     }
     n_dmrs = (rel15->BWPStart+rel15->rbStart+rel15->rbSize)*nb_re_dmrs;
 
+    if(rel15->dlDmrsScramblingId != gNB->pdsch_gold_init[rel15->SCID])  {
+      gNB->pdsch_gold_init[rel15->SCID] = rel15->dlDmrsScramblingId;
+      nr_init_pdsch_dmrs(gNB, rel15->SCID, rel15->dlDmrsScramblingId);
+    }
+
+    uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot];
     uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100
     uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos);
     uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs*dmrs_len-xOverhead)*rel15->rbSize*rel15->nrOfLayers;
@@ -146,17 +151,18 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
     printf("\n");
 #endif
 
-    /// scrambling
     for (int q=0; q<rel15->NrOfCodewords; q++) {
-      uint32_t scrambled_output[encoded_length];
+      /// scrambling
       start_meas(dlsch_scrambling_stats);
+      uint32_t scrambled_output[(encoded_length>>5)+4]; // modulator acces by 4 bytes in some cases
+      memset(scrambled_output, 0, sizeof(scrambled_output));
+      if ( encoded_length > rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers) abort();
       nr_pdsch_codeword_scrambling(output,
                                    encoded_length,
                                    q,
                                    rel15->dataScramblingId,
                                    rel15->rnti,
                                    scrambled_output);
-      stop_meas(dlsch_scrambling_stats);
 
 #ifdef DEBUG_DLSCH
       printf("PDSCH scrambling:\n");
@@ -166,12 +172,16 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
         printf("\n");
       }
 #endif
-    start_meas(dlsch_modulation_stats);
+
+      stop_meas(dlsch_scrambling_stats);
+      /// Modulation
+      start_meas(dlsch_modulation_stats);
       nr_modulation(scrambled_output,
-		    encoded_length,
-		    Qm,
-		    mod_symbs[q]);
-    stop_meas(dlsch_modulation_stats);
+                    encoded_length,
+                    Qm,
+                    mod_symbs[q]);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 0);
+      stop_meas(dlsch_modulation_stats);
 #ifdef DEBUG_DLSCH
       printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re);
       for (int i=0; i<nb_re>>3; i++) {
@@ -186,18 +196,18 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
     start_meas(&gNB->dlsch_layer_mapping_stats); 
     /// Layer mapping
     nr_layer_mapping(mod_symbs,
-		     rel15->nrOfLayers,
-		     nb_re,
-		     tx_layers);
+                     rel15->nrOfLayers,
+                     nb_re,
+                     tx_layers);
 #ifdef DEBUG_DLSCH
     printf("Layer mapping (%d layers):\n", rel15->nrOfLayers);
     for (int l=0; l<rel15->nrOfLayers; l++)
       for (int i=0; i<(nb_re/rel15->nrOfLayers)>>3; i++) {
-	printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7);
-	for (int j=0; j<8; j++) {
-	  printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]);
-	}
-	printf("\n");
+        printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7);
+        for (int j=0; j<8; j++) {
+          printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]);
+        }
+        printf("\n");
       }
 #endif
 
@@ -216,7 +226,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
 
 #ifdef DEBUG_DLSCH_MAPPING
     printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
-	   start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
+           start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
 #endif
 
     start_meas(&gNB->dlsch_resource_mapping_stats);
@@ -269,7 +279,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
             l_prime = 0;
           }
           /// DMRS QPSK modulation
-          nr_modulation(pdsch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
+          nr_modulation(pdsch_dmrs[l][rel15->SCID], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // Qm = 2 as DMRS is QPSK modulated
 
 #ifdef DEBUG_DLSCH
           printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs, dmrs_Type);
@@ -290,7 +300,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
           if(ptrs_symbol) {
             /* PTRS QPSK Modulation for each OFDM symbol in a slot */
             LOG_D(PHY,"Doing ptrs modulation for symbol %d, n_ptrs %d\n",l,n_ptrs);
-            nr_modulation(pdsch_dmrs[l][0], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs);
+            nr_modulation(pdsch_dmrs[l][rel15->SCID], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs);
           }
         }
         uint16_t k = start_sc;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index f9478b7633282abe3f14926387be019b4d586f08..9b24504a1414f609e29e26a69a287d7c73a4fce6 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -338,7 +338,6 @@ uint8_t get_nr_prach_duration(uint8_t prach_format);
 void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
                         int16_t amp,
                         nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params,
-                        uint16_t cell_id,
                         int slot);
 
 void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
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 55deb686ad84fc9c0b47122d4e9c6c3568c5472d..3b4ce9a42354c76b127bc338bbc822c3974f95f3 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -466,8 +466,11 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 uint8_t gNB_id,
                                 unsigned char Ns,
                                 unsigned char symbol,
+                                unsigned short scrambling_id,
                                 unsigned short coreset_start_subcarrier,
-                                unsigned short nb_rb_coreset)
+                                unsigned short nb_rb_coreset,
+                                int32_t pdcch_est_size,
+                                int32_t pdcch_dl_ch_estimates[][pdcch_est_size])
 {
 
   unsigned char aarx;
@@ -476,7 +479,6 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
   int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
   int ch_offset,symbol_offset;
 
-  int **dl_ch_estimates  =ue->pdcch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
 
   ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
@@ -493,13 +495,11 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
   fm = filt16a_m1;
   fr = filt16a_r1;
 
-
   // checking if re-initialization of scrambling IDs is needed (should be done here but scrambling ID for PDCCH is not taken from RRC)
-/*  if (( != ue->scramblingID_pdcch){
-    ue->scramblingID_pdcch=;
-    nr_gold_pdsch(ue,ue->scramblingID_pdcch);
-  }*/
-
+  if (scrambling_id != ue->scramblingID_pdcch){
+    ue->scramblingID_pdcch = scrambling_id;
+    nr_gold_pdcch(ue,ue->scramblingID_pdcch);
+  }
 
   // generate pilot
   int pilot[nb_rb_coreset * 3] __attribute__((aligned(16))); 
@@ -511,7 +511,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
     k = coreset_start_subcarrier;
     pil   = (int16_t *)&pilot[0];
     rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
-    dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
+    dl_ch = (int16_t *)&pdcch_dl_ch_estimates[aarx][ch_offset];
 
     memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
 
@@ -666,6 +666,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 unsigned char Ns,
                                 unsigned short p,
                                 unsigned char symbol,
+                                unsigned char nscid,
+                                unsigned short scrambling_id,
                                 unsigned short BWPStart,
                                 uint8_t config_type,
                                 unsigned short bwp_start_subcarrier,
@@ -703,11 +705,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int8_t delta = get_delta(p, config_type);
 
   // checking if re-initialization of scrambling IDs is needed
-  /*if ((XXX.scramblingID0 != ue->scramblingID[0]) || (XXX.scramblingID1 != ue->scramblingID[1])){
-    ue->scramblingID[0] = XXX.scramblingID0;
-    ue->scramblingID[1] = XXX.scramblingID1;
-    nr_gold_pdsch(ue,ue->scramblingID);
-  }*/
+  if (scrambling_id != ue->scramblingID_dlsch[nscid]){
+    ue->scramblingID_dlsch[nscid] = scrambling_id;
+    nr_gold_pdsch(ue, nscid, scrambling_id);
+  }
 
   nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][0], &pilot[0], 1000+p, 0, nb_rb_pdsch+rb_offset, config_type);
 
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index aa4b78e1453cef70f784e4f3e7cedd325a076a3a..ce99f0f9c96a770b4f9d1261475328b1879225bf 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -44,8 +44,11 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 uint8_t gNB_id,
                                 unsigned char Ns,
                                 unsigned char symbol,
+                                unsigned short scrambling_id,
                                 unsigned short coreset_start_subcarrier,
-                                unsigned short nb_rb_coreset);
+                                unsigned short nb_rb_coreset,
+                                int32_t pdcch_est_size,
+                                int32_t pdcch_dl_ch_estimates[][pdcch_est_size]);
 
 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
                              UE_nr_rxtx_proc_t *proc,
@@ -74,6 +77,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 unsigned char Ns,
                                 unsigned short p,
                                 unsigned char symbol,
+                                unsigned char nscid,
+                                unsigned short scrambling_id,
                                 unsigned short BWPStart,
                                 uint8_t config_type,
                                 unsigned short bwp_start_subcarrier,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index 057be50e8c9545b091a43d8fa5ac83956dbfac13..336d388d40d794644f9774418bcbfe92399abd78 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -42,6 +42,7 @@
 #include "PHY/CODING/coding_extern.h"
 #include "PHY/sse_intrin.h"
 #include "common/utils/nr/nr_common.h"
+#include <openair1/PHY/TOOLS/phy_scope_interface.h>
 
 #include "assertions.h"
 #include "T.h"
@@ -201,7 +202,7 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
   }
 }
 
-int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp,
+int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t rx_size, int32_t rxdataF_comp[][rx_size],
                      int16_t *pdcch_llr, uint8_t symbol,uint32_t coreset_nbr_rb) {
   int16_t *rxF = (int16_t *) &rxdataF_comp[0][(symbol * coreset_nbr_rb * 12)];
   int32_t i;
@@ -270,7 +271,8 @@ int32_t pdcch_llr(NR_DL_FRAME_PARMS *frame_parms,
 //__m128i avg128P;
 
 //compute average channel_level on each (TX,RX) antenna pair
-void nr_pdcch_channel_level(int32_t **dl_ch_estimates_ext,
+void nr_pdcch_channel_level(int32_t rx_size,
+                            int32_t dl_ch_estimates_ext[][rx_size],
                             NR_DL_FRAME_PARMS *frame_parms,
                             int32_t *avg,
                             int symbol,
@@ -337,9 +339,11 @@ void nr_pdcch_channel_level(int32_t **dl_ch_estimates_ext,
 
 // This function will extract the mapped DM-RS PDCCH REs as per 38.211 Section 7.4.1.3.2 (Mapping to physical resources)
 void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
-                                 int32_t **dl_ch_estimates,
-                                 int32_t **rxdataF_ext,
-                                 int32_t **dl_ch_estimates_ext,
+                                 int32_t est_size,
+                                 int32_t dl_ch_estimates[][est_size],
+                                 int32_t rx_size,
+                                 int32_t rxdataF_ext[][rx_size],
+                                 int32_t dl_ch_estimates_ext[][rx_size],
                                  uint8_t symbol,
                                  NR_DL_FRAME_PARMS *frame_parms,
                                  uint8_t *coreset_freq_dom,
@@ -515,9 +519,9 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
 
 #define print_shorts(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
 
-void nr_pdcch_channel_compensation(int32_t **rxdataF_ext,
-                                   int32_t **dl_ch_estimates_ext,
-                                   int32_t **rxdataF_comp,
+void nr_pdcch_channel_compensation(int32_t rx_size, int32_t rxdataF_ext[][rx_size],
+                                   int32_t dl_ch_estimates_ext[][rx_size],
+                                   int32_t rxdataF_comp[][rx_size],
                                    int32_t **rho,
                                    NR_DL_FRAME_PARMS *frame_parms,
                                    uint8_t symbol,
@@ -628,7 +632,8 @@ void nr_pdcch_channel_compensation(int32_t **rxdataF_ext,
 
 
 void nr_pdcch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
-                         int32_t **rxdataF_comp,
+                         int32_t rx_size,
+                         int32_t rxdataF_comp[][rx_size],
                          uint8_t symbol) {
 #if defined(__x86_64__) || defined(__i386__)
   __m128i *rxdataF_comp128_0,*rxdataF_comp128_1;
@@ -664,19 +669,31 @@ void nr_pdcch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
 
 int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
                     UE_nr_rxtx_proc_t *proc,
-                    fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
-		    int16_t *e_rx) {
+                    int32_t pdcch_est_size,
+                    int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+                    int16_t *pdcch_e_rx,
+                    fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
 
   uint32_t frame = proc->frame_rx;
   uint32_t slot  = proc->nr_slot_rx;
   NR_UE_COMMON *common_vars      = &ue->common_vars;
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
-  NR_UE_PDCCH *pdcch_vars        = ue->pdcch_vars[proc->thread_id][0];
 
   uint8_t log2_maxh, aarx;
   int32_t avgs;
   int32_t avgP[4];
   int n_rb,rb_offset;
+
+  // Pointers to extracted PDCCH symbols in frequency-domain.
+  int32_t rx_size = 4*273*12;
+  int32_t rxdataF_ext[4*frame_parms->nb_antennas_rx][rx_size];
+  int32_t rxdataF_comp[4*frame_parms->nb_antennas_rx][rx_size];
+  int32_t pdcch_dl_ch_estimates_ext[4*frame_parms->nb_antennas_rx][rx_size];
+
+  // Pointer to llrs, 4-bit resolution.
+  int32_t llr_size = 2*4*100*12;
+  int16_t llr[llr_size];
+
   get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset);
   LOG_D(PHY,"pdcch coreset: freq %x, n_rb %d, rb_offset %d\n",
         rel15->coreset.frequency_domain_resource[0],n_rb,rb_offset);
@@ -684,9 +701,11 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
     LOG_D(PHY,"in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n");
 
     nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
-                                pdcch_vars->dl_ch_estimates,
-                                pdcch_vars->rxdataF_ext,
-                                pdcch_vars->dl_ch_estimates_ext,
+                                pdcch_est_size,
+                                pdcch_dl_ch_estimates,
+                                rx_size,
+                                rxdataF_ext,
+                                pdcch_dl_ch_estimates_ext,
                                 s,
                                 frame_parms,
                                 rel15->coreset.frequency_domain_resource,
@@ -696,7 +715,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
     LOG_D(PHY,"we enter nr_pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP);
     LOG_D(PHY,"in nr_pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n");
     // compute channel level based on ofdm symbol 0
-    nr_pdcch_channel_level(pdcch_vars->dl_ch_estimates_ext,
+    nr_pdcch_channel_level(rx_size,
+                           pdcch_dl_ch_estimates_ext,
                            frame_parms,
                            avgP,
                            s,
@@ -718,26 +738,33 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
     LOG_D(PHY,"we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh);
     LOG_D(PHY,"in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n");
     // compute LLRs for ofdm symbol 0 only
-    nr_pdcch_channel_compensation(pdcch_vars->rxdataF_ext,
-                                  pdcch_vars->dl_ch_estimates_ext,
-                                  pdcch_vars->rxdataF_comp,
+    nr_pdcch_channel_compensation(rx_size, rxdataF_ext,
+                                  pdcch_dl_ch_estimates_ext,
+                                  rxdataF_comp,
                                   NULL,
                                   frame_parms,
                                   s,
                                   log2_maxh,
                                   n_rb); // log2_maxh+I0_shift
+
+    UEscopeCopy(ue, pdcchRxdataF_comp, rxdataF_comp, sizeof(struct complex16), frame_parms->nb_antennas_rx, rx_size);
+
     if (frame_parms->nb_antennas_rx > 1) {
       LOG_D(PHY,"we enter nr_pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx);
-      nr_pdcch_detection_mrc(frame_parms, pdcch_vars->rxdataF_comp,s);
+      nr_pdcch_detection_mrc(frame_parms, rx_size, rxdataF_comp,s);
     }
 
     LOG_D(PHY,"we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s);
     LOG_D(PHY,"in nr_pdcch_llr(rxdataF_comp -> llr)\n");
     nr_pdcch_llr(frame_parms,
-                 pdcch_vars->rxdataF_comp,
-                 pdcch_vars->llr,
+                 rx_size,
+                 rxdataF_comp,
+                 llr,
                  s,
                  n_rb);
+
+    UEscopeCopy(ue, pdcchLlr, llr, sizeof(int16_t), 1, llr_size);
+
 #if T_TRACER
     
     //  T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL),
@@ -751,8 +778,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
   }
 
   LOG_D(PHY,"we enter nr_pdcch_demapping_deinterleaving(), number of candidates %d\n",rel15->number_of_candidates);
-  nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars->llr,
-                                    (uint32_t *) e_rx,
+  nr_pdcch_demapping_deinterleaving((uint32_t *) llr,
+                                    (uint32_t *) pdcch_e_rx,
                                     rel15->coreset.duration,
                                     rel15->coreset.StartSymbolIndex,
                                     n_rb,
@@ -833,13 +860,12 @@ static uint16_t nr_dci_false_detection(uint64_t *dci,
   return x;
 }
 
-uint8_t nr_dci_decoding_procedure(int16_t *e_rx,
-				  PHY_VARS_NR_UE *ue,
+uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
+                                  int16_t *pdcch_e_rx,
                                   fapi_nr_dci_indication_t *dci_ind,
-                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
-
-  NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0];
+                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
+                                  NR_UE_PDCCH_CONFIG *phy_pdcch_config) {
 
   //int gNB_id = 0;
   int16_t tmp_e[16*108];
@@ -870,7 +896,8 @@ uint8_t nr_dci_decoding_procedure(int16_t *e_rx,
       LOG_D(PHY, "(%i.%i) Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d, length %d, format %s\n",
             proc->frame_rx, proc->nr_slot_rx, j, rel15->number_of_candidates, CCEind, e_rx_cand_idx, L, dci_length, nr_dci_format_string[rel15->dci_format_options[k]]);
 
-      nr_pdcch_unscrambling(&e_rx[e_rx_cand_idx], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
+
+      nr_pdcch_unscrambling(&pdcch_e_rx[e_rx_cand_idx], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
 
 #ifdef DEBUG_DCI_DECODING
       uint32_t *z = (uint32_t *) &e_rx[e_rx_cand_idx];
@@ -915,7 +942,7 @@ uint8_t nr_dci_decoding_procedure(int16_t *e_rx,
     }
     e_rx_cand_idx += 9*L*6*2; //e_rx index for next candidate (L CCEs, 6 REGs per CCE and 9 REs per REG and 2 uint16_t per RE)
   }
-  pdcch_vars->nb_search_space = 0;
+  phy_pdcch_config->nb_search_space = 0;
   return(dci_ind->number_of_dcis);
 }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index db10c36613ddd4304775db3655ea261f87432eb5..1020735c72696da11f3a15a21e7fe777073f26e4 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -101,7 +101,7 @@ void free_list(NR_UE_SSB *node) {
 }
 
 
-int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol)
+int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, NR_UE_PDCCH_CONFIG *phy_pdcch_config)
 {
   NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   int ret =-1;
@@ -165,6 +165,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
                      0,
                      temp_ptr->i_ssb,
                      SISO,
+                     phy_pdcch_config,
                      &result);
 
     temp_ptr=temp_ptr->next_ssb;
@@ -215,6 +216,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
   NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
   int ret=-1;
   int rx_power=0; //aarx,
+
+  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN);
 
@@ -335,7 +338,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
 
       if (ret==0) { //we got sss channel
         nr_gold_pbch(ue);
-        ret = nr_pbch_detection(proc, ue, 1);  // start pbch detection at first symbol after pss
+        ret = nr_pbch_detection(proc, ue, 1, &phy_pdcch_config);  // start pbch detection at first symbol after pss
       }
 
       if (ret == 0) {
@@ -354,15 +357,17 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
         nr_gold_pdcch(ue,fp->Nid_cell);
 
         // compute the scrambling IDs for PDSCH DMRS
-        for (int i=0; i<2; i++)
-          ue->scramblingID[i]=fp->Nid_cell;
-
-        nr_gold_pdsch(ue,ue->scramblingID);
+        for (int i=0; i<NR_NB_NSCID; i++) {
+          ue->scramblingID_dlsch[i]=fp->Nid_cell;
+          nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
+        }
 
         // initialize the pusch dmrs
-        uint16_t N_n_scid[2] = {fp->Nid_cell,fp->Nid_cell};
-        int n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization
-        nr_init_pusch_dmrs(ue, N_n_scid, n_scid);
+        for (int i=0; i<NR_NB_NSCID; i++) {
+          ue->scramblingID_ulsch[i]=fp->Nid_cell;
+          nr_init_pusch_dmrs(ue, ue->scramblingID_ulsch[i], i);
+        }
+
 
         // we also need to take into account the shift by samples_per_frame in case the if is true
         if (ue->ssb_offset < sync_pos_frame){
@@ -531,33 +536,40 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
   // if stand alone and sync on ssb do sib1 detection as part of initial sync
   if (sa==1 && ret==0) {
     bool dec = false;
-    NR_UE_PDCCH *pdcch_vars  = ue->pdcch_vars[proc->thread_id][0];
     int gnb_id = 0; //FIXME
     int coreset_nb_rb=0;
     int coreset_start_rb=0;
 
-    for(int n_ss = 0; n_ss<pdcch_vars->nb_search_space; n_ss++) {
-      uint8_t nb_symb_pdcch = pdcch_vars->pdcch_config[n_ss].coreset.duration;
-      int start_symb = pdcch_vars->pdcch_config[n_ss].coreset.StartSymbolIndex;
-      get_coreset_rballoc(pdcch_vars->pdcch_config[n_ss].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
+    // Hold the channel estimates in frequency domain.
+    int32_t pdcch_est_size = fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH);
+    int32_t pdcch_dl_ch_estimates[4*fp->nb_antennas_rx][pdcch_est_size];
+
+
+    for(int n_ss = 0; n_ss<phy_pdcch_config.nb_search_space; n_ss++) {
+      uint8_t nb_symb_pdcch = phy_pdcch_config.pdcch_config[n_ss].coreset.duration;
+      int start_symb = phy_pdcch_config.pdcch_config[n_ss].coreset.StartSymbolIndex;
+      get_coreset_rballoc(phy_pdcch_config.pdcch_config[n_ss].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
       for (uint16_t l=start_symb; l<start_symb+nb_symb_pdcch; l++) {
         nr_slot_fep_init_sync(ue,
                               proc,
                               l, // the UE PHY has no notion of the symbols to be monitored in the search space
-                              pdcch_vars->slot,
-                              is*fp->samples_per_frame+pdcch_vars->sfn*fp->samples_per_frame+ue->rx_offset);
+                              phy_pdcch_config.slot,
+                              is*fp->samples_per_frame+phy_pdcch_config.sfn*fp->samples_per_frame+ue->rx_offset);
 
         if (coreset_nb_rb > 0)
           nr_pdcch_channel_estimation(ue,
                                       proc,
                                       0,
-                                      pdcch_vars->slot,
+                                      phy_pdcch_config.slot,
                                       l,
-                                      fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
-                                      coreset_nb_rb);
+                                      fp->Nid_cell,
+                                      fp->first_carrier_offset+(phy_pdcch_config.pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
+                                      coreset_nb_rb,
+                                      pdcch_est_size,
+                                      pdcch_dl_ch_estimates);
 
       }
-      int  dci_cnt = nr_ue_pdcch_procedures(gnb_id, ue, proc, n_ss);
+      int  dci_cnt = nr_ue_pdcch_procedures(gnb_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, &phy_pdcch_config, n_ss);
       if (dci_cnt>0){
         NR_UE_DLSCH_t *dlsch = ue->dlsch_SI[gnb_id];
         if (dlsch && (dlsch->active == 1)) {
@@ -570,8 +582,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
             nr_slot_fep_init_sync(ue,
                                   proc,
                                   m,
-                                  pdcch_vars->slot,  // same slot and offset as pdcch
-                                  is*fp->samples_per_frame+pdcch_vars->sfn*fp->samples_per_frame+ue->rx_offset);
+                                  phy_pdcch_config.slot,  // same slot and offset as pdcch
+                                  is*fp->samples_per_frame+phy_pdcch_config.sfn*fp->samples_per_frame+ue->rx_offset);
           }
 
           int ret = nr_ue_pdsch_procedures(ue,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index 2705132bc6adccc1aa917766c1ef5c9232d429e0..48b08d761ece8f76e29eb3f1e737f8a686ac4393 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -391,6 +391,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
                 uint8_t gNB_id,
                 uint8_t i_ssb,
                 MIMO_mode_t mimo_mode,
+                NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                 fapiPbch_t *result) {
   NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
   int max_h=0;
@@ -577,7 +578,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
   nr_downlink_indication_t dl_indication;
   fapi_nr_rx_indication_t *rx_ind=calloc(sizeof(*rx_ind),1);
   uint16_t number_pdus = 1;
-  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id);
+
+  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, phy_pdcch_config);
   nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus, proc,(void *)result);
 
   if (ue->if_inst && ue->if_inst->dl_indication)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
index 41e338fabe3c6e7226ca9600c8ac635cb4de0b7a..d1cdea2354f758dbaceb204d3251d43dbbb9612f 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -1076,8 +1076,11 @@ uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue,
 
 int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
                     UE_nr_rxtx_proc_t *proc,
-                    fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
-		    int16_t *e_rx);
+                    int32_t pdcch_est_size,
+                    int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+                    int16_t *pdcch_e_rx,
+                    fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
+
 
 /*! \brief Extract PSS and SSS resource elements
   @param phy_vars_ue Pointer to UE variables
@@ -1130,11 +1133,13 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
                 uint8_t eNB_id,
                 uint8_t i_ssb,
                 MIMO_mode_t mimo_mode,
-		fapiPbch_t* result);
+                NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+                fapiPbch_t* result);
 
 int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
-		      PHY_VARS_NR_UE *ue,
-                      int pbch_initial_symbol);
+		              PHY_VARS_NR_UE *ue,
+                      int pbch_initial_symbol,
+                      NR_UE_PDCCH_CONFIG *phy_pdcch_config);
 
 uint16_t rx_pbch_emul(PHY_VARS_NR_UE *phy_vars_ue,
                       uint8_t eNB_id,
@@ -1628,11 +1633,12 @@ uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms,
 
 #include <openair1/PHY/LTE_TRANSPORT/transport_proto.h>
 
-uint8_t nr_dci_decoding_procedure(int16_t *e_rx,
-				  PHY_VARS_NR_UE *ue,
+uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
+                                  int16_t *pdcch_e_rx,
                                   fapi_nr_dci_indication_t *dci_ind,
-                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
+                                  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
+                                  NR_UE_PDCCH_CONFIG *phy_pdcch_config);
 
 
 /** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation.  It performs
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index abfe52603fbe23ed2f858cdd3769071726536fe0..4086f60f02e956f5f2fe4c10bea0f5f9a7cbbf8b 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -260,6 +260,8 @@ typedef struct {
   uint16_t ptrs_symbols;
   // PTRS symbol index, to be updated every PTRS symbol within a slot.
   uint8_t ptrs_symbol_index;
+  uint8_t nscid;
+  uint16_t dlDmrsScramblingId;
   /// PDU BITMAP 
   uint16_t pduBitmap;
 } NR_DL_UE_HARQ_t;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 802cb55e03445dcd26ce7c17f3272022efb85c3f..bab0c75aff198ee80778f809d62c3de80eb43ca9 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -32,6 +32,7 @@
 #include <stdint.h>
 #include "PHY/NR_REFSIG/dmrs_nr.h"
 #include "PHY/NR_REFSIG/ptrs_nr.h"
+#include "PHY/NR_REFSIG/refsig_defs_ue.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
 #include "PHY/MODULATION/nr_modulation.h"
@@ -215,9 +216,16 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
   /////////////////////////DMRS Modulation/////////////////////////
   ///////////
-  uint32_t **pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
+
+  if(pusch_pdu->ul_dmrs_scrambling_id != UE->scramblingID_ulsch[pusch_pdu->scid])  {
+    UE->scramblingID_ulsch[pusch_pdu->scid] = pusch_pdu->ul_dmrs_scrambling_id;
+    nr_init_pusch_dmrs(UE, pusch_pdu->scid, pusch_pdu->ul_dmrs_scrambling_id);
+  }
+
+  uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
   uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
   int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16)));
+
   ///////////
   ////////////////////////////////////////////////////////////////////////
 
@@ -382,7 +390,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
           // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
           // Perform this on gold sequence, not required when SC FDMA operation is done,
           LOG_D(PHY,"DMRS in symbol %d\n",l);
-          nr_modulation(pusch_dmrs[l], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // Qm = 2 as DMRS is QPSK modulated
+          nr_modulation(pusch_dmrs[l][pusch_pdu->scid], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
         } else {
           dmrs_idx = 0;
         }
@@ -392,7 +400,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
         if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
           is_ptrs_sym = 1;
-          nr_modulation(pusch_dmrs[l], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
+          nr_modulation(pusch_dmrs[l][pusch_pdu->scid], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
         }
       }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
index 6ab5ec72e58a1b2e24807a96d6fedb00b3eafe04..ff8d5d42ff803118d1b2650d2044bd1647e3af73 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
@@ -558,6 +558,9 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric,
   }
   //#endif
 
+  if (Nid1==N_ID_1_NUMBER)
+    return -1;
+  
   int re = 0;
   int im = 0;
   if (Nid1 == N_ID_1_NUMBER) {
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index 970db701c71552570c81307165f764bfd1c09f56..723813fbb62632ba31b8f82e609a5dc74685174a 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -678,52 +678,42 @@ static void uePbchIQ  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_U
 
 static void uePcchLLR  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDCCH LLRs
-  if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr)
+  if (!data[pdcchLlr])
     return;
 
   //int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
   //int Qm = 2;
-  int coded_bits_per_codeword = 2*4*100*12; //num_re*Qm;
+  const int sz=data[pdcchLlr]->lineSz;
   float *llr, *bit;
-  oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0);
-  int base=0;
+  oai_xygraph_getbuff(graph, &bit, &llr, sz, 0);
 
-  for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
-    int16_t *pdcch_llr = (int16_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->llr;
-
-    for (int i=0; i<coded_bits_per_codeword; i++) {
-      llr[base+i] = (float) pdcch_llr[i];
-    }
+  int16_t *pdcch_llr = (int16_t *)(data[pdcchLlr]+1);
 
-    base+=coded_bits_per_codeword;
+  for (int i=0; i<sz; i++) {
+    llr[i] = (float) pdcch_llr[i];
   }
 
-  AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, "");
-  oai_xygraph(graph,bit,llr,base,0,10);
+  oai_xygraph(graph,bit,llr,sz,0,10);
 }
 static void uePcchIQ  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDCCH I/Q of MF Output
-  if (!phy_vars_ue->pdcch_vars[0][eNB_id]->rxdataF_comp[0])
+  if (!data[pdcchRxdataF_comp])
     return;
 
-  int nb=4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
+  const int sz=data[pdcchRxdataF_comp]->lineSz;
+  //const int antennas=data[pdcchRxdataF_comp]->colSz;
+  // We take the first antenna only for now
   float *I, *Q;
-  oai_xygraph_getbuff(graph, &I, &Q, nb*RX_NB_TH_MAX, 0);
-  int base=0;
-
-  for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
-    scopeSample_t *pdcch_comp = (scopeSample_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->rxdataF_comp[0];
+  oai_xygraph_getbuff(graph, &I, &Q, sz, 0);
 
-    for (int i=0; i< nb; i++) {
-      I[base+i] = pdcch_comp[i].r;
-      Q[base+i] = pdcch_comp[i].i;
-    }
+  scopeSample_t *pdcch_comp = (scopeSample_t *) (data[pdcchRxdataF_comp]+1);
 
-    base+=nb;
+  for (int i=0; i<sz; i++) {
+    I[i] = pdcch_comp[i].r;
+    Q[i] = pdcch_comp[i].i;
   }
 
-  AssertFatal(base <= nb*RX_NB_TH_MAX, "");
-  oai_xygraph(graph,I,Q,base,0,10);
+  oai_xygraph(graph,I,Q,sz,0,10);
 }
 static void uePdschLLR  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDSCH LLRs
@@ -908,7 +898,6 @@ static void *nrUEscopeThread(void *arg) {
   char *name="5G-UE-scope";
   fl_initialize (&fl_argc, &name, NULL, 0, 0);
   OAI_phy_scope_t  *form_nrue=create_phy_scope_nrue(0);
-  (( scopeData_t *)ue->scopeData)->liveData=calloc(sizeof(scopeGraphData_t *), UEdataTypeNumberOfItems);
 
   while (!oai_exit) {
     fl_freeze_form(form_nrue->phy_scope);
@@ -925,28 +914,43 @@ static void *nrUEscopeThread(void *arg) {
 }
 
 void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz) {
+  // Local static copy of the scope data bufs
+  // The active data buf is alterned to avoid interference between the Scope thread (display) and the Rx thread (data input)
+  // Index of "2" could be set to the number of Rx threads + 1
+  static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][2] = {0};
+  static int  copyDataBufsIdx[UEdataTypeNumberOfItems] = {0};
+
   scopeData_t *tmp=(scopeData_t *)ue->scopeData;
 
   if (tmp) {
-    scopeGraphData_t *live= ((scopeGraphData_t **)tmp->liveData)[type];
+    // Begin of critical zone between UE Rx threads that might copy new data at the same time: might require a mutex
+    int newCopyDataIdx = (copyDataBufsIdx[type]==0)?1:0;
+    copyDataBufsIdx[type] = newCopyDataIdx;
+    // End of critical zone between UE Rx threads
 
-    if (live == NULL || live->dataSize < elementSz*colSz*lineSz) {
-      scopeGraphData_t *ptr=realloc(live, sizeof(scopeGraphData_t) + elementSz*colSz*lineSz);
+    // New data will be copied in a different buffer than the live one
+    scopeGraphData_t *copyData= copyDataBufs[type][newCopyDataIdx];
+
+    if (copyData == NULL || copyData->dataSize < elementSz*colSz*lineSz) {
+      scopeGraphData_t *ptr=realloc(copyData, sizeof(scopeGraphData_t) + elementSz*colSz*lineSz);
 
       if (!ptr) {
         LOG_E(PHY,"can't realloc\n");
         return;
       } else {
-        live=ptr;
+        copyData=ptr;
       }
     }
 
-    live->dataSize=elementSz*colSz*lineSz;
-    live->elementSz=elementSz;
-    live->colSz=colSz;
-    live->lineSz=lineSz;
-    memcpy(live+1, dataIn,  elementSz*colSz*lineSz);
-    ((scopeGraphData_t **)tmp->liveData)[type]=live;
+    copyData->dataSize=elementSz*colSz*lineSz;
+    copyData->elementSz=elementSz;
+    copyData->colSz=colSz;
+    copyData->lineSz=lineSz;
+    memcpy(copyData+1, dataIn,  elementSz*colSz*lineSz);
+    copyDataBufs[type][newCopyDataIdx] = copyData;
+
+    // The new data just copied in the local static buffer becomes live now
+    ((scopeGraphData_t **)tmp->liveData)[type]=copyData;
   }
 }
 
@@ -954,6 +958,7 @@ void nrUEinitScope(PHY_VARS_NR_UE *ue) {
   AssertFatal(ue->scopeData=malloc(sizeof(scopeData_t)),"");
   scopeData_t *scope=(scopeData_t *) ue->scopeData;
   scope->copyData=UEcopyData;
+  AssertFatal(scope->liveData=calloc(sizeof(scopeGraphData_t *), UEdataTypeNumberOfItems),"");
   pthread_t forms_thread;
   threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
 }
diff --git a/openair1/PHY/TOOLS/oai_dfts.c b/openair1/PHY/TOOLS/oai_dfts.c
index 83207426fde1a4906866a2bdc1b082debcaa6441..c2b6a55210822fd4e066adf7888d4463309f164d 100644
--- a/openair1/PHY/TOOLS/oai_dfts.c
+++ b/openair1/PHY/TOOLS/oai_dfts.c
@@ -7082,43 +7082,40 @@ static inline void dft12f(simd_q15_t *x0,
 
   simd_q15_t tmp_dft12[12];
 
-  simd_q15_t *tmp_dft12_ptr = &tmp_dft12[0];
-
   // msg("dft12\n");
 
   bfly4_tw1(x0,
             x3,
             x6,
             x9,
-            tmp_dft12_ptr,
-            tmp_dft12_ptr+3,
-            tmp_dft12_ptr+6,
-            tmp_dft12_ptr+9);
-
+            tmp_dft12,
+            tmp_dft12+3,
+            tmp_dft12+6,
+            tmp_dft12+9);
 
   bfly4_tw1(x1,
             x4,
             x7,
             x10,
-            tmp_dft12_ptr+1,
-            tmp_dft12_ptr+4,
-            tmp_dft12_ptr+7,
-            tmp_dft12_ptr+10);
+            tmp_dft12+1,
+            tmp_dft12+4,
+            tmp_dft12+7,
+            tmp_dft12+10);
 
 
   bfly4_tw1(x2,
             x5,
             x8,
             x11,
-            tmp_dft12_ptr+2,
-            tmp_dft12_ptr+5,
-            tmp_dft12_ptr+8,
-            tmp_dft12_ptr+11);
+            tmp_dft12+2,
+            tmp_dft12+5,
+            tmp_dft12+8,
+            tmp_dft12+11);
 
   //  k2=0;
-  bfly3_tw1(tmp_dft12_ptr,
-            tmp_dft12_ptr+1,
-            tmp_dft12_ptr+2,
+  bfly3_tw1(tmp_dft12,
+            tmp_dft12+1,
+            tmp_dft12+2,
             y0,
             y4,
             y8);
@@ -7126,9 +7123,9 @@ static inline void dft12f(simd_q15_t *x0,
 
 
   //  k2=1;
-  bfly3(tmp_dft12_ptr+3,
-        tmp_dft12_ptr+4,
-        tmp_dft12_ptr+5,
+  bfly3(tmp_dft12+3,
+        tmp_dft12+4,
+        tmp_dft12+5,
         y1,
         y5,
         y9,
@@ -7138,9 +7135,9 @@ static inline void dft12f(simd_q15_t *x0,
 
 
   //  k2=2;
-  bfly3(tmp_dft12_ptr+6,
-        tmp_dft12_ptr+7,
-        tmp_dft12_ptr+8,
+  bfly3(tmp_dft12+6,
+        tmp_dft12+7,
+        tmp_dft12+8,
         y2,
         y6,
         y10,
@@ -7148,9 +7145,9 @@ static inline void dft12f(simd_q15_t *x0,
         W4_12);
 
   //  k2=3;
-  bfly3(tmp_dft12_ptr+9,
-        tmp_dft12_ptr+10,
-        tmp_dft12_ptr+11,
+  bfly3(tmp_dft12+9,
+        tmp_dft12+10,
+        tmp_dft12+11,
         y3,
         y7,
         y11,
@@ -10606,15 +10603,43 @@ int dfts_autoinit(void)
 
 #ifndef MR_MAIN
 
-void dft(uint8_t sizeidx, int16_t *sigF,int16_t *sig,unsigned char scale_flag){
-	AssertFatal((sizeidx>=0 && sizeidx<(int)DFT_SIZE_IDXTABLESIZE),"Invalid dft size index %i\n",sizeidx);
-	dft_ftab[sizeidx](sigF,sig,scale_flag);
+void dft(uint8_t sizeidx, int16_t *input,int16_t *output,unsigned char scale_flag){
+	AssertFatal((sizeidx >= 0 && sizeidx<DFT_SIZE_IDXTABLESIZE),"Invalid dft size index %i\n",sizeidx);
+        int algn=0xF;
+        #ifdef __AVX2__
+        if ( (dft_ftab[sizeidx].size%3) != 0 ) // there is no AVX2 implementation for multiples of 3 DFTs
+          algn=0x1F;
+        #endif 
+        AssertFatal(((intptr_t)output&algn)==0,"Buffers should be aligned %p",output);
+        if (((intptr_t)input)&algn) {
+          LOG_D(PHY, "DFT called with input not aligned, add a memcpy, size %d\n", sizeidx);
+          int sz=dft_ftab[sizeidx].size;
+          if (sizeidx==DFT_12) // This case does 8 DFTs in //
+            sz*=8;
+          int16_t tmp[sz*2] __attribute__ ((aligned(32))); // input and output are not in right type (int16_t instead of c16_t)
+          memcpy(tmp, input, sizeof tmp);
+          dft_ftab[sizeidx].func(tmp,output,scale_flag);
+        } else
+          dft_ftab[sizeidx].func(input,output,scale_flag);
 };
 
-void idft(uint8_t sizeidx, int16_t *sigF,int16_t *sig,unsigned char scale_flag){
-	AssertFatal((sizeidx>=0 && sizeidx<(int)IDFT_SIZE_IDXTABLESIZE),"Invalid idft size index %i\n",sizeidx);
-	idft_ftab[sizeidx](sigF,sig,scale_flag);
+void idft(uint8_t sizeidx, int16_t *input,int16_t *output,unsigned char scale_flag){
+	AssertFatal((sizeidx>=0 && sizeidx<DFT_SIZE_IDXTABLESIZE),"Invalid idft size index %i\n",sizeidx);
+        int algn=0xF;
+        #ifdef __AVX2__
+          algn=0x1F;
+        #endif
+        AssertFatal( ((intptr_t)output&algn)==0,"Buffers should be 16 bytes aligned %p",output);
+        if (((intptr_t)input)&algn ) {  
+          LOG_D(PHY, "DFT called with input not aligned, add a memcpy\n");
+          int sz=idft_ftab[sizeidx].size;
+          int16_t tmp[sz*2] __attribute__ ((aligned(32))); // input and output are not in right type (int16_t instead of c16_t)
+          memcpy(tmp, input, sizeof tmp);
+          dft_ftab[sizeidx].func(tmp,output,scale_flag);
+        } else
+          idft_ftab[sizeidx].func(input,output,scale_flag);
 };
+
 #endif
 
 /*---------------------------------------------------------------------------------------*/
diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h
index 9cd8e1dc40c0924d3b01f1ef7561bd46b46f1561..6162e1eee58023622c0aaccc5e2de962aa62bb67 100644
--- a/openair1/PHY/TOOLS/phy_scope_interface.h
+++ b/openair1/PHY/TOOLS/phy_scope_interface.h
@@ -45,6 +45,8 @@ enum UEdataType {
   pbchDlChEstimateTime,
   pbchLlr,
   pbchRxdataF_comp,
+  pdcchLlr,
+  pdcchRxdataF_comp,
   UEdataTypeNumberOfItems
 };
 
diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h
index c763ec6bac55e7da5a07bdca1ee2b6807d91f59f..145fbe4a31a2867e21f1ba645ea0ebef125a0a55 100644
--- a/openair1/PHY/TOOLS/tools_defs.h
+++ b/openair1/PHY/TOOLS/tools_defs.h
@@ -188,159 +188,156 @@ This function performs optimized fixed-point radix-2 FFT/IFFT.
         );
 */
 
-
+#define FOREACH_DFTSZ(SZ_DEF) \
+  SZ_DEF(12) \
+  SZ_DEF(24) \
+  SZ_DEF(36) \
+  SZ_DEF(48) \
+  SZ_DEF(60) \
+  SZ_DEF(64) \
+  SZ_DEF(72) \
+  SZ_DEF(96) \
+  SZ_DEF(108) \
+  SZ_DEF(120) \
+  SZ_DEF(128) \
+  SZ_DEF(144) \
+  SZ_DEF(180) \
+  SZ_DEF(192) \
+  SZ_DEF(216) \
+  SZ_DEF(240) \
+  SZ_DEF(256) \
+  SZ_DEF(288) \
+  SZ_DEF(300) \
+  SZ_DEF(324) \
+  SZ_DEF(360) \
+  SZ_DEF(384) \
+  SZ_DEF(432) \
+  SZ_DEF(480) \
+  SZ_DEF(512) \
+  SZ_DEF(540) \
+  SZ_DEF(576) \
+  SZ_DEF(600) \
+  SZ_DEF(648) \
+  SZ_DEF(720) \
+  SZ_DEF(768) \
+  SZ_DEF(864) \
+  SZ_DEF(900) \
+  SZ_DEF(960) \
+  SZ_DEF(972) \
+  SZ_DEF(1024) \
+  SZ_DEF(1080) \
+  SZ_DEF(1152) \
+  SZ_DEF(1200) \
+  SZ_DEF(1296) \
+  SZ_DEF(1440) \
+  SZ_DEF(1500) \
+  SZ_DEF(1536) \
+  SZ_DEF(1620) \
+  SZ_DEF(1728) \
+  SZ_DEF(1800) \
+  SZ_DEF(1920) \
+  SZ_DEF(1944) \
+  SZ_DEF(2048) \
+  SZ_DEF(2160) \
+  SZ_DEF(2304) \
+  SZ_DEF(2400) \
+  SZ_DEF(2592) \
+  SZ_DEF(2700) \
+  SZ_DEF(2880) \
+  SZ_DEF(2916) \
+  SZ_DEF(3000) \
+  SZ_DEF(3072) \
+  SZ_DEF(3240) \
+  SZ_DEF(4096) \
+  SZ_DEF(6144) \
+  SZ_DEF(8192) \
+  SZ_DEF(9216) \
+  SZ_DEF(12288) \
+  SZ_DEF(18432) \
+  SZ_DEF(24576) \
+  SZ_DEF(36864) \
+  SZ_DEF(49152) \
+  SZ_DEF(73728) \
+  SZ_DEF(98304)
+
+#define FOREACH_IDFTSZ(SZ_DEF)\
+  SZ_DEF(64) \
+  SZ_DEF(128) \
+  SZ_DEF(256) \
+  SZ_DEF(512) \
+  SZ_DEF(1024) \
+  SZ_DEF(1536) \
+  SZ_DEF(2048) \
+  SZ_DEF(3072) \
+  SZ_DEF(4096) \
+  SZ_DEF(6144) \
+  SZ_DEF(8192) \
+  SZ_DEF(9216) \
+  SZ_DEF(12288) \
+  SZ_DEF(18432) \
+  SZ_DEF(24576) \
+  SZ_DEF(36864) \
+  SZ_DEF(49152) \
+  SZ_DEF(73728) \
+  SZ_DEF(98304)
 
 #ifdef OAIDFTS_MAIN
-typedef  void(*adftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);  
-typedef  void(*aidftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);     
-
-void dft12(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft24(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft36(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft48(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft60(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft64(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft72(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft96(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft108(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft120(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft128(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft144(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft180(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft192(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft216(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft240(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft256(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft288(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft300(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft324(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft360(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft384(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft432(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft480(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft512(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft540(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft576(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft600(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft648(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft720(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft768(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft864(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft900(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft960(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft972(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1024(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1080(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1152(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1200(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1296(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1440(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1500(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void dft1620(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1728(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1800(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1920(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1944(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2048(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2160(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2304(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2400(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2592(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2700(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2880(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft2916(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft3000(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void dft3240(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft4096(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void dft8192(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft9216(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft12288(int16_t *x,int16_t *y,uint8_t scale_flag);  
-void dft18432(int16_t *x,int16_t *y,uint8_t scale_flag); 
-void dft24576(int16_t *x,int16_t *y,uint8_t scale_flag); 
-void dft36864(int16_t *x,int16_t *y,uint8_t scale_flag); 
-void dft49152(int16_t *x,int16_t *y,uint8_t scale_flag); 
-void dft73728(int16_t *x,int16_t *y,uint8_t scale_flag); 
-void dft98304(int16_t *x,int16_t *y,uint8_t scale_flag);
-
-
-void idft64(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft128(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft256(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft512(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft1024(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft2048(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft4096(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft8192(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft9216(int16_t *x,int16_t *y,uint8_t scale_flag);
-void idft12288(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft18432(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft24576(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft36864(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft49152(int16_t *sigF,int16_t *sig,uint8_t scale_flag); 
-void idft73728(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
-void idft98304(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+typedef  void(*adftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);
+typedef  void(*aidftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);
+
+#define SZ_FUNC(Sz) void dft ## Sz(int16_t *x,int16_t *y,uint8_t scale_flag);
 
+FOREACH_DFTSZ(SZ_FUNC)
 
+#define SZ_iFUNC(Sz) void idft ## Sz(int16_t *x,int16_t *y,uint8_t scale_flag);
 
+FOREACH_IDFTSZ(SZ_iFUNC)
 
 #else
-  typedef  void(*dftfunc_t)(uint8_t sizeidx,int16_t *sigF,int16_t *sig,unsigned char scale_flag);  
-  typedef  void(*idftfunc_t)(uint8_t sizeidx,int16_t *sigF,int16_t *sig,unsigned char scale_flag);  
+typedef  void(*dftfunc_t)(uint8_t sizeidx,int16_t *sigF,int16_t *sig,unsigned char scale_flag);
+typedef  void(*idftfunc_t)(uint8_t sizeidx,int16_t *sigF,int16_t *sig,unsigned char scale_flag);
 #  ifdef OAIDFTS_LOADER
-  dftfunc_t dft;
-  idftfunc_t idft;
+dftfunc_t dft;
+idftfunc_t idft;
 #  else
-  extern dftfunc_t dft;
-  extern idftfunc_t idft;
-  extern int load_dftslib(void);
+extern dftfunc_t dft;
+extern idftfunc_t idft;
+extern int load_dftslib(void);
 #  endif
 #endif
 
-typedef enum DFT_size_idx {
-	DFT_12,    DFT_24,    DFT_36,   DFT_48,     DFT_60,   DFT_72,   DFT_96,
-	DFT_108,   DFT_120,   DFT_128,  DFT_144,    DFT_180,  DFT_192,  DFT_216,   DFT_240,
-	DFT_256,   DFT_288,   DFT_300,  DFT_324,    DFT_360,  DFT_384,  DFT_432,   DFT_480,
-	DFT_512,   DFT_540,   DFT_576,  DFT_600,    DFT_648,  DFT_720,  DFT_768,   DFT_864,
-	DFT_900,   DFT_960,   DFT_972,  DFT_1024,   DFT_1080, DFT_1152, DFT_1200,  DFT_1296,
-	DFT_1440,  DFT_1500,  DFT_1536, DFT_1620,   DFT_1728, DFT_1800, DFT_1920,  DFT_1944,
-	DFT_2048,  DFT_2160,  DFT_2304, DFT_2400,   DFT_2592, DFT_2700, DFT_2880,  DFT_2916,
-	DFT_3000,  DFT_3072,  DFT_3240, DFT_4096,   DFT_6144, DFT_8192, DFT_9216,  DFT_12288,
-	DFT_18432, DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304,
-	DFT_SIZE_IDXTABLESIZE
-} dft_size_idx_t;
+#define SZ_ENUM(Sz) DFT_ ## Sz,
 
-#ifdef OAIDFTS_MAIN
-adftfunc_t dft_ftab[]={
-	dft12,    dft24,    dft36,    dft48,    dft60,   dft72,   dft96,
-	dft108,   dft120,   dft128,   dft144,   dft180,  dft192,  dft216,   dft240,
-	dft256,   dft288,   dft300,   dft324,   dft360,  dft384,  dft432,   dft480,
-	dft512,   dft540,   dft576,   dft600,   dft648,  dft720,  dft768,   dft864,
-	dft900,   dft960,   dft972,   dft1024,  dft1080, dft1152, dft1200,  dft1296,
-	dft1440,  dft1500,  dft1536,  dft1620,  dft1728, dft1800, dft1920,  dft1944,
-	dft2048,  dft2160,  dft2304,  dft2400,  dft2592, dft2700, dft2880,  dft2916,
-	dft3000,  dft3072,  dft3240,  dft4096,  dft6144, dft8192, dft9216,  dft12288,
-	dft18432, dft24576, dft36864, dft49152, dft73728, dft98304
-};
-#endif
+typedef enum dft_size_idx {
+  FOREACH_DFTSZ(SZ_ENUM)
+  DFT_SIZE_IDXTABLESIZE
+}  dft_size_idx_t;
+
+#define SZ_iENUM(Sz) IDFT_ ## Sz,
 
 typedef enum idft_size_idx {
-	IDFT_128,   IDFT_256,  IDFT_512,   IDFT_1024,  IDFT_1536,  IDFT_2048,  IDFT_3072,  IDFT_4096,
-	IDFT_6144,  IDFT_8192, IDFT_9216,  IDFT_12288, IDFT_18432, IDFT_24576, IDFT_36864, IDFT_49152, 
-	IDFT_73728, IDFT_98304, 
-	IDFT_SIZE_IDXTABLESIZE
-} idft_size_idx_t;
+  FOREACH_IDFTSZ(SZ_iENUM)
+  IDFT_SIZE_IDXTABLESIZE
+}  idft_size_idx_t;
+
 #ifdef OAIDFTS_MAIN
-aidftfunc_t idft_ftab[]={
-	idft128,   idft256,  idft512,   idft1024,  idft1536,  idft2048,  idft3072,  idft4096,
-	idft6144,  idft8192, idft9216,  idft12288, idft18432, idft24576, idft36864, idft49152,
-	idft73728, idft98304
+
+#define SZ_PTR(Sz) {dft ## Sz,Sz},
+struct {
+  adftfunc_t func;
+  int size;
+} dft_ftab[]= {
+  FOREACH_DFTSZ(SZ_PTR)
+};
+
+#define SZ_iPTR(Sz)  {idft ## Sz,Sz},
+struct {
+  adftfunc_t func;
+  int size;
+} idft_ftab[]= {
+  FOREACH_IDFTSZ(SZ_iPTR)
 };
+
 #endif
 
 
@@ -394,7 +391,7 @@ int32_t add_real_vector64(int16_t *x,
                           uint32_t N);
 
 int32_t sub_real_vector64(int16_t *x,
-                          int16_t* y,
+                          int16_t *y,
                           int16_t *z,
                           uint32_t N);
 
@@ -451,7 +448,7 @@ int32_t signal_energy_amp_shift(int32_t *input, uint32_t length);
 /*!\fn int32_t signal_energy(int *,uint32_t);
 \brief Computes the signal energy per subcarrier
 */
-int32_t subcarrier_energy(int32_t *,uint32_t, int32_t* subcarrier_energy, uint16_t rx_power_correction);
+int32_t subcarrier_energy(int32_t *,uint32_t, int32_t *subcarrier_energy, uint16_t rx_power_correction);
 #endif
 
 /*!\fn int32_t signal_energy_nodc(int32_t *,uint32_t);
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 4350688e5c6c8ff45ffb546cb98d478d70e2ae45..7b655c023a9bbd27db6c315528f38eef6c66bf50 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -850,9 +850,15 @@ typedef struct PHY_VARS_gNB_s {
   /// counter to average prach energh over first 100 prach opportunities
   int prach_energy_counter;
 
+  int csi_gold_init;
+  int pdcch_gold_init;
+  int pdsch_gold_init[2];
+  int pusch_gold_init[2];
+
   int ap_N1;
   int ap_N2;
   int ap_XP;
+
   int pucch0_thres;
   int pusch_thres;
   int prach_thres;
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 0bfe1b002c04f7193687d2f282dfbfadeba95293..82de7ed96ea014d117fc68f37d2c0129f575775a 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -550,57 +550,20 @@ typedef struct {
 } NR_UE_PDCCH_SEARCHSPACE;
 #endif
 typedef struct {
-  /// \brief Pointers to extracted PDCCH symbols in frequency-domain.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **rxdataF_ext;
-  /// \brief Pointers to extracted and compensated PDCCH symbols in frequency-domain.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **rxdataF_comp;
-  /// \brief Hold the channel estimates in frequency domain.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[
-  int32_t **dl_ch_estimates;
-  /// \brief Hold the channel estimates in time domain (used for tracking).
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: samples? [0..2*ofdm_symbol_size[
-  int32_t **dl_ch_estimates_time;
-  /// \brief Pointers to extracted channel estimates of PDCCH symbols.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_estimates_ext;
-  /// \brief Pointers to channel cross-correlation vectors for multi-gNB detection.
-  /// - first index: rx antenna [0..nb_antennas_rx[
-  /// - second index: ? [0..]
-  int32_t **rho;
-  /// \brief Pointer to llrs, 4-bit resolution.
-  /// - first index: ? [0..48*N_RB_DL[
-  int16_t *llr;
-  /// \brief Pointer to llrs, 16-bit resolution.
-  /// - first index: ? [0..96*N_RB_DL[
-  int16_t *llr16;
-  /// \brief \f$\overline{w}\f$ from 36-211.
-  /// - first index: ? [0..48*N_RB_DL[
-  int16_t *wbar;
-  /// Total number of PDU errors (diagnostic mode)
-  uint32_t dci_errors;
+  int nb_search_space;
+  uint16_t sfn;
+  uint16_t slot;
+  fapi_nr_dl_config_dci_dl_pdu_rel15_t pdcch_config[FAPI_NR_MAX_SS];
+} NR_UE_PDCCH_CONFIG;
+
+typedef struct {
   /// Total number of PDU received
   uint32_t dci_received;
   /// Total number of DCI False detection (diagnostic mode)
   uint32_t dci_false;
   /// Total number of DCI missed (diagnostic mode)
   uint32_t dci_missed;
-  /// nCCE for PDCCH per subframe
-  uint8_t nCCE[10];
-  //Check for specific DCIFormat and AgregationLevel
-  uint8_t dciFormat;
-  uint8_t agregationLevel;
-  int nb_search_space;
-  fapi_nr_dl_config_dci_dl_pdu_rel15_t pdcch_config[FAPI_NR_MAX_SS];
-  // frame and slot for sib1 in initial sync
-  uint16_t sfn;
-  uint16_t slot;
+
   /*
 #ifdef NR_PDCCH_DEFS_NR_UE
   int nb_searchSpaces;
@@ -786,7 +749,10 @@ typedef struct {
   uint32_t ****nr_gold_pdsch[NUMBER_OF_CONNECTED_eNB_MAX];
 
   // Scrambling IDs used in PDSCH DMRS
-  uint16_t scramblingID[2];
+  uint16_t scramblingID_dlsch[2];
+
+  // Scrambling IDs used in PUSCH DMRS
+  uint16_t scramblingID_ulsch[2];
 
   /// PDCCH DMRS
   uint32_t ***nr_gold_pdcch[NUMBER_OF_CONNECTED_eNB_MAX];
@@ -795,7 +761,7 @@ typedef struct {
   uint16_t scramblingID_pdcch;
 
   /// PUSCH DMRS sequence
-  uint32_t ***nr_gold_pusch_dmrs;
+  uint32_t ****nr_gold_pusch_dmrs;
 
   uint32_t X_u[64][839];
 
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index a546fb353f253fb3c30e19087c6b29b3a6ff4b6f..5f4ddc2fb55b1768a9ce36a31efc5449c168d041 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -95,6 +95,8 @@
 #define NR_RX_NB_TH 1
 #define NR_NB_TH_SLOT 2
 
+#define NR_NB_NSCID 2
+
 extern const uint8_t nr_rv_round_map[4]; 
 
 static inline
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index ee7f734ae2c8d35664fae8442cf36fd7e678ac07..46816d0373c118c4ecbb7d536441012ccbfea4fc 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -158,8 +158,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
   
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1);
 
-    nr_generate_dci_top(msgTx,
-			gNB->nr_gold_pdcch_dmrs[slot],
+    nr_generate_dci_top(msgTx, slot,
 			&gNB->common_vars.txdataF[0][txdataF_offset],
 			AMP, fp);
 
@@ -178,7 +177,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
     if (csirs->active == 1) {
       LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
       nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params = csirs->csirs_pdu.csi_rs_pdu_rel15;
-      nr_generate_csi_rs(gNB, AMP, csi_params, gNB->gNB_config.cell_config.phy_cell_id.value, slot);
+      nr_generate_csi_rs(gNB, AMP, csi_params, slot);
       csirs->active = 0;
     }
   }
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index eeea57ffc6125ddfd9af36ba9cb83a770f041d31..9bcf659eac83b4a279521acdc6cbeece4e980109 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -116,16 +116,18 @@ int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, re
 void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id);
 
 /*! \brief Scheduling for UE RX procedures in normal subframes.
-  @param ue             Pointer to UE variables on which to act
-  @param proc           Pointer to proc information
-  @param gNB_id         Local id of eNB on which to act
-  @param dlsch_parallel use multithreaded dlsch processing
-  @param txFifo         Result fifo if PDSCH is run in parallel
+  @param ue                     Pointer to UE variables on which to act
+  @param proc                   Pointer to proc information
+  @param gNB_id                 Local id of eNB on which to act
+  @param dlsch_parallel         use multithreaded dlsch processing
+  @param phy_pdcch_config       PDCCH Config for this slot
+  @param txFifo                 Result fifo if PDSCH is run in parallel
 */
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
                            uint8_t dlsch_parallel,
+                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                            notifiedFIFO_t *txFifo);
 
 int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
@@ -383,7 +385,8 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
                            fapi_nr_rx_indication_t *rx_ind,
                            UE_nr_rxtx_proc_t *proc,
                            PHY_VARS_NR_UE *ue,
-                           uint8_t gNB_id);
+                           uint8_t gNB_id,
+                           void *phy_data);
 
 /*@}*/
 
@@ -417,8 +420,11 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
                            NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1);
 
 int nr_ue_pdcch_procedures(uint8_t gNB_id,
-			   PHY_VARS_NR_UE *ue,
-			   UE_nr_rxtx_proc_t *proc,
+                           PHY_VARS_NR_UE *ue,
+                           UE_nr_rxtx_proc_t *proc,
+                           int32_t pdcch_est_size,
+                           int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                            int n_ss);
 
 
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 257b727258abc8d437d44155f019621f1f553091..51b34fb9baa9d2014129041190a74a2fe5d37759 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -315,6 +315,8 @@ void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
   dlsch0_harq->mcs = dlsch_config_pdu->mcs;
   dlsch0_harq->rvidx = dlsch_config_pdu->rv;
   dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
+  dlsch0_harq->nscid = dlsch_config_pdu->nscid;
+  dlsch0_harq->dlDmrsScramblingId = dlsch_config_pdu->dlDmrsScramblingId;
   //get nrOfLayers from DCI info
   uint8_t Nl = 0;
   for (int i = 0; i < 12; i++) { // max 12 ports
@@ -351,15 +353,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
     // Note: we have to handle the thread IDs for this. To be revisited completely.
     thread_id = scheduled_response->thread_id;
     NR_UE_DLSCH_t *dlsch0 = NULL;
-    NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0];
     NR_UE_ULSCH_t *ulsch = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0];
     NR_UE_PUCCH *pucch_vars = PHY_vars_UE_g[module_id][cc_id]->pucch_vars[thread_id][0];
+    NR_UE_PDCCH_CONFIG *phy_pdcch_config = NULL;
 
     if(scheduled_response->dl_config != NULL){
       fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
       fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu;
       fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config;
-      pdcch_vars->nb_search_space = 0;
 
       for (int i = 0; i < dl_config->number_pdus; ++i){
         AssertFatal(dl_config->number_pdus < FAPI_NR_DL_CONFIG_LIST_NUM,"dl_config->number_pdus %d out of bounds\n",dl_config->number_pdus);
@@ -369,12 +370,16 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
         switch(dl_config->dl_config_list[i].pdu_type) {
           case FAPI_NR_DL_CONFIG_TYPE_DCI:
+            if (NULL == phy_pdcch_config) {
+              phy_pdcch_config = (NR_UE_PDCCH_CONFIG *)scheduled_response->phy_data;
+              phy_pdcch_config->nb_search_space = 0;
+            }
             pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
-            memcpy(&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],pdcch_config,sizeof(*pdcch_config));
-            pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1;
-            pdcch_vars->sfn = scheduled_response->frame;
-            pdcch_vars->slot = slot;
-            LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space);
+            memcpy((void*)&phy_pdcch_config->pdcch_config[phy_pdcch_config->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config));
+            phy_pdcch_config->nb_search_space = phy_pdcch_config->nb_search_space + 1;
+            phy_pdcch_config->sfn = scheduled_response->frame;
+            phy_pdcch_config->slot = slot;
+            LOG_D(PHY,"Number of DCI SearchSpaces %d\n",phy_pdcch_config->nb_search_space);
             break;
           case FAPI_NR_DL_CONFIG_TYPE_CSI_IM:
             LOG_I(PHY,"Received CSI-IM PDU at FAPI\n");
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index ba8c5913a82f96c44d4f00c1a3713e92987250cf..974e112990be5b84877a6e3a4eef08bec2168f9c 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -87,7 +87,8 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
                            fapi_nr_rx_indication_t *rx_ind,
                            UE_nr_rxtx_proc_t *proc,
                            PHY_VARS_NR_UE *ue,
-                           uint8_t gNB_id){
+                           uint8_t gNB_id,
+                           void *phy_data){
 
   memset((void*)dl_ind, 0, sizeof(nr_downlink_indication_t));
 
@@ -97,6 +98,7 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
   dl_ind->frame     = proc->frame_rx;
   dl_ind->slot      = proc->nr_slot_rx;
   dl_ind->thread_id = proc->thread_id;
+  dl_ind->phy_data  = phy_data;
 
   if (dci_ind) {
 
@@ -360,7 +362,7 @@ void nr_ue_measurement_procedures(uint16_t l,
 
 static void nr_ue_pbch_procedures(uint8_t gNB_id,
 			   PHY_VARS_NR_UE *ue,
-				  UE_nr_rxtx_proc_t *proc,int estimateSz, struct complex16 dl_ch_estimates[][estimateSz])
+				  UE_nr_rxtx_proc_t *proc,int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], NR_UE_PDCCH_CONFIG *phy_pdcch_config)
 {
   int ret = 0;
 
@@ -380,7 +382,8 @@ static void nr_ue_pbch_procedures(uint8_t gNB_id,
                    gNB_id,
                    (ue->frame_parms.ssb_index)&7,
                    SISO,
-		   &result);
+                   phy_pdcch_config,
+                   &result);
 
   if (ret==0) {
 
@@ -486,6 +489,9 @@ unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb
 int nr_ue_pdcch_procedures(uint8_t gNB_id,
                            PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
+                           int32_t pdcch_est_size,
+                           int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                            int n_ss)
 {
   int frame_rx = proc->frame_rx;
@@ -494,14 +500,16 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
   fapi_nr_dci_indication_t *dci_ind = calloc(1, sizeof(*dci_ind));
   nr_downlink_indication_t dl_indication;
 
-  NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][gNB_id];
-  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &pdcch_vars->pdcch_config[n_ss];
+  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[n_ss];
 
   start_meas(&ue->dlsch_rx_pdcch_stats);
 
+  /// PDCCH/DCI e-sequence (input to rate matching).
+  int32_t pdcch_e_rx_size = NR_MAX_PDCCH_SIZE;
+  int16_t pdcch_e_rx[pdcch_e_rx_size];
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
-  int16_t e_rx[NR_MAX_PDCCH_SIZE]={0};
-  nr_rx_pdcch(ue, proc, rel15, e_rx);
+  nr_rx_pdcch(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, pdcch_e_rx, rel15);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
   
 
@@ -512,7 +520,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
 	 n_ss);
 #endif
 
-  dci_cnt = nr_dci_decoding_procedure(e_rx, ue, proc, dci_ind, rel15);
+  dci_cnt = nr_dci_decoding_procedure(ue, proc, pdcch_e_rx, dci_ind, rel15, phy_pdcch_config);
 
 #ifdef NR_PDCCH_SCHED_DEBUG
   LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt);
@@ -532,11 +540,13 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
   ue->pdcch_vars[proc->thread_id][gNB_id]->dci_received += dci_cnt;
 
   dci_ind->number_of_dcis = dci_cnt;
+
   // fill dl_indication message
-  nr_fill_dl_indication(&dl_indication, dci_ind, NULL, proc, ue, gNB_id);
+  nr_fill_dl_indication(&dl_indication, dci_ind, NULL, proc, ue, gNB_id, phy_pdcch_config);
   //  send to mac
   ue->if_inst->dl_indication(&dl_indication, NULL);
 
+
   stop_meas(&ue->dlsch_rx_pdcch_stats);
     
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
@@ -581,6 +591,8 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
                                       nr_slot_rx,
                                       get_dmrs_port(aatx,dlsch0_harq->dmrs_ports),
                                       m,
+                                      dlsch0_harq->nscid,
+                                      dlsch0_harq->dlDmrsScramblingId,
                                       BWPStart,
                                       dlsch0_harq->dmrsConfigType,
                                       ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12,
@@ -800,16 +812,16 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 
     switch (pdsch) {
       case RA_PDSCH:
-        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id);
+        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
         nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
         ue->UE_mode[gNB_id] = RA_RESPONSE;
         break;
       case PDSCH:
-        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id);
+        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
         nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
         break;
       case SI_PDSCH:
-        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id);
+        nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
         nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
         break;
       default:
@@ -1367,6 +1379,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
                            uint8_t dlsch_parallel,
+                           NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                            notifiedFIFO_t *txFifo
                            )
 {                                         
@@ -1374,10 +1387,9 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   int nr_slot_rx = proc->nr_slot_rx;
   int slot_pbch;
   int slot_ssb;
-  NR_UE_PDCCH *pdcch_vars  = ue->pdcch_vars[proc->thread_id][0];
   fapi_nr_config_request_t *cfg = &ue->nrUE_config;
 
-  uint8_t nb_symb_pdcch = pdcch_vars->nb_search_space > 0 ? pdcch_vars->pdcch_config[0].coreset.duration : 0;
+  uint8_t nb_symb_pdcch = phy_pdcch_config->nb_search_space > 0 ? phy_pdcch_config->pdcch_config[0].coreset.duration : 0;
   uint8_t dci_cnt = 0;
   NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
   
@@ -1396,8 +1408,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   int coreset_nb_rb=0;
   int coreset_start_rb=0;
 
-  if (pdcch_vars->nb_search_space > 0)
-    get_coreset_rballoc(pdcch_vars->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
+  if (phy_pdcch_config->nb_search_space > 0)
+    get_coreset_rballoc(phy_pdcch_config->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
 
   slot_pbch = is_pbch_in_slot(cfg, frame_rx, nr_slot_rx, fp);
   slot_ssb  = is_ssb_in_slot(cfg, frame_rx, nr_slot_rx, fp);
@@ -1428,7 +1440,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
     if ((ue->decode_MIB == 1) && slot_pbch) {
 
       LOG_D(PHY," ------  Decode MIB: frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
-      nr_ue_pbch_procedures(gNB_id, ue, proc, estimateSz, dl_ch_estimates);
+      nr_ue_pbch_procedures(gNB_id, ue, proc, estimateSz, dl_ch_estimates, phy_pdcch_config);
 
       if (ue->no_timing_correction==0) {
         LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
@@ -1469,13 +1481,17 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                 nr_slot_rx);
   }
 
+    // Hold the channel estimates in frequency domain.
+  int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16);
+  __attribute__ ((aligned(16))) int32_t pdcch_dl_ch_estimates[4*fp->nb_antennas_rx][pdcch_est_size];
+
   dci_cnt = 0;
-  for(int n_ss = 0; n_ss<pdcch_vars->nb_search_space; n_ss++) {
+  for(int n_ss = 0; n_ss<phy_pdcch_config->nb_search_space; n_ss++) {
     for (uint16_t l=0; l<nb_symb_pdcch; l++) {
 
       // note: this only works if RBs for PDCCH are contigous!
       LOG_D(PHY, "pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d, coreset_nb_rb %d\n",
-            fp->first_carrier_offset, pdcch_vars->pdcch_config[n_ss].BWPStart, coreset_start_rb, coreset_nb_rb);
+            fp->first_carrier_offset, phy_pdcch_config->pdcch_config[n_ss].BWPStart, coreset_start_rb, coreset_nb_rb);
 
       if (coreset_nb_rb > 0)
         nr_pdcch_channel_estimation(ue,
@@ -1483,13 +1499,16 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                                     gNB_id,
                                     nr_slot_rx,
                                     l,
-                                    fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
-                                    coreset_nb_rb);
+                                    phy_pdcch_config->pdcch_config[n_ss].coreset.pdcch_dmrs_scrambling_id,
+                                    fp->first_carrier_offset+(phy_pdcch_config->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
+                                    coreset_nb_rb,
+                                    pdcch_est_size,
+                                    pdcch_dl_ch_estimates);
 
       stop_meas(&ue->ofdm_demod_stats);
 
     }
-    dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc, n_ss);
+    dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_pdcch_config, n_ss);
   }
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
 
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index 21a2b98585aeec621a2f6b08881dfa17d1f8cf6c..64e377b896716985b964dcfa229444bd4a20a0a0 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -618,7 +618,7 @@ int main(int argc, char **argv)
 	 }
 	 }*/
 
-  free(test_input);
+	//free(test_input); it must not be free as it is in DLSCH_struct -> free_gNB_dlsch () -> free(harq->pdu) with no checks or control
 
   free_channel_desc_scm(gNB2UE);
 
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index b6314e344b4ba1629e2031c84f636491e4379800..00262149c9e8486f1dc606c4a1fc9ba905a45dd4 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -961,10 +961,10 @@ int main(int argc, char **argv)
   nr_gold_pdcch(UE, frame_parms->Nid_cell);
 
   // compute the scrambling IDs for PDSCH DMRS
-  for (int i = 0; i < 2; i++)
-    UE->scramblingID[i] = frame_parms->Nid_cell;
-
-  nr_gold_pdsch(UE, UE->scramblingID);
+  for (int i = 0; i < 2; i++) {
+    UE->scramblingID_dlsch[i] = frame_parms->Nid_cell;
+    nr_gold_pdsch(UE, i, UE->scramblingID_dlsch[i]);
+  }
 
   nr_l2_init_ue(NULL);
   UE_mac = get_mac_inst(0);
@@ -1003,6 +1003,8 @@ int main(int argc, char **argv)
 
   nr_dcireq_t dcireq;
   nr_scheduled_response_t scheduled_response;
+  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
+
   memset((void*)&dcireq,0,sizeof(dcireq));
   memset((void*)&scheduled_response,0,sizeof(scheduled_response));
   dcireq.module_id = 0;
@@ -1017,6 +1019,7 @@ int main(int argc, char **argv)
   scheduled_response.frame = frame;
   scheduled_response.slot  = slot;
   scheduled_response.thread_id = 0;
+  scheduled_response.phy_data = &phy_pdcch_config;
 
   nr_ue_phy_config_request(&UE_mac->phy_config);
   //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
@@ -1259,6 +1262,7 @@ int main(int argc, char **argv)
                                &UE_proc,
                                0,
                                dlsch_threads,
+                               &phy_pdcch_config,
                                NULL);
         
         //printf("dlsim round %d ends\n",round);
@@ -1407,8 +1411,6 @@ int main(int argc, char **argv)
       LOG_M("chestF0.m","chF0",&UE->pdsch_vars[0][0]->dl_ch_estimates_ext[0][0],g_rbSize*12*14,1,1);
       write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1);
       LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE_proc.thread_id][0]->llr[0],available_bits,1,0);
-      LOG_M("pdcch_rxFcomp.m","pdcch_rxFcomp",&UE->pdcch_vars[0][0]->rxdataF_comp[0][0],96*12,1,1);
-      LOG_M("pdcch_rxFllr.m","pdcch_rxFllr",UE->pdcch_vars[0][0]->llr,96*12,1,1);
       break;
     }
 
diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
index 351c2f33c47a74a94e8276201289767a47b67973..2d1fc597557518e993d84c2d83636c37457b01c1 100644
--- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
+++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
@@ -28,7 +28,8 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
                            fapi_nr_rx_indication_t *rx_ind,
                            UE_nr_rxtx_proc_t *proc,
                            PHY_VARS_NR_UE *ue,
-                           uint8_t gNB_id) {}
+                           uint8_t gNB_id,
+                           void *phy_data) {}
 void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
                            uint8_t pdu_type,
                            uint8_t gNB_id,
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 8fc6410538a25f57c55fc6b70cb60dc1c065fd13..62f6b21528e81082024a49f68e718cad646c7057 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -74,7 +74,10 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
 int nr_ue_pdcch_procedures(uint8_t gNB_id,
 			   PHY_VARS_NR_UE *ue,
 			   UE_nr_rxtx_proc_t *proc,
-                           int n_ss) {
+         int32_t pdcch_est_size,
+         int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+         NR_UE_PDCCH_CONFIG *phy_pdcch_config,
+         int n_ss) {
   return 0;
 }
 
@@ -722,6 +725,8 @@ int main(int argc, char **argv)
       }
       else {
 	UE_nr_rxtx_proc_t proc={0};
+  NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
+
 	UE->rx_offset=0;
 	uint8_t ssb_index = 0;
 	const int estimateSz=7*2*sizeof(int)*frame_parms->ofdm_symbol_size;
@@ -750,7 +755,8 @@ int main(int argc, char **argv)
                          0,
                          ssb_index%8,
                          SISO,
-			 &result);
+                         &phy_pdcch_config,
+                         &result);
 
 	if (ret==0) {
 	  //UE->rx_ind.rx_indication_body->mib_pdu.ssb_index;  //not yet detected automatically
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 2646e5da586c1c929ff80e8d206f8b4b0dac3e92..09499248b2c96767352c5c6e0e6189d109087327 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -782,10 +782,10 @@ int main(int argc, char **argv)
 
   init_nr_ue_transport(UE);
 
-  // initialize the pusch dmrs
-  uint16_t N_n_scid[2] = {frame_parms->Nid_cell,frame_parms->Nid_cell};
-  int n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization
-  nr_init_pusch_dmrs(UE, N_n_scid, n_scid);
+  for(int n_scid = 0; n_scid<2; n_scid++) {
+    UE->scramblingID_ulsch[n_scid] = frame_parms->Nid_cell;
+    nr_init_pusch_dmrs(UE, frame_parms->Nid_cell, n_scid);
+  }
 
   //Configure UE
   NR_UE_RRC_INST_t rrcue;
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index eb6b2bdccd4a7fa2a6093ab0cf2077e76ea46728..8cd831970fae7b9b6a4a84aa6b4959b0ab2893b1 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -154,7 +154,7 @@ typedef enum {
 {GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N2, "vert. log. antenna ports", 0, iptr:NULL,  defintval:1,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_PDSCHANTENNAPORTS_XP, "XP log. antenna ports",   0, iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_PUSCHANTENNAPORTS,            NULL,   0,            iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
-{GNB_CONFIG_STRING_SIB1TDA,                      NULL,   0,            iptr:NULL,   defintval:0,                 TYPE_INT,       0},  \
+{GNB_CONFIG_STRING_SIB1TDA,                      NULL,   0,            iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_DOCSIRS,                      NULL,   0,            iptr:NULL,   defintval:0,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_DOSRS,                        NULL,   0,            iptr:NULL,   defintval:0,                 TYPE_INT,       0},  \
 {GNB_CONFIG_STRING_NRCELLID,                     NULL,   0,            u64ptr:NULL, defint64val:1,               TYPE_UINT64,    0},  \
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 3e4d53b985be0ae4270287fed9ef0e5d7ec2e4e4..7ed99b92b5131d76740fb7b61b714a4759e05422 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -48,6 +48,7 @@ void nr_ue_init_mac(module_id_t module_idP);
    \param module_id      module id
    \param cc_id          component carrier id
    \param gNB_index      gNB index
+   \param phy_data       PHY structure to be filled in by the callee in the FAPI call (L1 caller -> indication to L2 -> FAPI call to L1 callee)
    \param extra_bits     extra bits for frame calculation
    \param l_ssb_equal_64 check if ssb number of candicate is equal 64, 1=equal; 0=non equal. Reference 38.212 7.1.1
    \param pduP           pointer to pdu
@@ -56,7 +57,8 @@ void nr_ue_init_mac(module_id_t module_idP);
 int8_t nr_ue_decode_mib(
     module_id_t module_id, 
     int cc_id, 
-    uint8_t gNB_index, 
+    uint8_t gNB_index,
+    void *phy_data, 
     uint8_t extra_bits, 
     uint32_t ssb_length, 
     uint32_t ssb_index,
@@ -132,7 +134,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
    @param int cc_id                    CC ID
    @param frame_t frame                frame number
    @param int slot                     reference number
-   @param UE_nr_rxtx_proc_t *proc      pointer to process context */
+   @param void *phy_pata               pointer to a PHY specific structure to be filled in the scheduler response (can be null) */
 void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
                              fapi_nr_dl_config_request_t *dl_config,
                              fapi_nr_ul_config_request_t *ul_config,
@@ -141,7 +143,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
                              int cc_id,
                              frame_t frame,
                              int slot,
-                             int thread_id);
+                             int thread_id,
+                             void *phy_data);
 
 /*! \fn int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
    \brief Called by PHY to get sdu for PUSCH transmission.  It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures.  It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header.  CRNTI element is not supported yet.  It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU.
@@ -373,7 +376,8 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
                           uint8_t ssb_subcarrier_offset,
                           uint32_t ssb_index,
                           uint16_t ssb_start_subcarrier,
-                          frequency_range_t frequency_range);
+                          frequency_range_t frequency_range,
+                          void *phy_data);
 
 /* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It provides the timing advance and t-CRNTI.
 @param Mod_id Index of UE instance
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index ab63303629d3a60e5a4dd90de3913119d4e9bb60..79ebaea70ace7b82964b141988301fb974709d37 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -281,13 +281,13 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){
     LOG_D(MAC, "In %s: returning rnti_type %s \n", __FUNCTION__, rnti_types[rnti_type]);
 
     return rnti_type;
-
 }
 
 
 int8_t nr_ue_decode_mib(module_id_t module_id,
                         int cc_id,
                         uint8_t gNB_index,
+                        void *phy_data,
                         uint8_t extra_bits,	//	8bits 38.212 c7.1.1
                         uint32_t ssb_length,
                         uint32_t ssb_index,
@@ -363,7 +363,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
                            ssb_subcarrier_offset,
                            ssb_index,
                            ssb_start_subcarrier,
-                           mac->frequency_range);
+                           mac->frequency_range,
+                           phy_data);
   }
   else {
     NR_ServingCellConfigCommon_t *scc = mac->scc;
@@ -874,14 +875,26 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     if(pdsch_TimeDomainAllocationList && rnti!=SI_RNTI)
       mappingtype = pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType;
 
+    struct NR_DMRS_DownlinkConfig *dl_dmrs_config = NULL;
+    if(mac->DLbwp[0])
+      dl_dmrs_config = (mappingtype == typeA) ?
+                       mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup :
+                       mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup;
+
+    dlsch_config_pdu_1_0->nscid = 0;
+    if(dl_dmrs_config && dl_dmrs_config->scramblingID0)
+      dlsch_config_pdu_1_0->dlDmrsScramblingId = *dl_dmrs_config->scramblingID0;
+    else
+      dlsch_config_pdu_1_0->dlDmrsScramblingId = mac->physCellId;
+
     /* dmrs symbol positions*/
     dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
                                                          (get_softmodem_params()->nsa) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position,
                                                          dlsch_config_pdu_1_0->number_symbols,
                                                          dlsch_config_pdu_1_0->start_symbol,
                                                          mappingtype, 1);
-    dlsch_config_pdu_1_0->dmrsConfigType = (mac->DLbwp[0] != NULL) ?
-                                           (mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0;
+    dlsch_config_pdu_1_0->dmrsConfigType = (dl_dmrs_config != NULL) ?
+                                           (dl_dmrs_config->dmrs_Type == NULL ? 0 : 1) : 0;
 
     /* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */
     if (dlsch_config_pdu_1_0->number_symbols == 2)
@@ -1075,7 +1088,30 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     if(pdsch_TimeDomainAllocationList)
       mappingtype = pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType;
 
-    dlsch_config_pdu_1_1->dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2;
+    struct NR_DMRS_DownlinkConfig *dl_dmrs_config = (mappingtype == typeA) ?
+                                                    pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup :
+                                                    pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup;
+
+    switch (dci->dmrs_sequence_initialization.val) {
+      case 0:
+        dlsch_config_pdu_1_1->nscid = 0;
+        if(dl_dmrs_config->scramblingID0)
+          dlsch_config_pdu_1_1->dlDmrsScramblingId = *dl_dmrs_config->scramblingID0;
+        else
+          dlsch_config_pdu_1_1->dlDmrsScramblingId = mac->physCellId;
+        break;
+      case 1:
+        dlsch_config_pdu_1_1->nscid = 1;
+        if(dl_dmrs_config->scramblingID1)
+          dlsch_config_pdu_1_1->dlDmrsScramblingId = *dl_dmrs_config->scramblingID1;
+        else
+          dlsch_config_pdu_1_1->dlDmrsScramblingId = mac->physCellId;
+        break;
+      default:
+        AssertFatal(1==0,"Invalid dmrs sequence initialization value\n");
+    }
+
+    dlsch_config_pdu_1_1->dmrsConfigType = dl_dmrs_config->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2;
 
     /* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214,
              using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */
@@ -1136,17 +1172,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
 
     /* ANTENNA_PORTS */
     uint8_t n_codewords = 1; // FIXME!!!
-    long *max_length = NULL;
-    long *dmrs_type = NULL;
+    long *max_length = dl_dmrs_config->maxLength;
+    long *dmrs_type = dl_dmrs_config->dmrs_Type;
+
     dlsch_config_pdu_1_1->n_front_load_symb = 1; // default value
-    if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA) {
-      max_length = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength;
-      dmrs_type = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type;
-    }
-    if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB) {
-      max_length = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength;
-      dmrs_type = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type;
-    }
+
     if ((dmrs_type == NULL) && (max_length == NULL)){
       // Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1
       dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_1[dci->antenna_ports.val][0];
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index cef910fc184996d5ff2c4906df640f3c021e0dfa..0afad893d750a4cc7a2c05ecf43ca9ba2e58004d 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -93,7 +93,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
                              int cc_id,
                              frame_t frame,
                              int slot,
-                             int thread_id){
+                             int thread_id,
+                             void *phy_data){
 
   scheduled_response->dl_config  = dl_config;
   scheduled_response->ul_config  = ul_config;
@@ -103,6 +104,7 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
   scheduled_response->frame      = frame;
   scheduled_response->slot       = slot;
   scheduled_response->thread_id  = thread_id;
+  scheduled_response->phy_data   = phy_data;
 
 }
 
@@ -734,6 +736,11 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
                          ? pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
     }
 
+    pusch_config_pdu->scid = 0;
+    pusch_config_pdu->ul_dmrs_scrambling_id = mac->physCellId;
+    if(*dci_format == NR_UL_DCI_FORMAT_0_1)
+      pusch_config_pdu->scid = dci->dmrs_sequence_initialization.val;
+
     /* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/
 
     if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) {
@@ -759,6 +766,14 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
       LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d \n", pusch_config_pdu->num_dmrs_cdm_grps_no_data,
                 pusch_config_pdu->dfts_ofdm.low_papr_group_number);
     }
+    else {
+      if (pusch_config_pdu->scid == 0 &&
+          NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0)
+        pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0;
+      if (pusch_config_pdu->scid == 1 &&
+          NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1)
+        pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1;
+    }
 
     /* TRANSFORM PRECODING --------------------------------------------------------------------------------------------------------*/
 
@@ -1059,7 +1074,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
       nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
       mac->dl_config_request = dcireq.dl_config_req;
 
-      fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
+      fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data);
       if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
         mac->if_module->scheduled_response(&scheduled_response);
     }
@@ -1075,7 +1090,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
         fill_dci_search_candidates(mac->ra.ss, rel15);
         dl_config->number_pdus = 1;
         LOG_D(MAC,"mac->cg %p: Calling fill_scheduled_response rnti %x, type0_pdcch, num_pdus %d\n",mac->cg,rel15->rnti,dl_config->number_pdus);
-        fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
+        fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data);
         if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
           mac->if_module->scheduled_response(&scheduled_response);
       }
@@ -1184,7 +1199,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
         }
         pthread_mutex_unlock(&ul_config->mutex_ul_config); // avoid double lock
 
-        fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, frame_tx, slot_tx, ul_info->thread_id);
+        fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, frame_tx, slot_tx, ul_info->thread_id, NULL);
         if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
           mac->if_module->scheduled_response(&scheduled_response);
         }
@@ -2339,7 +2354,7 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
                           O_SR, O_ACK, O_CSI);
     LOG_D(NR_MAC, "Configuring pucch, is_common = %d\n", pucch.is_common);
     nr_scheduled_response_t scheduled_response;
-    fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
+    fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id, NULL);
     if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
       mac->if_module->scheduled_response(&scheduled_response);
   }
@@ -2686,7 +2701,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
         }
       } // if format1
 
-      fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
+      fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id, NULL);
       if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
         mac->if_module->scheduled_response(&scheduled_response);
     } // is_nr_prach_slot
@@ -2701,7 +2716,8 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
                           uint8_t ssb_subcarrier_offset,
                           uint32_t ssb_index,
                           uint16_t ssb_start_subcarrier,
-                          frequency_range_t frequency_range) {
+                          frequency_range_t frequency_range,
+                          void *phy_data) {
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
   nr_scheduled_response_t scheduled_response;
@@ -2749,7 +2765,7 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
     slot_s = mac->type0_PDCCH_CSS_config.n_c;
   }
   LOG_D(MAC,"Calling fill_scheduled_response, type0_pdcch, num_pdus %d\n",dl_config->number_pdus);
-  fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, module_idP, cc_id, frame_s, slot_s, 0); // TODO fix thread_id, for now assumed 0
+  fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, module_idP, cc_id, frame_s, slot_s, 0, phy_data); // TODO fix thread_id, for now assumed 0
 
   if (dl_config->number_pdus) {
     if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 8c9d7e8bc8527f124d762b628da24e93b532f812..4b654e2ad18fe9285a924237e2d985b06feca362 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -621,6 +621,8 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
                                1, &is_typeA,
                                &startSymbolIndex, &nrOfSymbols);
 
+      AssertFatal((startSymbolIndex+nrOfSymbols)<14,"SIB1 TDA %d would cause overlap with CSI-RS. Please select a different SIB1 TDA.\n",time_domain_allocation);
+
       int mappingtype = is_typeA? typeA: typeB;
       uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex, mappingtype, 1);
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 784a71f23ff3c019759802da86ed1474f1c4e614..399033abd0bad00d99bbcc443ad1430e502ea29c 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -519,4 +519,7 @@ bool nr_find_nb_rb(uint16_t Qm,
 void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
 
 void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp);
+
+void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl);
+
 #endif /*__LAYER2_NR_MAC_PROTO_H__*/
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index f3810ebb82f90c4c2ee0e759f1b3a26dd57673cc..b8b79f8399f10a5908f5b558aeea52e300a0c7ac 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -1065,7 +1065,7 @@ void *nrue_standalone_pnf_task(void *context)
 
 //  L2 Abstraction Layer
 int handle_bcch_bch(module_id_t module_id, int cc_id,
-                    unsigned int gNB_index, uint8_t *pduP,
+                    unsigned int gNB_index, void *phy_data, uint8_t *pduP,
                     unsigned int additional_bits,
                     uint32_t ssb_index, uint32_t ssb_length,
                     uint16_t ssb_start_subcarrier, uint16_t cell_id){
@@ -1073,6 +1073,7 @@ int handle_bcch_bch(module_id_t module_id, int cc_id,
   return nr_ue_decode_mib(module_id,
 			  cc_id,
 			  gNB_index,
+			  phy_data,
 			  additional_bits,
 			  ssb_length,  //  Lssb = 64 is not support    
 			  ssb_index,
@@ -1210,7 +1211,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
         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, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->thread_id);
+          fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->thread_id, dl_info->phy_data);
           nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response);
         }
         memset(def_dci_pdu_rel15, 0, sizeof(*def_dci_pdu_rel15));
@@ -1231,7 +1232,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
         switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
           case FAPI_NR_RX_PDU_TYPE_SSB:
             mac->ssb_rsrp_dBm = (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.rsrp_dBm;
-            ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
+            ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->phy_data,
                                          (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu,
                                          (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.additional_bits,
                                          (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_index,
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
index 034c1c6b48b2ec4dac7046c9c4a03c486ac67380..45d1a071ca96323c353dcf5d0b5754c773fedae2 100755
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
@@ -123,6 +123,9 @@ typedef struct {
     /// dci reception indication structure
     fapi_nr_dci_indication_t *dci_ind;
 
+    /// PHY specific data structure that can be passed on to L2 via nr_downlink_indication_t and
+    /// back to L1 via the nr_scheduled_response_t 
+    void *phy_data;
 } nr_downlink_indication_t;
 
 
@@ -176,6 +179,9 @@ typedef struct {
     /// data transmission request structure
     fapi_nr_tx_request_t *tx_request;
 
+    /// PHY data structure initially passed on to L2 via the nr_downlink_indication_t and
+    /// returned to L1 via nr_scheduled_response_t
+    void *phy_data;
 } nr_scheduled_response_t;
 
 typedef struct {
@@ -286,6 +292,7 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq);
 
 //  TODO check
 /**\brief handle BCCH-BCH message from dl_indication
+   \param phy_data        PHY structure to be filled in by the callee in the FAPI call (L1 caller -> indication to L2 -> FAPI call to L1 callee)
    \param pduP            pointer to bch pdu
    \param additional_bits corresponding to 38.212 ch.7
    \param ssb_index       SSB index within 0 - (L_ssb-1) corresponding to 38.331 ch.13 parameter i
@@ -294,6 +301,7 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq);
 int handle_bcch_bch(module_id_t module_id,
                     int cc_id,
                     unsigned int gNB_index,
+                    void *phy_data,
                     uint8_t *pduP,
                     unsigned int additional_bits,
                     uint32_t ssb_index,
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index 9a59d1977ac2754ca03a150fe450c8d4d0312ecc..9252a23596156771840f8f939f39ee3d52c4abcb 100755
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -1452,15 +1452,15 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGr
   ASN_SEQUENCE_ADD(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig_drb);
 }
 
+
 void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
-                            rrc_gNB_carrier_data_t *carrier,
                             NR_UE_NR_Capability_t *uecap,
-                            const gNB_RrcConfigurationReq* configuration)
-{
+                            const gNB_RrcConfigurationReq* configuration) {
+
   NR_SpCellConfig_t *SpCellConfig = cellGroupConfig->spCellConfig;
   if (SpCellConfig == NULL) return;
 
-  NR_ServingCellConfigCommon_t *scc = carrier->servingcellconfigcommon;
+  NR_ServingCellConfigCommon_t *scc = configuration->scc;
 
   NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP;
   set_dl_mcs_table(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing,
@@ -1471,7 +1471,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
     for (int i=0; i<DL_BWP_list->list.count; i++){
       NR_BWP_Downlink_t *bwp = DL_BWP_list->list.array[i];
       int scs = bwp->bwp_Common->genericParameters.subcarrierSpacing;
-      set_dl_mcs_table(scs, configuration->force_256qam_off ? NULL : uecap, bwp->bwp_Dedicated, carrier->servingcellconfigcommon);
+      set_dl_mcs_table(scs, configuration->force_256qam_off ? NULL : uecap, bwp->bwp_Dedicated, scc);
     }
   }
 }
@@ -1951,9 +1951,9 @@ int16_t do_RRCReconfiguration(
 
     if(cellGroupConfig!=NULL){
       update_cellGroupConfig(cellGroupConfig,
-                             carrier,
                              ue_context_pP->ue_context.UE_Capability_nr,
                              configuration);
+
       enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
           NULL,
           (void *)cellGroupConfig,
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h
index 52efba6f45dba44099631f0f840f818d4c47fcb7..aeef5f93a7ef1eac76400206cd0bbf44c9fe595e 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h
@@ -112,7 +112,6 @@ void fill_initial_cellGroupConfig(int uid,
                                   const gNB_RrcConfigurationReq *configuration);
 
 void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
-                            rrc_gNB_carrier_data_t *carrier,
                             NR_UE_NR_Capability_t *uecap,
                             const gNB_RrcConfigurationReq *configuration);
 
diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c
index f8f05f2fe59abd98efc07f35637685d81910dd7c..bb2a180146c12bc92e65ba768e57289dada83075 100644
--- a/openair2/RRC/NR/nr_rrc_config.c
+++ b/openair2/RRC/NR/nr_rrc_config.c
@@ -31,6 +31,145 @@
 #include "nr_rrc_config.h"
 #include "common/utils/nr/nr_common.h"
 
+const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
+
+
+void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, int uid, int nb_slots_per_period) {
+
+  nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset));
+  int ideal_period = nb_slots_per_period*MAX_MOBILES_PER_GNB;
+
+  if (ideal_period<5) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots4;
+    nzpcsi0->periodicityAndOffset->choice.slots4 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<6) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots5;
+    nzpcsi0->periodicityAndOffset->choice.slots5 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<9) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots8;
+    nzpcsi0->periodicityAndOffset->choice.slots8 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<11) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots10;
+    nzpcsi0->periodicityAndOffset->choice.slots10 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<17) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots16;
+    nzpcsi0->periodicityAndOffset->choice.slots16 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<21) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots20;
+    nzpcsi0->periodicityAndOffset->choice.slots20 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<41) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots40;
+    nzpcsi0->periodicityAndOffset->choice.slots40 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<81) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots80;
+    nzpcsi0->periodicityAndOffset->choice.slots80 = nb_slots_per_period*uid;
+  }
+  else if (ideal_period<161) {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160;
+    nzpcsi0->periodicityAndOffset->choice.slots160 = nb_slots_per_period*uid;
+  }
+  else {
+    nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320;
+    nzpcsi0->periodicityAndOffset->choice.slots320 = (nb_slots_per_period*uid)%320 + (nb_slots_per_period*uid)/320;
+  }
+}
+
+
+void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
+                  NR_CSI_MeasConfig_t *csi_MeasConfig,
+                  int uid,
+                  int num_dl_antenna_ports,
+                  int curr_bwp,
+                  int do_csirs) {
+
+  if (do_csirs) {
+
+    csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList));
+    NR_NZP_CSI_RS_ResourceSet_t *nzpcsirs0 = calloc(1,sizeof(*nzpcsirs0));
+    nzpcsirs0->nzp_CSI_ResourceSetId = 0;
+    NR_NZP_CSI_RS_ResourceId_t *nzpid0 = calloc(1,sizeof(*nzpid0));
+    *nzpid0 = 0;
+    ASN_SEQUENCE_ADD(&nzpcsirs0->nzp_CSI_RS_Resources,nzpid0);
+    nzpcsirs0->repetition = NULL;
+    nzpcsirs0->aperiodicTriggeringOffset = NULL;
+    nzpcsirs0->trs_Info = NULL;
+    ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpcsirs0);
+
+    const NR_TDD_UL_DL_Pattern_t *tdd = servingcellconfigcommon->tdd_UL_DL_ConfigurationCommon ?
+                                        &servingcellconfigcommon->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
+
+    const int n_slots_frame = slotsperframe[*servingcellconfigcommon->ssbSubcarrierSpacing];
+
+    int nb_slots_per_period = n_slots_frame;
+    if (tdd)
+      nb_slots_per_period = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
+
+    csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList));
+    NR_NZP_CSI_RS_Resource_t *nzpcsi0 = calloc(1,sizeof(*nzpcsi0));
+    nzpcsi0->nzp_CSI_RS_ResourceId = 0;
+    NR_CSI_RS_ResourceMapping_t resourceMapping;
+    switch (num_dl_antenna_ports) {
+      case 1:
+        resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2;
+        resourceMapping.frequencyDomainAllocation.choice.row2.buf = calloc(2, sizeof(uint8_t));
+        resourceMapping.frequencyDomainAllocation.choice.row2.size = 2;
+        resourceMapping.frequencyDomainAllocation.choice.row2.bits_unused = 4;
+        resourceMapping.frequencyDomainAllocation.choice.row2.buf[0] = 0;
+        resourceMapping.frequencyDomainAllocation.choice.row2.buf[1] = 16;
+        resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1;
+        resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM;
+        break;
+      case 2:
+        resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other;
+        resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(2, sizeof(uint8_t));
+        resourceMapping.frequencyDomainAllocation.choice.other.size = 1;
+        resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2;
+        resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 4;
+        resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p2;
+        resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
+        break;
+      case 4:
+        resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4;
+        resourceMapping.frequencyDomainAllocation.choice.row4.buf = calloc(2, sizeof(uint8_t));
+        resourceMapping.frequencyDomainAllocation.choice.row4.size = 1;
+        resourceMapping.frequencyDomainAllocation.choice.row4.bits_unused = 5;
+        resourceMapping.frequencyDomainAllocation.choice.row4.buf[0] = 32;
+        resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p4;
+        resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
+        break;
+      default:
+        AssertFatal(1==0,"Number of ports not yet supported\n");
+    }
+    resourceMapping.firstOFDMSymbolInTimeDomain = 13;  // last symbol of slot
+    resourceMapping.firstOFDMSymbolInTimeDomain2 = NULL;
+    resourceMapping.density.present = NR_CSI_RS_ResourceMapping__density_PR_one;
+    resourceMapping.density.choice.one = (NULL_t)0;
+    resourceMapping.freqBand.startingRB = 0;
+    resourceMapping.freqBand.nrofRBs = ((curr_bwp>>2)+(curr_bwp%4>0))<<2;
+    nzpcsi0->resourceMapping = resourceMapping;
+    nzpcsi0->powerControlOffset = 0;
+    nzpcsi0->powerControlOffsetSS=calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS));
+    *nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
+    nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
+    set_csirs_periodicity(nzpcsi0, uid, nb_slots_per_period);
+    nzpcsi0->qcl_InfoPeriodicCSI_RS = NULL;
+    ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0);
+  }
+  else {
+    csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = NULL;
+    csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = NULL;
+  }
+  csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList = NULL;
+  csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList = NULL;
+}
+
 void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
                        NR_ServingCellConfigCommon_t *scc,
                        int numerology,
diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h
index 1a0d091e3594ef01f77dbc3185d01f5ec764c5d8..7a0fe892fdc850f02138959e4b9261fa8f987636 100644
--- a/openair2/RRC/NR/nr_rrc_config.h
+++ b/openair2/RRC/NR/nr_rrc_config.h
@@ -113,6 +113,12 @@ typedef struct physicalcellgroup_s{
 
 void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc);
 void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay);
+void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
+                  NR_CSI_MeasConfig_t *csi_MeasConfig,
+                  int uid,
+                  int num_dl_antenna_ports,
+                  int curr_bwp,
+                  int do_csirs);
 void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap,
                       NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
                       NR_ServingCellConfigCommon_t *scc);
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index f1462fee341012b4b07aa2fe51f81dd908481446..006040bbb9417f842d6e028acd39bee8f9c958a6 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -82,12 +82,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
                                      const gNB_RrcConfigurationReq *configuration,
                                      int uid);
 
-void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
-                  NR_CSI_MeasConfig_t *csi_MeasConfig,
-                  int dl_antenna_ports,
-                  int curr_bwp,
-                  int do_csirs);
-
 void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
                            NR_ServingCellConfig_t *servingcellconfigdedicated,
                            NR_RRCReconfiguration_IEs_t *reconfig,
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index a112afbb960ca16b8a914a647fb0a44e4566046b..36113fb7eea025f70d09e5cf5c70916450f15a5e 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -1066,24 +1066,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  csi_MeasConfig->csi_IM_ResourceToReleaseList = NULL;
  csi_MeasConfig->csi_IM_ResourceSetToReleaseList = NULL;
 
- if (do_csirs) {
-   csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList));
-   NR_NZP_CSI_RS_ResourceSet_t *nzpcsirs0 = calloc(1,sizeof(*nzpcsirs0));
-   nzpcsirs0->nzp_CSI_ResourceSetId = 0;
-   NR_NZP_CSI_RS_ResourceId_t *nzpid0 = calloc(1,sizeof(*nzpid0));
-   *nzpid0 = 0;
-   ASN_SEQUENCE_ADD(&nzpcsirs0->nzp_CSI_RS_Resources,nzpid0);
-   nzpcsirs0->repetition = NULL;
-   nzpcsirs0->aperiodicTriggeringOffset = NULL;
-   nzpcsirs0->trs_Info = NULL;
-   ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpcsirs0);
- }
- else
-   csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList  = NULL;
-
- csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList = NULL;
-
- config_csirs(servingcellconfigcommon, csi_MeasConfig,dl_antenna_ports,curr_bwp,do_csirs);
+ config_csirs(servingcellconfigcommon, csi_MeasConfig, uid, dl_antenna_ports, curr_bwp, do_csirs);
 
  csi_MeasConfig->csi_SSB_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_SSB_ResourceSetToAddModList));
  csi_MeasConfig->csi_SSB_ResourceSetToReleaseList = NULL;
@@ -1102,9 +1085,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list,ssbresset0);
 
  csi_MeasConfig->csi_ResourceConfigToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_ResourceConfigToAddModList));
+ csi_MeasConfig->csi_ResourceConfigToReleaseList = NULL;
 
  if (do_csirs) {
-   csi_MeasConfig->csi_ResourceConfigToReleaseList = NULL;
    NR_CSI_ResourceConfig_t *csires0 = calloc(1,sizeof(*csires0));
    csires0->csi_ResourceConfigId=0;
    csires0->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB;
@@ -1315,62 +1298,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
 }
 
 
-void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
-                  NR_CSI_MeasConfig_t *csi_MeasConfig,
-                  int dl_antenna_ports,
-                  int curr_bwp,
-                  int do_csirs) {
-
- if (do_csirs) {
-   csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList));
-   NR_NZP_CSI_RS_Resource_t *nzpcsi0 = calloc(1,sizeof(*nzpcsi0));
-   nzpcsi0->nzp_CSI_RS_ResourceId = 0;
-   NR_CSI_RS_ResourceMapping_t resourceMapping;
-   switch (dl_antenna_ports) {
-     case 1:
-       resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2;
-       resourceMapping.frequencyDomainAllocation.choice.row2.buf = calloc(2, sizeof(uint8_t));
-       resourceMapping.frequencyDomainAllocation.choice.row2.size = 2;
-       resourceMapping.frequencyDomainAllocation.choice.row2.bits_unused = 4;
-       resourceMapping.frequencyDomainAllocation.choice.row2.buf[0] = 0;
-       resourceMapping.frequencyDomainAllocation.choice.row2.buf[1] = 16;
-       resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1;
-       resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM;
-       break;
-     case 2:
-       resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other;
-       resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(2, sizeof(uint8_t));
-       resourceMapping.frequencyDomainAllocation.choice.other.size = 1;
-       resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2;
-       resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 4;
-       resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p2;
-       resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
-       break;
-     default:
-       AssertFatal(1==0,"Number of ports not yet supported\n");
-   }
-   resourceMapping.firstOFDMSymbolInTimeDomain = 6;
-   resourceMapping.firstOFDMSymbolInTimeDomain2 = NULL;
-   resourceMapping.density.present = NR_CSI_RS_ResourceMapping__density_PR_one;
-   resourceMapping.density.choice.one = (NULL_t)0;
-   resourceMapping.freqBand.startingRB = 0;
-   resourceMapping.freqBand.nrofRBs = ((curr_bwp>>2)+(curr_bwp%4>0))<<2;
-   nzpcsi0->resourceMapping = resourceMapping;
-   nzpcsi0->powerControlOffset = 0;
-   nzpcsi0->powerControlOffsetSS=calloc(1,sizeof(*nzpcsi0->powerControlOffsetSS));
-   *nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
-   nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
-   nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset));
-   nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320;
-   nzpcsi0->periodicityAndOffset->choice.slots320 = 0;
-   nzpcsi0->qcl_InfoPeriodicCSI_RS = NULL;
-   ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0);
- }
- else
-   csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = NULL;
-}
-
-
 void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
                            NR_ServingCellConfig_t *servingcellconfigdedicated,
                            NR_RRCReconfiguration_IEs_t *reconfig,