diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container
index f5852bace54c2773d4fbe3eda0bb7be2f9cff3f0..57738a318334aad50a3d5f8a6fdee7f4a2664b96 100644
--- a/ci-scripts/Jenkinsfile-GitLab-Container
+++ b/ci-scripts/Jenkinsfile-GitLab-Container
@@ -222,7 +222,7 @@ pipeline {
           when { expression {doMandatoryTests} }
           steps {
             script {
-              triggerSlaveJob ('RAN-RF-Sim-Test-5G', 'Test-RF-Sim-Container-4G')
+              triggerSlaveJob ('RAN-RF-Sim-Test-5G', 'Test-RF-Sim-Container-5G')
             }
           }
           post {
diff --git a/ci-scripts/Jenkinsfile-push-registry b/ci-scripts/Jenkinsfile-push-registry
index 91d6136e0a55824cff05cc10f36419e815a6dfb0..f5847ff0aab2e45adee158f8f5d8fceda735f209 100644
--- a/ci-scripts/Jenkinsfile-push-registry
+++ b/ci-scripts/Jenkinsfile-push-registry
@@ -55,7 +55,9 @@ pipeline {
     stage ("Push to DockerHub") {
       steps {
         script {
-          WEEK_TAG = sh returnStdout: true, script: 'date +"%Y.w%U"'
+          WEEK_REF = sh returnStdout: true, script: 'date +"%Y.w%V"'
+          WEEK_REF = WEEK_REF.trim()
+          WEEK_TAG = sh returnStdout: true, script: 'python3 ./ci-scripts/provideUniqueImageTag.py --start_tag ' + WEEK_REF
           WEEK_TAG = WEEK_TAG.trim()
 
           withCredentials([
diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py
index fdc2bc1597078728190e669bf71e39e14b824f04..d85659568bc76b4973b89ed9b5cbbecf4a8944c1 100644
--- a/ci-scripts/cls_containerize.py
+++ b/ci-scripts/cls_containerize.py
@@ -606,6 +606,8 @@ class Containerize():
 		if containerToKill:
 			mySSH.command('docker kill --signal INT ' + containerName, '\$', 30)
 			time.sleep(5)
+			mySSH.command('docker kill --signal KILL ' + containerName, '\$', 30)
+			time.sleep(5)
 			mySSH.command('docker logs ' + containerName + ' > ' + lSourcePath + '/cmake_targets/' + self.eNB_logFile[self.eNB_instance], '\$', 30)
 			mySSH.command('docker rm -f ' + containerName, '\$', 30)
 		# Forcing the down now to remove the networks and any artifacts
diff --git a/ci-scripts/cls_module_ue.py b/ci-scripts/cls_module_ue.py
index cabd0a045de63385c7a0cc159b2e536fe06f0855..fb107007980d53059da297e06bcb396a80922480 100644
--- a/ci-scripts/cls_module_ue.py
+++ b/ci-scripts/cls_module_ue.py
@@ -76,7 +76,8 @@ class Module_UE:
 			logging.debug('Starting ' + self.Process['Name'])
 			mySSH = sshconnection.SSHConnection()
 			mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
-			mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S ' + self.Process['Cmd'] + ' ' +  self.Process['Apn'][CNType]  + ' > /dev/null 2>&1 &','\$',5)
+			mySSH.command('echo ' + self.HostPassword + ' | sudo -S rm -f /tmp/quectel-cm.log','\$',5)
+			mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S stdbuf -o0 ' + self.Process['Cmd'] + ' ' +  self.Process['Apn'][CNType]  + ' > /tmp/quectel-cm.log 2>&1 &','\$',5)
 			mySSH.close()
 			#checking the process
 			time.sleep(5)
diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py
index 5d89a7b2e0bdac3c4bb442d1695d93c0cefdd173..ec1202cb216457eca9c7a4f15de772932f776fff 100644
--- a/ci-scripts/cls_oaicitest.py
+++ b/ci-scripts/cls_oaicitest.py
@@ -122,6 +122,7 @@ def GetPingTimeAnalysis(RAN,ping_log_file,ping_rttavg_threshold):
 		try:
 			mySSH = sshconnection.SSHConnection()
 			mySSH.copyout(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, ping_log_file+'.png', RAN.eNBSourceCodePath + '/cmake_targets/')
+			mySSH.copyout(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, ping_log_file, RAN.eNBSourceCodePath + '/cmake_targets/')
 		except:
 			logging.debug('\u001B[1;37;41m Ping PNG SCP to eNB FAILED\u001B[0m')
 
@@ -1598,7 +1599,7 @@ class OaiCiTest():
 			else:
 				if launchfromModule == False:
 					#ping log file is on the python executor
-					cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' 
+					cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' > ping_' + self.testCase_id + '_' + device_id + '.log 2>&1'
 					message = cmd + '\n'
 					logging.debug(cmd)
 					ret = subprocess.run(cmd, shell=True)
@@ -1623,7 +1624,7 @@ class OaiCiTest():
 					else:
 						Target = EPC.IPAddress
 					#ping from module NIC rather than IP address to make sure round trip is over the air	
-					cmd = 'ping -I ' + Module_UE.UENetwork  + ' ' + self.ping_args + ' ' +  Target  + ' 2>&1 > ping_' + self.testCase_id + '_' + self.ue_id + '.log' 
+					cmd = 'ping -I ' + Module_UE.UENetwork  + ' ' + self.ping_args + ' ' +  Target  + ' > ping_' + self.testCase_id + '_' + self.ue_id + '.log 2>&1'
 					SSH.command(cmd,'\$',int(ping_time[0])*1.5)
 					#copy the ping log file to have it locally for analysis (ping stats)
 					SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'ping_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
@@ -2084,7 +2085,8 @@ class OaiCiTest():
 			statusQueue.put(UE_IPAddress)
 			statusQueue.put(report_msg)
 			logging.debug('\u001B[1;37;45m TCP Bidir Iperf Result (' + UE_IPAddress + ') \u001B[0m')
-			logging.debug('\u001B[1;35m    ' + report_msg + '\u001B[0m')
+			for rLine in report_msg.split('\n'):
+				logging.debug('\u001B[1;35m    ' + rLine + '\u001B[0m')
 			lock.release()
 		else:
 			self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Bidir TCP : Could not analyze from Log file')
@@ -2379,10 +2381,12 @@ class OaiCiTest():
 			SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
 
 
-	def Iperf_Module(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC, Module_UE):
+	def Iperf_Module(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC, Module_UE, RAN):
+		SSH = sshconnection.SSHConnection()
+		server_filename = 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
+		client_filename = 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 		if (re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE)) or (re.match('OAICN5G', EPC.Type, re.IGNORECASE)):
 			#retrieve trf-gen container IP address
-			SSH = sshconnection.SSHConnection()
 			SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 			SSH.command('docker inspect --format="TRF_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" prod-trf-gen', '\$', 5)
 			result = re.search('TRF_IP_ADDR = (?P<trf_ip_addr>[0-9\.]+)', SSH.getBefore())
@@ -2404,20 +2408,18 @@ class OaiCiTest():
 			if self.iperf_direction=="DL":
 				logging.debug("Iperf for Module in DL mode detected")
 				##server side UE
-				server_filename='iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 				cmd = 'rm ' + server_filename
 				SSH.command(cmd,'\$',5)
-				cmd = 'echo $USER; nohup iperf -s -B ' + UE_IPAddress + ' -u 2>&1 > ' + server_filename + ' &'
+				cmd = 'echo $USER; nohup iperf -s -B ' + UE_IPAddress + ' -u -i 1 > ' + server_filename + ' 2>&1 &'
 				SSH.command(cmd,'\$',5)
 				SSH.close()
 				##client side EPC
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
-				client_filename = 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 				#remove old client file in EPC.SourceCodePath
 				cmd = 'rm ' + EPC.SourceCodePath + '/' + client_filename 
 				SSH.command(cmd,'\$',5)
-				iperf_cmd = 'bin/iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' 2>&1 > ' + client_filename
+				iperf_cmd = 'bin/iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' > ' + client_filename + ' 2>&1'
 				cmd = 'docker exec -w /iperf-2.0.13 -it prod-trf-gen /bin/bash -c \"' + iperf_cmd + '\"' 
 				SSH.command(cmd,'\$',int(iperf_time)*5.0)
 				SSH.command('docker cp prod-trf-gen:/iperf-2.0.13/'+ client_filename + ' ' + EPC.SourceCodePath, '\$', 5)
@@ -2433,19 +2435,17 @@ class OaiCiTest():
 				logging.debug("Iperf for Module in UL mode detected")
 				#server side EPC
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
-				server_filename = 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
 
-				iperf_cmd = 'echo $USER; nohup bin/iperf -s -u 2>&1 > ' + server_filename
+				iperf_cmd = 'echo $USER; nohup bin/iperf -s -u -i 1 > ' + server_filename + ' 2>&1'
 				cmd = 'docker exec -d -w /iperf-2.0.13 prod-trf-gen /bin/bash -c \"' + iperf_cmd + '\"' 
 				SSH.command(cmd,'\$',5)
 				SSH.close()
 
 				#client side UE
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
-				client_filename = 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 				cmd = 'rm '+ client_filename
 				SSH.command(cmd,'\$',5)
-				SSH.command('iperf -B ' + UE_IPAddress + ' -c ' +  trf_gen_IP + ' '  + self.iperf_args + ' 2>&1 > ' + client_filename, '\$', int(iperf_time)*5.0)
+				SSH.command('iperf -B ' + UE_IPAddress + ' -c ' +  trf_gen_IP + ' '  + self.iperf_args + ' > ' + client_filename + ' 2>&1', '\$', int(iperf_time)*5.0)
 				SSH.close()
 
 				#once client is done, retrieve the server file from container to EPC Host
@@ -2461,12 +2461,10 @@ class OaiCiTest():
 
 			elif self.iperf_direction=="BIDIR":
 				logging.debug("Iperf for Module in BIDIR mode detected")
-				server_filename = 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
-				client_filename = 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 
 				#server side EPC
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
-				iperf_cmd = 'echo $USER; nohup /usr/local/bin/iperf3 -s 2>&1 > ' + server_filename
+				iperf_cmd = 'echo $USER; nohup /usr/local/bin/iperf3 -s -i 1 > ' + server_filename + ' 2>&1'
 				cmd = 'docker exec -d -w /iperf-2.0.13 prod-trf-gen /bin/bash -c \"' + iperf_cmd + '\"' 
 				SSH.command(cmd,'\$',5)
 				SSH.close()
@@ -2475,7 +2473,7 @@ class OaiCiTest():
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 				cmd = 'rm '+ client_filename
 				SSH.command(cmd,'\$',5)
-				SSH.command('iperf3 -B ' + UE_IPAddress + ' -c ' +  trf_gen_IP + ' '  + self.iperf_args + ' 2>&1 > ' + client_filename, '\$', int(iperf_time)*5.0)
+				SSH.command('iperf3 -B ' + UE_IPAddress + ' -c ' +  trf_gen_IP + ' '  + self.iperf_args + ' > ' + client_filename + ' 2>&1', '\$', int(iperf_time)*5.0)
 				SSH.close()
 
 				#once client is done, retrieve the server file from container to EPC Host
@@ -2499,8 +2497,6 @@ class OaiCiTest():
 
 		else: 		#default is ltebox
 
-			SSH = sshconnection.SSHConnection()
-
 			#kill iperf processes before (in case there are still some remaining)
 			SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 			cmd = 'killall --signal=SIGKILL iperf'
@@ -2524,14 +2520,14 @@ class OaiCiTest():
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 				cmd = 'rm iperf_server_' +  self.testCase_id + '_' + self.ue_id + '.log'
 				SSH.command(cmd,'\$',5)
-				cmd = 'echo $USER; nohup /opt/iperf-2.0.10/iperf -s -B ' + UE_IPAddress + ' -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log &' 
+				cmd = 'echo $USER; nohup /opt/iperf-2.0.10/iperf -s -B ' + UE_IPAddress + ' -u -i 1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log 2>&1 &' 
 				SSH.command(cmd,'\$',5)
 				SSH.close()
 				#client side EPC
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 				cmd = 'rm iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 				SSH.command(cmd,'\$',5)
-				cmd = 'iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log' 
+				cmd = 'iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log 2>&1' 
 				SSH.command(cmd,'\$',int(iperf_time)*5.0)
 				SSH.close()
 				#copy the 2 resulting files locally
@@ -2547,7 +2543,7 @@ class OaiCiTest():
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 				cmd = 'rm iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
 				SSH.command(cmd,'\$',5)
-				cmd = 'echo $USER; nohup iperf -s -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log  &'
+				cmd = 'echo $USER; nohup iperf -s -u -i 1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log 2>&1 &'
 				SSH.command(cmd,'\$',5)
 				SSH.close()
 
@@ -2555,7 +2551,7 @@ class OaiCiTest():
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 				cmd = 'rm iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 				SSH.command(cmd,'\$',5)
-				SSH.command('/opt/iperf-2.0.10/iperf -c 192.172.0.1 ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '\$', int(iperf_time)*5.0)
+				SSH.command('/opt/iperf-2.0.10/iperf -c 192.172.0.1 ' + self.iperf_args + ' > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log 2>&1', '\$', int(iperf_time)*5.0)
 				SSH.close()
 
 				#copy the 2 resulting files locally
@@ -2566,15 +2562,13 @@ class OaiCiTest():
 				self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)
 			elif self.iperf_direction=="BIDIR":
 				logging.debug("Iperf for Module in BIDIR mode detected")
-				server_filename = 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
-				client_filename = 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
 
 
 				#server side EPC
 				SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
 				cmd = 'rm ' + server_filename
 				SSH.command(cmd,'\$',5)
-				cmd = 'echo $USER; nohup iperf3 -s 2>&1 > '+server_filename+' &'
+				cmd = 'echo $USER; nohup iperf3 -s -i 1 > '+server_filename+' 2>&1 &'
 				SSH.command(cmd,'\$',5)
 				SSH.close()
 
@@ -2582,7 +2576,7 @@ class OaiCiTest():
 				SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 				cmd = 'rm ' + client_filename
 				SSH.command(cmd,'\$',5)
-				SSH.command('iperf3 -c 192.172.0.1 ' + self.iperf_args + ' 2>&1 > '+client_filename, '\$', int(iperf_time)*5.0)
+				SSH.command('iperf3 -c 192.172.0.1 ' + self.iperf_args + ' > '+client_filename + ' 2>&1', '\$', int(iperf_time)*5.0)
 				SSH.close()
 
 				#copy the 2 resulting files locally
@@ -2593,6 +2587,7 @@ class OaiCiTest():
 			else :
 				logging.debug("Incorrect or missing IPERF direction in XML")
 
+
 			#kill iperf processes after to be clean
 			SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
 			cmd = 'killall --signal=SIGKILL iperf'
@@ -2606,7 +2601,12 @@ class OaiCiTest():
 			cmd = 'killall --signal=SIGKILL iperf3'
 			SSH.command(cmd,'\$',5)
 			SSH.close()
-			return
+
+		# Copying to xNB server for Jenkins artifacting
+		if (os.path.isfile(server_filename)):
+			SSH.copyout(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, server_filename, RAN.eNBSourceCodePath + '/cmake_targets/')
+		if (os.path.isfile(client_filename)):
+			SSH.copyout(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, client_filename, RAN.eNBSourceCodePath + '/cmake_targets/')
 
 	def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC):
 		try:
@@ -2804,12 +2804,12 @@ class OaiCiTest():
 				else:
 					SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.SourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
 				# fromdos has to be called on the python executor not on ADB server
-				cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 > /dev/null'
+				cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log > /dev/null 2>&1'
 				try:
 					subprocess.run(cmd, shell=True)
 				except:
 					pass
-				cmd = 'dos2unix -o iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 > /dev/null'
+				cmd = 'dos2unix -o iperf_server_' + self.testCase_id + '_' + device_id + '.log > /dev/null 2>&1'
 				try:
 					subprocess.run(cmd, shell=True)
 				except:
@@ -2995,7 +2995,7 @@ class OaiCiTest():
         	#special quick and dirty treatment for modules, iperf to be restructured
 			if self.ue_id!="": #is module
 				device_id = Module_UE.ID + "-" + Module_UE.Kind
-				p = Process(target = self.Iperf_Module ,args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, Module_UE,))
+				p = Process(target = self.Iperf_Module ,args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, Module_UE, RAN, ))
 			else: #legacy code
 				p = Process(target = self.Iperf_common, args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, ))
 			p.daemon = True
diff --git a/ci-scripts/cls_static_code_analysis.py b/ci-scripts/cls_static_code_analysis.py
index c899a9aabd678d8a0e107197a2e6f49e070ceb34..d6796ad414e1577e0c9d233e322e46f570f8838f 100644
--- a/ci-scripts/cls_static_code_analysis.py
+++ b/ci-scripts/cls_static_code_analysis.py
@@ -35,6 +35,7 @@ import sys              # arg
 import re               # reg
 import logging
 import os
+from pathlib import Path
 import time
 
 #-----------------------------------------------------------
@@ -51,7 +52,7 @@ class CppCheckResults():
 
 	def __init__(self):
 
-		self.variants = ['xenial', 'bionic']
+		self.variants = ['bionic', 'focal']
 		self.versions = ['','']
 		self.nbErrors = [0,0]
 		self.nbWarnings = [0,0]
@@ -116,12 +117,22 @@ class StaticCodeAnalysis():
 		# if the commit ID is provided use it to point to it
 		if self.ranCommitID != '':
 			mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
-
-		mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:xenial || true', '\$', 60)
-		mySSH.command('docker build --tag oai-cppcheck:xenial --file ci-scripts/docker/Dockerfile.cppcheck.xenial . > cmake_targets/log/cppcheck-xenial.txt 2>&1', '\$', 600)
+		# if the branch is not develop, then it is a merge request and we need to do
+		# the potential merge. Note that merge conflicts should already been checked earlier
+		if (self.ranAllowMerge):
+			if self.ranTargetBranch == '':
+				if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
+					mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
+			else:
+				logging.debug('Merging with the target branch: ' + self.ranTargetBranch)
+				mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
+
+		mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:focal || true', '\$', 60)
 		mySSH.command('sed -e "s@xenial@bionic@" ci-scripts/docker/Dockerfile.cppcheck.xenial > ci-scripts/docker/Dockerfile.cppcheck.bionic', '\$', 6)
 		mySSH.command('docker build --tag oai-cppcheck:bionic --file ci-scripts/docker/Dockerfile.cppcheck.bionic . > cmake_targets/log/cppcheck-bionic.txt 2>&1', '\$', 600)
-		mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:xenial || true', '\$', 30)
+		mySSH.command('sed -e "s@xenial@focal@" ci-scripts/docker/Dockerfile.cppcheck.xenial > ci-scripts/docker/Dockerfile.cppcheck.focal', '\$', 6)
+		mySSH.command('docker build --tag oai-cppcheck:focal --file ci-scripts/docker/Dockerfile.cppcheck.focal . > cmake_targets/log/cppcheck-focal.txt 2>&1', '\$', 600)
+		mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:focal || true', '\$', 30)
 
 		# Analyzing the logs
 		mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
@@ -131,8 +142,22 @@ class StaticCodeAnalysis():
 
 		mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '/*', '.')
 		CCR = CppCheckResults()
+		CCR_ref = CppCheckResults()
 		vId = 0
 		for variant in CCR.variants:
+			refAvailable = False
+			if self.ranAllowMerge:
+				refFolder = str(Path.home()) + '/cppcheck-references'
+				if (os.path.isfile(refFolder + '/cppcheck-'+ variant + '.txt')):
+					refAvailable = True
+					with open(refFolder + '/cppcheck-'+ variant + '.txt', 'r') as refFile:
+						for line in refFile:
+							ret = re.search(' (?P<nb_errors>[0-9\.]+) errors', str(line))
+							if ret is not None:
+								CCR_ref.nbErrors[vId] = int(ret.group('nb_errors'))
+							ret = re.search(' (?P<nb_warnings>[0-9\.]+) warnings', str(line))
+							if ret is not None:
+								CCR_ref.nbWarnings[vId] = int(ret.group('nb_warnings'))
 			if (os.path.isfile('./cppcheck-'+ variant + '.txt')):
 				xmlStart = False
 				with open('./cppcheck-'+ variant + '.txt', 'r') as logfile:
@@ -167,21 +192,43 @@ class StaticCodeAnalysis():
 								CCR.nbPtrAddNotNull[vId] += 1
 							if re.search('id="oppositeInnerCondition"', str(line)) is not None:
 								CCR.nbOppoInnerCondition[vId] += 1
-			logging.debug('========  Variant ' + variant + ' - ' + CCR.versions[vId] + ' ========')
-			logging.debug('   ' + str(CCR.nbErrors[vId]) + ' errors')
-			logging.debug('   ' + str(CCR.nbWarnings[vId]) + ' warnings')
-			logging.debug('  -- Details --')
-			logging.debug('   Memory leak:                     ' + str(CCR.nbMemLeaks[vId]))
-			logging.debug('   Possible null pointer deference: ' + str(CCR.nbNullPtrs[vId]))
-			logging.debug('   Uninitialized variable:          ' + str(CCR.nbUninitVars[vId]))
-			logging.debug('   Undefined behaviour shifting:    ' + str(CCR.nbTooManyBitsShift[vId]))
-			logging.debug('   Signed integer overflow:         ' + str(CCR.nbIntegerOverflow[vId]))
-			logging.debug('')
-			logging.debug('   Printf formatting issue:         ' + str(CCR.nbInvalidPrintf[vId]))
-			logging.debug('   Modulo result is predetermined:  ' + str(CCR.nbModuloAlways[vId]))
-			logging.debug('   Opposite Condition -> dead code: ' + str(CCR.nbOppoInnerCondition[vId]))
-			logging.debug('   Wrong Scanf Nb Args:             ' + str(CCR.nbWrongScanfArg[vId]))
-			logging.debug('')
+			vMsg  = ''
+			vMsg += '========  Variant ' + variant + ' - ' + CCR.versions[vId] + ' ========\n'
+			vMsg += '   ' + str(CCR.nbErrors[vId]) + ' errors\n'
+			vMsg += '   ' + str(CCR.nbWarnings[vId]) + ' warnings\n'
+			vMsg += '  -- Details --\n'
+			vMsg += '   Memory leak:                     ' + str(CCR.nbMemLeaks[vId]) + '\n'
+			vMsg += '   Possible null pointer deference: ' + str(CCR.nbNullPtrs[vId]) + '\n'
+			vMsg += '   Uninitialized variable:          ' + str(CCR.nbUninitVars[vId]) + '\n'
+			vMsg += '   Undefined behaviour shifting:    ' + str(CCR.nbTooManyBitsShift[vId]) + '\n'
+			vMsg += '   Signed integer overflow:         ' + str(CCR.nbIntegerOverflow[vId]) + '\n'
+			vMsg += '\n'
+			vMsg += '   Printf formatting issue:         ' + str(CCR.nbInvalidPrintf[vId]) + '\n'
+			vMsg += '   Modulo result is predetermined:  ' + str(CCR.nbModuloAlways[vId]) + '\n'
+			vMsg += '   Opposite Condition -> dead code: ' + str(CCR.nbOppoInnerCondition[vId]) + '\n'
+			vMsg += '   Wrong Scanf Nb Args:             ' + str(CCR.nbWrongScanfArg[vId]) + '\n'
+			for vLine in vMsg.split('\n'):
+				logging.debug(vLine)
+			if self.ranAllowMerge and refAvailable:
+				if CCR_ref.nbErrors[vId] == CCR.nbErrors[vId]:
+					logging.debug('   No change in number of errors')
+				elif CCR_ref.nbErrors[vId] > CCR.nbErrors[vId]:
+					logging.debug('   Good! Decrease in number of errors')
+				else:
+					logging.debug('   Bad! increase in number of errors')
+				if CCR_ref.nbWarnings[vId] == CCR.nbWarnings[vId]:
+					logging.debug('   No change in number of warnings')
+				elif CCR_ref.nbWarnings[vId] > CCR.nbWarnings[vId]:
+					logging.debug('   Good! Decrease in number of warnings')
+				else:
+					logging.debug('   Bad! increase in number of warnings')
+			# Create new reference file
+			if not self.ranAllowMerge:
+				refFolder = str(Path.home()) + '/cppcheck-references'
+				if not os.path.isdir(refFolder):
+					os.mkdir(refFolder)
+				with open(refFolder + '/cppcheck-'+ variant + '.txt', 'w') as refFile:
+					refFile.write(vMsg)
 			vId += 1
 
 		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
diff --git a/ci-scripts/conf_files/benetel-5g.conf b/ci-scripts/conf_files/benetel-5g.conf
index bfe61188b64514fcbff501725624a9330e7a05a9..8f3b03fddc52948faeabdb00de9826daaeb21c96 100644
--- a/ci-scripts/conf_files/benetel-5g.conf
+++ b/ci-scripts/conf_files/benetel-5g.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/ci-scripts/conf_files/gNB_SA_DU.conf b/ci-scripts/conf_files/gNB_SA_DU.conf
index c30805a2d9b6021db0df7b3c38186a0fd70b0e3d..256d724f3ff9898e942244b2cdc8443de355e515 100644
--- a/ci-scripts/conf_files/gNB_SA_DU.conf
+++ b/ci-scripts/conf_files/gNB_SA_DU.conf
@@ -37,8 +37,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
     sib1_tda                                                  = 0;
 
diff --git a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf
index 8b14b7455681031550803aaeb63ed19c81f52ada..33ab30887f6a11df307cbaac8e61e8d288515309 100644
--- a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf
+++ b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf
@@ -38,7 +38,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
 
     pdcch_ConfigSIB1 = (
diff --git a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf
index 02035ea827c2965a4c96314b28f7316ddf31e494..4a5eaec89b5f2faa7518e5c3a8fd60473f40ecc6 100644
--- a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf
+++ b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf
@@ -39,7 +39,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
 
     pdcch_ConfigSIB1 = (
diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
index e8c6cab1b496ac0e6295cd2b5ef53c216328e9a8..9353bd12d26ed802af0bad7f42f8bc7e79ba7621 100644
--- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
 	
     servingCellConfigCommon = (
diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
index 7d3409d4d490cfe99fbe1969315ec257547bdc4a..1019ec75ade5bb36558e7bb49bcfae9e0ffb6002 100644
--- a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
 
     servingCellConfigCommon = (
diff --git a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf
index 84b66060d978b97862af6291e6cf1bef10065399..55b1bdb24d9a6d41c4104241c6940f7357f0b70b 100644
--- a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf
@@ -20,7 +20,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
     pusch_TargetSNRx10                                        = 200;
     pucch_TargetSNRx10                                        = 200;
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf
index 9f5c2875b39c80e73c59efdbb22815ca3e64d524..1d7c4b57f08ec1a7b396097959cf1a9dac2aacf2 100644
--- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf
@@ -38,7 +38,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
     ul_prbblacklist                                           = "51,52,53,54"
     do_SRS                                                    = 1;
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf
index 594bd5e4c82dc0a1db81e39e61cc9ad392060e66..e2b331939b99082d2b90d2f7cb1b98688cf3061d 100644
--- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf
@@ -38,8 +38,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     #pusch_TargetSNRx10                                        = 200;
     #pucch_TargetSNRx10                                        = 200;
     ul_prbblacklist                                           = "51,52,53,54"
diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf
index 2361437f7c7c1b4004850bd1e0252d5f8dea823d..324b3d2ce1c36556816d128fd7cfef0fbe92e39a 100644
--- a/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf
@@ -38,8 +38,10 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
+    #pusch_TargetSNRx10                                        = 200;
+    #pucch_TargetSNRx10                                        = 200;
     ul_prbblacklist                                           = "79,80,81,82"
 
     pdcch_ConfigSIB1 = (
@@ -83,7 +85,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
         # this is RBstart=0,L=106 (275*(L-1))+RBstart
-        initialDLBWPlocationAndBandwidth                                        = 31899;
+        initialDLBWPlocationAndBandwidth                                        = 31624;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialDLBWPsubcarrierSpacing                                           = 1;
@@ -103,7 +105,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 31899;
+        initialULBWPlocationAndBandwidth                                        = 31624;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialULBWPsubcarrierSpacing                                           = 1;
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
index 6d05fee69272110925ba5760fc550c8c0fe1f41f..70535cadd892a3707509301f62637f0df99d2c74 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset = 0;
-    pdsch_AntennaPorts = 1;
-    pusch_AntennaPorts = 1;
     min_rxtxtime = 6;
 
     servingCellConfigCommon = (
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
index 55cb7b36c4dc495678847f78fb41b52f6be64746..af581453229280fbb425992a4e5023c408f1f5b3 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
@@ -20,8 +20,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
  
     servingCellConfigCommon = (
     {
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
index 7c4bb9cc59d5f6dc5374188ab78672f3c1033353..8f480d375717f5af5ea711ab5102bd93e9fbe080 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf
@@ -21,8 +21,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime = 6;
  
     servingCellConfigCommon = (
diff --git a/ci-scripts/provideUniqueImageTag.py b/ci-scripts/provideUniqueImageTag.py
new file mode 100644
index 0000000000000000000000000000000000000000..ee8306402fb7bdac08977a9f392c1c6f04de1f85
--- /dev/null
+++ b/ci-scripts/provideUniqueImageTag.py
@@ -0,0 +1,54 @@
+import argparse
+import os
+import re
+import subprocess
+import sys
+
+AUTH_SERVICE = 'registry.docker.io'
+AUTH_SCOPE   = 'repository:rdefosseoai/oai-enb:pull'
+
+def main() -> None:
+    args = _parse_args()
+
+    cmd = 'curl -fsSL "https://auth.docker.io/token?service=' + AUTH_SERVICE + '&scope=' + AUTH_SCOPE + '" | jq --raw-output ".token"'
+    token = subprocess.check_output(cmd, shell=True, universal_newlines=True)
+    token = str(token).strip()
+    cmd = 'curl -fsSL -H "Authorization: Bearer ' + token + '" "https://index.docker.io/v2/rdefosseoai/oai-enb/tags/list" | jq .'
+    listOfTags = subprocess.check_output(cmd, shell=True, universal_newlines=True)
+
+    foundTag = False
+    for tag in listOfTags.split('\n'):
+        if re.search('"' + args.start_tag + '"', tag) is not None:
+            foundTag = True
+
+    if not foundTag:
+        print (args.start_tag)
+        sys.exit(0)
+
+    proposedVariants = ['a', 'b', 'c', 'd']
+    for variant in proposedVariants:
+        foundTag = False
+        currentVariant = variant
+        for tag in listOfTags.split('\n'):
+            if re.search('"' + args.start_tag + variant + '"', tag) is not None:
+                foundTag = True
+                break
+        if not foundTag:
+            break
+
+    if not foundTag:
+        print (args.start_tag + currentVariant)
+
+def _parse_args() -> argparse.Namespace:
+    parser = argparse.ArgumentParser(description='Provides an unique new image tag for DockerHub')
+
+    parser.add_argument(
+        '--start_tag', '-st',
+        action='store',
+        required=True,
+        help='Proposed Starting Tag',
+    )
+    return parser.parse_args()
+
+if __name__ == '__main__':
+    main()
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 3b32a75542db080ea50a91ffdc13e530709010a1..f95ce90c66937d1e74c139b0e3d87af1e1cd71de 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -756,11 +756,11 @@ class RANManagement():
 		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/enb_*.pcap .','\$',20)
 		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/gnb_*.pcap .','\$',20)
 		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5)
-		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log.png log/*/*.log log/*/*.pcap', '\$', 60)
+		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log* iperf*.log log/*/*.log log/*/*.pcap', '\$', 60)
 		result = re.search('core.\d+', mySSH.getBefore())
 		if result is not None:
 			mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip core* ran_build/build/{lte,nr}-softmodem', '\$', 60) # add core and executable to zip
-		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log.png log/*/*.log log/*/*.pcap', '\$', 15)
+		mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log* iperf*.log log/*/*.log log/*/*.pcap', '\$', 15)
 		mySSH.close()
 
 	def AnalyzeLogFile_eNB(self, eNBlogFile, HTML, checkers={}):
diff --git a/ci-scripts/xml_files/container_nsa_b200_quectel.xml b/ci-scripts/xml_files/container_nsa_b200_quectel.xml
index 55f8b8638df8c67791e0641fe7f5ad5a90b13d58..610f0b019a447ff5e78e632cd9b016143c054f6b 100644
--- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml
+++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml
@@ -39,8 +39,9 @@
  050001
  070001
  070000
- 050000
- 050001
+ 070002
+ 050002
+ 050003
  010002
  000001
  030202
@@ -117,10 +118,28 @@
 		<ping_rttavg_threshold>15</ping_rttavg_threshold>
 	</testCase>
 
+	<testCase id="050002">
+		<class>Ping</class>
+		<desc>Ping: 20pings in 20sec</desc>
+		<id>idefix</id>
+		<ping_args>-c 20</ping_args>
+		<ping_packetloss_threshold>1</ping_packetloss_threshold>
+		<ping_rttavg_threshold>15</ping_rttavg_threshold>
+	</testCase>
+
+	<testCase id="050003">
+		<class>Ping</class>
+		<desc>Ping: 100pings in 20sec</desc>
+		<id>idefix</id>
+		<ping_args>-c 100 -i 0.2</ping_args>
+		<ping_packetloss_threshold>1</ping_packetloss_threshold>
+		<ping_rttavg_threshold>15</ping_rttavg_threshold>
+	</testCase>
+
 	<testCase id="070000">
 		<class>Iperf</class>
 		<desc>iperf (DL/40Mbps/UDP)(60 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 40M -t 60</iperf_args>
+		<iperf_args>-u -b 40M -t 60 -i 1 -fm</iperf_args>
 		<direction>DL</direction>
 		<id>idefix</id>
 		<iperf_packetloss_threshold>20</iperf_packetloss_threshold>
@@ -131,7 +150,7 @@
 	<testCase id="070001">
 		<class>Iperf</class>
 		<desc>iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile)</desc>
-		<iperf_args>-u -b 3M -t 60</iperf_args>
+		<iperf_args>-u -b 3M -t 60 -i 1 -fm</iperf_args>
 		<direction>UL</direction>
 		<id>idefix</id>
 		<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
@@ -139,6 +158,15 @@
 		<iperf_profile>single-ue</iperf_profile>
 	</testCase>
 
+    <testCase id="070002">
+        <class>Iperf</class>
+        <desc>iperf (BIDIR TCP)(10 sec)(single-ue profile)</desc>
+        <iperf_args>-t 10 --bidir</iperf_args>
+        <direction>BIDIR</direction>
+        <id>idefix</id>
+        <iperf_profile>single-ue</iperf_profile>
+    </testCase>
+
     <testCase id="030201">
         <class>Undeploy_Object</class>
         <desc>Undeploy eNB</desc>
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/README.md b/ci-scripts/yaml_files/5g_rfsimulator/README.md
index 5eb2a789a94c30ae294a65680cd1864f0d476ffc..64c9084500ce58c964875b8ad78313cb0506cab4 100644
--- a/ci-scripts/yaml_files/5g_rfsimulator/README.md
+++ b/ci-scripts/yaml_files/5g_rfsimulator/README.md
@@ -234,7 +234,7 @@ Making sure the OAI UE is connected:
 $ docker exec -it rfsim5g-oai-nr-ue /bin/bash
 root@bb4d400a832d:/opt/oai-nr-ue# ifconfig 
 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
-        inet 192.168.71.137  netmask 255.255.255.192  broadcast 192.168.71.191
+        inet 192.168.71.150  netmask 255.255.255.192  broadcast 192.168.71.191
         ether 02:42:c0:a8:47:89  txqueuelen 0  (Ethernet)
         RX packets 224259  bytes 5821372018 (5.8 GB)
         RX errors 0  dropped 0  overruns 0  frame 0
@@ -270,7 +270,7 @@ Create entry for Second UE in docker-compose.yaml file as follows:
         privileged: true
         container_name: rfsim5g-oai-nr-ue2
         environment:
-            RFSIMULATOR: 192.168.71.136
+            RFSIMULATOR: 192.168.71.140
             FULL_IMSI: '208990100001101'
             FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
             OPC: 'C42449363BBAD02B66D16BC975D77CC1'
@@ -282,7 +282,7 @@ Create entry for Second UE in docker-compose.yaml file as follows:
             - oai-gnb
         networks:
             public_net:
-                ipv4_address: 192.168.71.138
+                ipv4_address: 192.168.71.151
         healthcheck:
             test: /bin/bash -c "pgrep nr-uesoftmodem"
             interval: 10s
@@ -326,7 +326,7 @@ Making sure the Second OAI UE is connected:
 $ docker exec -it rfsim5g-oai-nr-ue2 /bin/bash
 root@bb4d400a832d:/opt/oai-nr-ue# ifconfig 
 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
-        inet 192.168.71.138  netmask 255.255.255.192  broadcast 192.168.71.191
+        inet 192.168.71.151  netmask 255.255.255.192  broadcast 192.168.71.191
         ether 02:42:c0:a8:47:8a  txqueuelen 0  (Ethernet)
         RX packets 3192021  bytes 67784900946 (67.7 GB)
         RX errors 0  dropped 0  overruns 0  frame 0
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
index 808be7d83d5f8c370a49c1a91050e2642f700070..f27ec3050dc2116faf97f28d4e25f64abb8fcf02 100644
--- a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
+++ b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml
@@ -279,6 +279,30 @@ services:
             timeout: 5s
             retries: 5
 
+    oai-nr-ue2:
+        image: oai-nr-ue:develop
+        privileged: true
+        container_name: rfsim5g-oai-nr-ue2
+        environment: 
+            RFSIMULATOR: 192.168.71.140
+            FULL_IMSI: '208990100001101'
+            FULL_KEY: 'fec86ba6eb707ed08905757b1bb44b8f'
+            OPC: 'C42449363BBAD02B66D16BC975D77CC1'
+            DNN: oai
+            NSSAI_SST: 1
+            NSSAI_SD: 1
+            USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 -C 3619200000 --nokrnmod --log_config.global_log_options level,nocolor,time
+        depends_on:
+            - oai-gnb
+        networks:
+            public_net:
+                ipv4_address: 192.168.71.151
+        healthcheck:
+            test: /bin/bash -c "pgrep nr-uesoftmodem"
+            interval: 10s
+            timeout: 5s
+            retries: 5
+
 networks:
     public_net:
         driver: bridge
diff --git a/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql b/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql
index fbd7907a71edd41cc32016f91176b270b8b5bd11..75f586c299c93afd9d62ac3dee0a4b82084b8710 100755
--- a/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql
+++ b/ci-scripts/yaml_files/5g_rfsimulator/oai_db.sql
@@ -192,6 +192,7 @@ LOCK TABLES `users` WRITE;
 /*!40000 ALTER TABLE `users` DISABLE KEYS */;
 INSERT INTO `users` VALUES ('20834123456789','380561234567','35609204079300',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,'+�E��ų\0�,IH��H',0,0,00000000000000000096,'Px�X \Z1��x��','^��K�����FeU���'),('20810000001234','33611123456','35609204079299',NULL,'PURGED',120,40000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000281454575616225,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','�4�s@���z��~�'),('31002890832150','33638060059','35611302209414',NULL,'PURGED',120,40000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012416,'`�F�݆��D��ϛ���','�4�s@���z��~�'),('001010123456789','33600101789','35609204079298',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'\0	\n\r',1,0,00000000000000000351,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','L�*\\�����^��]� '),('208930000000001','33638030001','35609204079301',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208950000000002','33638050002','35609204079502',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000020471,'\0	\n\r','�4�s@���z��~�'),('208950000000003','33638050003','35609204079503',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012343,'\0	\n\r','�4�s@���z��~�'),('208950000000004','33638050004','35609204079504',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000005','33638050005','35609204079505',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000001','33638050001','35609204079501',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208950000000006','33638050006','35609204079506',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000007','33638050007','35609204079507',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208930000000002','33638030002','35609204079302',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000003','33638030003','35609204079303',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000004','33638030004','35609204079304',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000005','33638030005','35609204079305',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000006','33638030006','35609204079306',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000007','33638030007','35609204079307',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000007','33638040007','35609204079407',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000006','33638040006','35609204079406',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000005','33638040005','35609204079405',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000004','33638040004','35609204079404',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000003','33638040003','35609204079403',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000002','33638040002','35609204079402',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000001','33638040001','35609204079401',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208920100001100','33638020001','35609204079201',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001101','33638020001','35609204079201',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204937234,'\0	\n\r','�$I6;��+f�k�u�|�'),('208920100001102','33638020002','35609204079202',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001103','33638020003','35609204079203',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001104','33638020004','35609204079204',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001105','33638020005','35609204079205',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001106','33638020006','35609204079206',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000000000000006103,'ebd07771ace8677a','�$I6;��+f�k�u�|�'),('208920100001107','33638020007','35609204079207',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001108','33638020008','35609204079208',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001109','33638020009','35609204079209',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001110','33638020010','35609204079210',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001111','33638030011','35609304079211',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001112','33638030012','35609304079212',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001113','33638030013','35609304079213',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000006263,'�SNܒ�Iv��e�6','�4�s@���z��~�'),('208950000000008','33638050008','35609204079508',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000009','33638050009','35609204079509',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000010','33638050010','35609204079510',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000011','33638050011','35609204079511',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000012','33638050012','35609204079512',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000013','33638050013','35609204079513',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000014','33638050014','35609204079514',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000015','33638050015','35609204079515',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д����	|hb',1,0,00000000000000000000,'3536663032363164','�4�s@���z��~�'),('208920100001118','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204934762,'~?03�u-%�ey�y�','�$I6;��+f�k�u�|�'),('208920100001121','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'&��@xg�]���\n��Vp','�$I6;��+f�k�u�|�'),('208920100001119','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'269482407867805d','�$I6;��+f�k�u�|�'),('208920100001120','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'3236393438323430','�$I6;��+f�k�u�|�');
 INSERT INTO `users` VALUES ('208990100001100','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1);
+INSERT INTO `users` VALUES ('208990100001101','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1);
 INSERT INTO `users` VALUES ('208950000000031','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
 INSERT INTO `users` VALUES ('208950000000032','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
 INSERT INTO `users` VALUES ('208950000000033','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d);
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 4793ef4e95fc7a0e78d280ee0c07bb93ac95f71f..ff0d3c5a4786e6bef0a7016d7ab6ae1ad9e1aac7 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -63,7 +63,7 @@
 
 #include "PHY/phy_extern.h"
 
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "common/ran_context.h"
 #include "RRC/LTE/rrc_extern.h"
 #include "PHY_INTERFACE/phy_interface.h"
 #include "common/utils/LOG/log_extern.h"
@@ -75,7 +75,6 @@
 #include "enb_config.h"
 #include "gnb_paramdef.h"
 
-
 #include "s1ap_eNB.h"
 #include "SIMULATION/ETH_TRANSPORT/proto.h"
 #include <executables/softmodem-common.h>
@@ -518,7 +517,8 @@ void init_eNB_afterRU(void) {
     RC.nb_nr_inst = 1;
   for (inst=0; inst<RC.nb_nr_inst; inst++) {
     LOG_I(PHY,"RC.nb_nr_CC[inst:%d]:%p\n", inst, RC.gNB[inst]);
-    gNB                                  =  RC.gNB[inst];
+    gNB = RC.gNB[inst];
+
     phy_init_nr_gNB(gNB,0,0);
 
     // map antennas and PRACH signals to gNB RX
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index ff3bdf3b8e2a9f91c2434d46901f71e04227c19c..6a8faa6669a13cb6a9f2550d981a953a57871b0c 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -38,7 +38,7 @@
 #include "openair1/PHY/CODING/nrLDPC_extern.h"
 #include "assertions.h"
 #include <math.h>
-
+#include <complex.h>
 #include "PHY/NR_TRANSPORT/nr_ulsch.h"
 #include "PHY/NR_REFSIG/nr_refsig.h"
 #include "SCHED_NR/fapi_nr_l1.h"
@@ -71,6 +71,407 @@ int l1_north_init_gNB() {
   return(0);
 }
 
+int init_codebook_gNB(PHY_VARS_gNB *gNB) {
+
+  if(gNB->frame_parms.nb_antennas_tx>1){
+    int CSI_RS_antenna_ports = gNB->frame_parms.nb_antennas_tx;
+    //NR Codebook Generation for codebook type1 SinglePanel
+    int N1 = gNB->ap_N1;
+    int N2 = gNB->ap_N2;
+    //Uniform Planner Array: UPA
+    //    X X X X ... X
+    //    X X X X ... X
+    // N2 . . . . ... .
+    //    X X X X ... X
+    //   |<-----N1---->|
+    int x_polarization = gNB->ap_XP;
+    //Get the uniform planar array parameters
+    // To be confirmed
+    int O2 = N2 > 1? 4 : 1; //Vertical beam oversampling (1 or 4)
+    int O1 = CSI_RS_antenna_ports > 2 ? 4 : 1; //Horizontal beam oversampling (1 or 4)
+    AssertFatal(CSI_RS_antenna_ports == N1*N2*x_polarization,
+                "Nb of antenna ports at PHY %d does not correspond to what passed down with fapi %d\n",
+                 N1*N2*x_polarization, CSI_RS_antenna_ports);
+
+    // Generation of codebook Type1 with codebookMode 1 (CSI_RS_antenna_ports < 16)
+    if (CSI_RS_antenna_ports < 16) {
+      //Generate DFT vertical beams
+      //ll: index of a vertical beams vector (represented by i1_1 in TS 38.214)
+      double complex v[N1*O1][N1];
+      for (int ll=0; ll<N1*O1; ll++) { //i1_1
+        for (int nn=0; nn<N1; nn++) {
+          v[ll][nn] = cexp(I*(2*M_PI*nn*ll)/(N1*O1));
+          //printf("v[%d][%d] = %f +j %f\n", ll,nn, creal(v[ll][nn]),cimag(v[ll][nn]));
+        }
+      }
+      //Generate DFT Horizontal beams
+      //mm: index of a Horizontal beams vector (represented by i1_2 in TS 38.214)
+      double complex u[N2*O2][N2];
+      for (int mm=0; mm<N2*O2; mm++) { //i1_2
+        for (int nn=0; nn<N2; nn++) {
+          u[mm][nn] = cexp(I*(2*M_PI*nn*mm)/(N2*O2));
+              //printf("u[%d][%d] = %f +j %f\n", mm,nn, creal(u[mm][nn]),cimag(u[mm][nn]));
+        }
+      }
+      //Generate co-phasing angles
+      //i_2: index of a co-phasing vector
+      //i1_1, i1_2, and i_2 are reported from UEs
+      double complex theta_n[4];
+      for (int nn=0; nn<4; nn++) {
+        theta_n[nn] = cexp(I*M_PI*nn/2);
+        //printf("theta_n[%d] = %f +j %f\n", nn, creal(theta_n[nn]),cimag(theta_n[nn]));
+      }
+      //Kronecker product v_lm
+      double complex v_lm[N1*O1][N2*O2][N2*N1];
+      //v_ll_mm_codebook denotes the elements of a precoding matrix W_i1,1_i_1,2
+      for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+        for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+          for (int nn1=0; nn1<N1; nn1++) {
+            for (int nn2=0; nn2<N2; nn2++) {
+              //printf("indx %d \n",nn1*N2+nn2);
+              v_lm[ll][mm][nn1*N2+nn2] = v[ll][nn1]*u[mm][nn2];
+              //printf("v_lm[%d][%d][%d] = %f +j %f\n",ll,mm, nn1*N2+nn2, creal(v_lm[ll][mm][nn1*N2+nn2]),cimag(v_lm[ll][mm][nn1*N2+nn2]));
+            }
+          }
+        }
+      }
+
+      int max_mimo_layers =(CSI_RS_antenna_ports<NR_MAX_NB_LAYERS) ? CSI_RS_antenna_ports : NR_MAX_NB_LAYERS;
+
+      gNB->nr_mimo_precoding_matrix = (int32_t ***)malloc16(max_mimo_layers* sizeof(int32_t **));
+      int32_t ***mat = gNB->nr_mimo_precoding_matrix;
+      double complex res_code;
+
+      //Table 5.2.2.2.1-5:
+      //Codebook for 1-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
+      gNB->pmiq_size[0] = N1*O1*N2*O2*4+1;
+      mat[0] = (int32_t **)malloc16(gNB->pmiq_size[0]*sizeof(int32_t *));
+
+      //pmi=0 corresponds to unit matrix
+      mat[0][0] = (int32_t *)calloc(2*N1*N2,sizeof(int32_t));
+      for(int j_col=0; j_col<1; j_col++) { //1 layer
+        for (int i_rows=0; i_rows<2*N1*N2; i_rows++) { //2-x polarized antenna
+          if(j_col==i_rows) {
+            mat[0][0][i_rows+j_col] = 0x7fff;
+          }
+        }
+      }
+
+      for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+        for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+          for (int nn=0; nn<4; nn++) {
+            int pmiq = 1+ll*N2*O2*4+mm*4+nn;
+            mat[0][pmiq] = (int32_t *)malloc16((2*N1*N2)*1*sizeof(int32_t));
+            LOG_D(PHY, "layer 1 Codebook pmiq = %d\n",pmiq);
+            for (int len=0; len<N1*N2; len++) {
+              res_code=sqrt(1/(double)CSI_RS_antenna_ports)*v_lm[ll][mm][len];
+              if (creal(res_code)>0)
+                ((short*) &mat[0][pmiq][len])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+              else
+                ((short*) &mat[0][pmiq][len])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+              if (cimag(res_code)>0)
+                ((short*) &mat[0][pmiq][len])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+              else
+                ((short*) &mat[0][pmiq][len])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+              LOG_D(PHY, "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                    pmiq, len, creal(res_code), cimag(res_code),((short*) &mat[0][pmiq][len])[0],((short*) &mat[0][pmiq][len])[1]);
+            }
+
+            for(int len=N1*N2; len<2*N1*N2; len++) {
+              res_code=sqrt(1/(double)CSI_RS_antenna_ports)*theta_n[nn]*v_lm[ll][mm][len-N1*N2];
+              if (creal(res_code)>0)
+                ((short*) &mat[0][pmiq][len])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+              else
+                ((short*) &mat[0][pmiq][len])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+              if (cimag(res_code)>0)
+                ((short*) &mat[0][pmiq][len])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+              else
+                ((short*) &mat[0][pmiq][len])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+              LOG_D(PHY, "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                    pmiq, len, creal(res_code), cimag(res_code),((short*) &mat[0][pmiq][len])[0],((short*) &mat[0][pmiq][len])[1]);
+            }
+          }
+        }
+      }
+
+      int llc;
+      int mmc;
+      double complex phase_sign;
+      //Table 5.2.2.2.1-6:
+      //Codebook for 2-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
+      //Compute the code book size for generating 2 layers out of Tx antenna ports
+
+      //pmi_size is computed as follows
+      gNB->pmiq_size[1] = 1;//1 for unity matrix
+      for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+        for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+          for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+            for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+              for (int nn=0; nn<2; nn++) {
+                if((llb != ll) || (mmb != mm) || ((N1 == 1) && (N2 == 1))) gNB->pmiq_size[1] += 1;
+              }
+            }
+          }
+        }
+      }
+      mat[1] = (int32_t **)malloc16(gNB->pmiq_size[1]*sizeof(int32_t *));
+
+      //pmi=0 corresponds to unit matrix
+      mat[1][0] = (int32_t *)calloc((2*N1*N2)*(2),sizeof(int32_t));
+      for(int j_col=0; j_col<2; j_col++) { //2 layers
+        for (int i_rows=0; i_rows<2*N1*N2; i_rows++) { //2-x polarized antenna
+          if(j_col==i_rows) {
+            mat[1][0][i_rows*2+j_col] = 0x7fff;
+          }
+        }
+      }
+
+      //pmi=1,...,pmi_size, we construct
+      int pmiq = 0;
+      for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+        for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+          for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+            for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+              for (int nn=0; nn<2; nn++) {
+                if((llb != ll) || (mmb != mm) || ((N1 == 1) && (N2 == 1))){
+                  pmiq += 1;
+                  mat[1][pmiq] = (int32_t *)malloc16((2*N1*N2)*(2)*sizeof(int32_t));
+                  LOG_I(PHY, "layer 2 Codebook pmiq = %d\n",pmiq);
+                  for(int j_col=0; j_col<2; j_col++) {
+                    if (j_col==0) {
+                      llc = llb;
+                      mmc = mmb;
+                      phase_sign = 1;
+                    }
+                    if (j_col==1) {
+                      llc = ll;
+                      mmc = mm;
+                      phase_sign = -1;
+                    }
+                    for (int i_rows=0; i_rows<N1*N2; i_rows++) {
+                      res_code=sqrt(1/(double)(2*CSI_RS_antenna_ports))*v_lm[llc][mmc][i_rows];
+                      if (creal(res_code)>0)
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                      else
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                      if (cimag(res_code)>0)
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                      else
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                      LOG_D(PHY, "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                            pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[1][pmiq][i_rows*2+j_col])[0],((short*) &mat[1][pmiq][i_rows*2+j_col])[1]);
+                    }
+                    for (int i_rows=N1*N2; i_rows<2*N1*N2; i_rows++) {
+                      res_code=sqrt(1/(double)(2*CSI_RS_antenna_ports))*(phase_sign)*theta_n[nn]*v_lm[llc][mmc][i_rows-N1*N2];
+                      if (creal(res_code)>0)
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                      else
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                      if (cimag(res_code)>0)
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                      else
+                        ((short*) &mat[1][pmiq][i_rows*2+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                      LOG_D(PHY, "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                            pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[1][pmiq][i_rows*2+j_col])[0],((short*) &mat[1][pmiq][i_rows*2+j_col])[1]);
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      //Table 5.2.2.2.1-7:
+      //Codebook for 3-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
+      if(max_mimo_layers>=3) {
+
+        //pmi_size is computed as follows
+        gNB->pmiq_size[2] = 1;//unity matrix
+        for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+          for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+            for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+              for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+                for (int nn=0; nn<2; nn++) {
+                  if((llb != ll) || (mmb != mm)) gNB->pmiq_size[2] += 1;
+                }
+              }
+            }
+          }
+        }
+        mat[2] = (int32_t **)malloc16(gNB->pmiq_size[2]*sizeof(int32_t *));
+        //pmi=0 corresponds to unit matrix
+        mat[2][0] = (int32_t *)calloc((2*N1*N2)*(3),sizeof(int32_t));
+        for(int j_col=0; j_col<3; j_col++) { //3 layers
+          for (int i_rows=0; i_rows<2*N1*N2; i_rows++) { //2-x polarized antenna
+            if(j_col==i_rows) {
+              mat[2][0][i_rows*3+j_col] = 0x7fff;
+            }
+          }
+        }
+
+        pmiq = 0;
+        //pmi=1,...,pmi_size are computed as follows
+        for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+          for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+            for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+              for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+                for (int nn=0; nn<2; nn++) {
+                  if((llb != ll) || (mmb != mm)){
+                    pmiq += 1;
+                    mat[2][pmiq] = (int32_t *)malloc16((2*N1*N2)*(3)*sizeof(int32_t));
+                    LOG_I(PHY, "layer 3 Codebook pmiq = %d\n",pmiq);
+                    for(int j_col=0; j_col<3; j_col++) {
+                      if (j_col==0) {
+                        llc = llb;
+                        mmc = mmb;
+                        phase_sign = 1;
+                      }
+                      if (j_col==1) {
+                        llc = ll;
+                        mmc = mm;
+                        phase_sign = 1;
+                      }
+                      if (j_col==2) {
+                        llc = ll;
+                        mmc = mm;
+                        phase_sign = -1;
+                      }
+                      for (int i_rows=0; i_rows<N1*N2; i_rows++) {
+                        res_code=sqrt(1/(double)(3*CSI_RS_antenna_ports))*v_lm[llc][mmc][i_rows];
+                        if (creal(res_code)>0)
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                        if (cimag(res_code)>0)
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                        LOG_D(PHY, "3 Layer Precoding Matrix[2][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                              pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[2][pmiq][i_rows*3+j_col])[0],((short*) &mat[2][pmiq][i_rows*3+j_col])[1]);
+                      }
+                      for (int i_rows=N1*N2; i_rows<2*N1*N2; i_rows++) {
+                        res_code=sqrt(1/(double)(3*CSI_RS_antenna_ports))*(phase_sign)*theta_n[nn]*v_lm[llc][mmc][i_rows-N1*N2];
+                        if (creal(res_code)>0)
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                        if (cimag(res_code)>0)
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[2][pmiq][i_rows*3+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                        LOG_D(PHY, "3 Layer Precoding Matrix[2][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                              pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[2][pmiq][i_rows*3+j_col])[0],((short*) &mat[2][pmiq][i_rows*3+j_col])[1]);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      //Table 5.2.2.2.1-8:
+      //Codebook for 4-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
+      if(max_mimo_layers>=4) {
+        //pmi_size is computed as follows
+        gNB->pmiq_size[3] = 1;//unity matrix
+        for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+          for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+            for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+              for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+                for (int nn=0; nn<2; nn++) {
+                  if((llb != ll) || (mmb != mm)) gNB->pmiq_size[3] += 1;
+                }
+              }
+            }
+          }
+        }
+
+        mat[3] = (int32_t **)malloc16(gNB->pmiq_size[3]*sizeof(int32_t *));
+        //pmi=0 corresponds to unit matrix
+        mat[3][0] = (int32_t *)calloc((2*N1*N2)*(4),sizeof(int32_t));
+        for(int j_col=0; j_col<4; j_col++) { //4 layers
+          for (int i_rows=0; i_rows<2*N1*N2; i_rows++) { //2-x polarized antenna
+            if(j_col==i_rows) {
+              mat[3][0][i_rows*4+j_col] = 0x7fff;
+            }
+          }
+        }
+
+        pmiq = 0;
+        //pmi=1,...,pmi_size are computed as follows
+        for(int llb=0; llb<N1*O1; llb++) { //i_1_1
+          for (int mmb=0; mmb<N2*O2; mmb++) { //i_1_2
+            for(int ll=0; ll<N1*O1; ll++) { //i_1_1
+              for (int mm=0; mm<N2*O2; mm++) { //i_1_2
+                for (int nn=0; nn<2; nn++) {
+
+                  if((llb != ll) || (mmb != mm)){
+                    pmiq += 1;
+                    mat[3][pmiq] = (int32_t *)malloc16((2*N1*N2)*4*sizeof(int32_t));
+                    LOG_I(PHY, "layer 4 pmiq = %d\n",pmiq);
+                    for(int j_col=0; j_col<4; j_col++) {
+                      if (j_col==0) {
+                        llc = llb;
+                        mmc = mmb;
+                        phase_sign = 1;
+                      }
+                      if (j_col==1) {
+                        llc = ll;
+                        mmc = mm;
+                        phase_sign = 1;
+                      }
+                      if (j_col==2) {
+                        llc = llb;
+                        mmc = mmb;
+                        phase_sign = -1;
+                      }
+                      if (j_col==3) {
+                        llc = ll;
+                        mmc = mm;
+                        phase_sign = -1;
+                      }
+                      for (int i_rows=0; i_rows<N1*N2; i_rows++) {
+                        res_code=sqrt(1/(double)(4*CSI_RS_antenna_ports))*v_lm[llc][mmc][i_rows];
+                        if (creal(res_code)>0)
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                        if (cimag(res_code)>0)
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                        LOG_D(PHY, "4 Layer Precoding Matrix[3][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                              pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[3][pmiq][i_rows*4+j_col])[0],((short*) &mat[3][pmiq][i_rows*4+j_col])[1]);
+                      }
+
+                      for (int i_rows=N1*N2; i_rows<2*N1*N2; i_rows++) {
+                        res_code=sqrt(1/(double)(4*CSI_RS_antenna_ports))*(phase_sign)*theta_n[nn]*v_lm[llc][mmc][i_rows-N1*N2];
+                        if (creal(res_code)>0)
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[0] = (short) ((creal(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[0] = (short) ((creal(res_code)*32768)-0.5);//convert to Q15
+                        if (cimag(res_code)>0)
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[1] = (short) ((cimag(res_code)*32768)+0.5);//convert to Q15
+                        else
+                          ((short*) &mat[3][pmiq][i_rows*4+j_col])[1] = (short) ((cimag(res_code)*32768)-0.5);//convert to Q15
+                        LOG_D(PHY, "4 Layer Precoding Matrix[3][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n",
+                              pmiq,i_rows,j_col, creal(res_code), cimag(res_code),((short*) &mat[3][pmiq][i_rows*4+j_col])[0],((short*) &mat[3][pmiq][i_rows*4+j_col])[1]);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return 0;
+}
 
 int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
                     unsigned char is_secondary_gNB,
@@ -108,6 +509,9 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   init_scrambling_luts();
   init_pucch2_luts();
   load_nrLDPClib(NULL);
+
+  init_codebook_gNB(gNB);
+
   // PBCH DMRS gold sequences generation
   nr_init_pbch_dmrs(gNB);
   //PDCCH DMRS init
@@ -317,6 +721,16 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
   const int max_ul_mimo_layers = 4; // taken from phy_init_nr_gNB()
   const int n_buf = Prx * max_ul_mimo_layers;
 
+  int max_dl_mimo_layers =(fp->nb_antennas_tx<NR_MAX_NB_LAYERS) ? fp->nb_antennas_tx : NR_MAX_NB_LAYERS;
+  if (fp->nb_antennas_tx>1) {
+    for (int nl = 0; nl < max_dl_mimo_layers; nl++) {
+      for(int size = 0; size < gNB->pmiq_size[nl]; size++)
+        free_and_zero(gNB->nr_mimo_precoding_matrix[nl][size]);
+      free_and_zero(gNB->nr_mimo_precoding_matrix[nl]);
+    }
+    free_and_zero(gNB->nr_mimo_precoding_matrix);
+  }
+
   uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
   for (int slot = 0; slot < fp->slots_per_frame; slot++) {
     for (int symb = 0; symb < fp->symbols_per_slot; symb++)
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 75315187d9a7068beb9f2f593e221c7dc76e2aad..142ef9b1d970aacb9e2772c5255c6fdce83a55d0 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -55,13 +55,11 @@ extern uint16_t beta_cqi[16];
  * \param[in] frame_parms LTE_DL_FRAME_PARMS structure.
  * \note This function is optimistic in that it expects malloc() to succeed.
  */
-void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
+void phy_init_nr_ue_PDSCH(NR_UE_PDSCH *const pdsch,
                            const NR_DL_FRAME_PARMS *const fp) {
 
   AssertFatal( pdsch, "pdsch==0" );
-  pdsch->pmi_ext = (uint8_t *)malloc16_clear( fp->N_RB_DL );
-  pdsch->llr[0] = (int16_t *)malloc16_clear( (8*(3*8*6144))*sizeof(int16_t) );
-  pdsch->layer_llr[0] = (int16_t *)malloc16_clear( (8*(3*8*6144))*sizeof(int16_t) );
+
   pdsch->llr128 = (int16_t **)malloc16_clear( sizeof(int16_t *) );
   // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV
   // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there
@@ -73,8 +71,6 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
   pdsch->dl_ch_estimates_ext    = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
   pdsch->dl_bf_ch_estimates     = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
   pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
-  //pdsch->dl_ch_rho_ext          = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-  //pdsch->dl_ch_rho2_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
   pdsch->dl_ch_mag0             = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
   pdsch->dl_ch_magb0            = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
   pdsch->dl_ch_magr0            = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
@@ -103,8 +99,6 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
       pdsch->dl_ch_estimates_ext[idx]     = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_bf_ch_estimates[idx]      = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
       pdsch->dl_bf_ch_estimates_ext[idx]  = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-      //pdsch->dl_ch_rho_ext[idx]           = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-      //pdsch->dl_ch_rho2_ext[idx]          = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_ch_mag0[idx]              = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_ch_magb0[idx]             = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_ch_magr0[idx]             = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
@@ -136,8 +130,11 @@ void phy_term_nr_ue__PDSCH(NR_UE_PDSCH* pdsch, const NR_DL_FRAME_PARMS *const fp
     free_and_zero(pdsch->rho[i]);
   }
   free_and_zero(pdsch->pmi_ext);
-  free_and_zero(pdsch->llr[0]);
-  free_and_zero(pdsch->layer_llr[0]);
+  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
+  for (int i=0; i<nb_codewords; i++)
+    free_and_zero(pdsch->llr[i]);
+  for (int i=0; i<NR_MAX_NB_LAYERS; i++)
+    free_and_zero(pdsch->layer_llr[i]);
   free_and_zero(pdsch->llr128);
   free_and_zero(pdsch->rxdataF_ext);
   free_and_zero(pdsch->rxdataF_uespec_pilots);
@@ -162,13 +159,10 @@ 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,k,l,slot,symb;
+  int i,j,slot,symb, gNB_id, th_id;
 
   NR_UE_SRS **const srs_vars             = ue->srs_vars;
 
-  int gNB_id;
-  int th_id;
-
   LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx);
 
   phy_init_nr_top(ue);
@@ -348,54 +342,18 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
       ue->nr_srs_info->srs_estimated_channel_time_shifted[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t));
     }
 
-    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 );
-    }
 
     for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-      ue->pdsch_vars[th_id][gNB_id]->llr_shifts          = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12);
-      ue->pdsch_vars[th_id][gNB_id]->llr_shifts_p        = ue->pdsch_vars[0][gNB_id]->llr_shifts;
-      ue->pdsch_vars[th_id][gNB_id]->llr[1]              = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
-      ue->pdsch_vars[th_id][gNB_id]->layer_llr[1]        = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
-      ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream    = (int16_t **)malloc16_clear( sizeof(int16_t *) );
+      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++) {
-      ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext      = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-    }
-
-    for (i=0; i<fp->nb_antennas_rx; i++)
-      for (j=0; j<4; j++) {
-        const int idx = (j*fp->nb_antennas_rx)+i;
-        const size_t num = 7*2*fp->N_RB_DL*12+4;
-
-        for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-          ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-        }
+      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
       }
-
-    //const size_t num = 7*2*fp->N_RB_DL*12+4;
-    for (k=0; k<8; k++) { //harq_pid
-      for (l=0; l<8; l++) { //round
-        for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-          ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-          ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-          ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l]    = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-          ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l]   = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
-        }
-
-        for (int i=0; i<fp->nb_antennas_rx; i++)
-          for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++)
-            const int idx = (j*fp->nb_antennas_rx)+i;
-
-            for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-              ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
-              ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
-              ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l][idx]    = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
-              ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l][idx]   = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
-            }
-          }
+      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
       }
     }
 
@@ -406,7 +364,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
       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]->e_rx                = (int16_t *)malloc16_clear( 4*2*100*12 );
       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]->dl_ch_rho_ext       = (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 *) );
@@ -424,7 +381,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
           //  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]->dl_ch_rho_ext[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);
         }
@@ -437,13 +393,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
 
   }
 
-  // initialization for the last instance of pdsch_vars (used for MU-MIMO)
-  for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
-    ue->pdsch_vars[th_id][gNB_id] = malloc16_clear(sizeof(NR_UE_PDSCH));
-    ue->pdsch_vars[th_id][gNB_id]->llr[1] = malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
-    ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
-  }
-
   ue->sinr_CQI_dB = (double *) malloc16_clear( fp->N_RB_DL*12*sizeof(double) );
   ue->init_averaging = 1;
 
@@ -523,37 +472,9 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
 
     // PDSCH
     for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
-      for (int k = 0; k < 8; k++) { //harq_pid
-        for (int l = 0; l < 8; l++) { //round
-          for (int i = 0; i < fp->nb_antennas_rx; i++) {
-            for (int j = 0; j < 4; j++) { //frame_parms->nb_antennas_tx; j++)
-              const int idx = j * fp->nb_antennas_rx + i;
-              free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l][idx]);
-              free_and_zero(ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l][idx]);
-              free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l][idx]);
-              free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l][idx]);
-            }
-          }
-
-          free_and_zero(ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l]);
-          free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l]);
-          free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l]);
-          free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l]);
-        }
-      }
 
-      for (int i = 0; i < fp->nb_antennas_rx; i++) {
-        for (int j = 0; j < 4; j++) {
-          const int idx = (j*fp->nb_antennas_rx)+i;
-          free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx]);
-        }
-      }
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr_shifts);
-      free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr[1]);
-      free_and_zero(ue->pdsch_vars[th_id][gNB_id]->layer_llr[1]);
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream);
-      free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext);
-
       phy_term_nr_ue__PDSCH(ue->pdsch_vars[th_id][gNB_id], fp);
       free_and_zero(ue->pdsch_vars[th_id][gNB_id]);
     }
@@ -565,7 +486,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
           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]->dl_ch_rho_ext[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]);
         }
@@ -576,7 +496,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
       free_and_zero(ue->pdcch_vars[th_id][gNB_id]->wbar);
       free_and_zero(ue->pdcch_vars[th_id][gNB_id]->e_rx);
       free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp);
-      free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext);
       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);
@@ -612,13 +531,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
     free_and_zero(ue->prach_vars[gNB_id]);
   }
 
-  const int gNB_id = ue->n_connected_gNB;
-  for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
-    free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr[1]);
-    free_and_zero(ue->pdsch_vars[th_id][gNB_id]->layer_llr[1]);
-    free_and_zero(ue->pdsch_vars[th_id][gNB_id]);
-  }
-
   free_and_zero(ue->sinr_CQI_dB);
 }
 
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index 8648dd7d82c70fe4fae0592b1a7636818a54a3cb..29940a4fbe99bd851d5fd7300470169e2775879f 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -402,6 +402,7 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue);
 void init_N_TA_offset(PHY_VARS_NR_UE *ue);
 void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
 int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char lowmem_flag);
+int init_codebook_gNB(PHY_VARS_gNB *gNB);
 void nr_phy_config_request(NR_PHY_Config_t *gNB);
 void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell,uint64_t position_in_burst);
 void phy_free_nr_gNB(PHY_VARS_gNB *gNB);
diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c
index 4cb3185b67ef5a99eeb624bcf57616220f6329f1..b1a108f24756294a2ce77390db3d667779ae435d 100644
--- a/openair1/PHY/MODULATION/nr_modulation.c
+++ b/openair1/PHY/MODULATION/nr_modulation.c
@@ -719,3 +719,18 @@ int nr_layer_precoder(int16_t **datatx_F_precoding, char *prec_matrix, uint8_t n
   /*  ((int16_t *)precodatatx_F)[0] = (int16_t)((((int16_t *)precodatatx_F)[0]*ONE_OVER_SQRT2_Q15)>>15);
       ((int16_t *)precodatatx_F)[1] = (int16_t)((((int16_t *)precodatatx_F)[1]*ONE_OVER_SQRT2_Q15)>>15);*/
 }
+
+int nr_layer_precoder_cm(int16_t **datatx_F_precoding, int *prec_matrix, uint8_t n_layers, int32_t re_offset)
+{
+  int32_t precodatatx_F = 0;
+  for (int al = 0; al<n_layers; al++) {
+    int16_t antenna_re = datatx_F_precoding[al][re_offset<<1];
+    int16_t antenna_im = datatx_F_precoding[al][(re_offset<<1) +1];
+    //printf("antenna precoding: %d %d\n",((int16_t *)&prec_matrix[al])[0],((int16_t *)&prec_matrix[al])[1]);
+    ((int16_t *) &precodatatx_F)[0] += (int16_t)(((int32_t)(antenna_re*(((int16_t *)&prec_matrix[al])[0])) - (int32_t)(antenna_im* (((int16_t *)&prec_matrix[al])[1])))>>15);
+    ((int16_t *) &precodatatx_F)[1] += (int16_t)(((int32_t)(antenna_re*(((int16_t *)&prec_matrix[al])[1])) + (int32_t)(antenna_im* (((int16_t *)&prec_matrix[al])[0])))>>15);
+  }
+
+  return precodatatx_F;
+}
+
diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h
index db15e3d9efc5fac5b145e82d5bca19e6735a61a1..65f147fffa2716cd4317b072ac31de34399d55e0 100644
--- a/openair1/PHY/MODULATION/nr_modulation.h
+++ b/openair1/PHY/MODULATION/nr_modulation.h
@@ -135,4 +135,9 @@ int nr_layer_precoder(int16_t **datatx_F_precoding,
 		char *prec_matrix,
 		uint8_t n_layers,
 		int32_t re_offset);
+
+int nr_layer_precoder_cm(int16_t **datatx_F_precoding,
+                int *prec_matrix,
+                uint8_t n_layers,
+                int32_t re_offset);
 #endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index e0c445d3852eb2cb709e0f83b9d8a2d3c25bf6d9..47d6c48373b4e93203e2e957434164909baab16b 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -439,8 +439,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
     // The same precoding matrix is applied on prg_size RBs, Thus
     //        pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
     // The Precoding matrix:
-    // The Codebook Type I and Type II are not supported yet.
-    // We`adopt the precoding matrices of PUSCH for 4 layers.
+    // The Codebook Type I
     start_meas(&gNB->dlsch_precoding_stats);
 
     for (int ap=0; ap<frame_parms->nb_antennas_tx; ap++) {
@@ -491,47 +490,38 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
             }
           }
           else {
-            //get the precoding matrix weights:
-            char *W_prec;
-            switch (frame_parms->nb_antennas_tx) {
-              case 1://1 antenna port
-                W_prec = nr_W_1l_2p[pmi][ap];
-                break;
-              case 2://2 antenna ports
-                if (rel15->nrOfLayers == 1)//1 layer
-                  W_prec = nr_W_1l_2p[pmi][ap];
-                else//2 layers
-                  W_prec = nr_W_2l_2p[pmi][ap];
-                break;
-              case 4://4 antenna ports
-                if (rel15->nrOfLayers == 1)//1 layer
-                  W_prec = nr_W_1l_4p[pmi][ap];
-                else if (rel15->nrOfLayers == 2)//2 layers
-                  W_prec = nr_W_2l_4p[pmi][ap];
-                else if (rel15->nrOfLayers == 3)//3 layers
-                  W_prec = nr_W_3l_4p[pmi][ap];
-                else//4 layers
-                  W_prec = nr_W_4l_4p[pmi][ap];
-                break;
-              default:
-                LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n");
-                W_prec = nr_W_1l_2p[pmi][ap];
-                break;
-            }
-            for (int i=0; i<NR_NB_SC_PER_RB; i++) {
-              int32_t re_offset = l*frame_parms->ofdm_symbol_size + k;
-              int32_t precodatatx_F = nr_layer_precoder(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset);
-              ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0];
-              ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1];
-#ifdef DEBUG_DLSCH_MAPPING
-              printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n",
-                     ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)],
-                     ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]);
-#endif
-              if (++k >= frame_parms->ofdm_symbol_size) {
+            if(frame_parms->nb_antennas_tx==1){//no precoding matrix defined
+              memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
+                     (void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
+                     NR_NB_SC_PER_RB*sizeof(int32_t));
+              k += NR_NB_SC_PER_RB;
+              if (k >= frame_parms->ofdm_symbol_size) {
                 k -= frame_parms->ofdm_symbol_size;
               }
             }
+            else {
+              //get the precoding matrix weights:
+              int32_t **mat = gNB->nr_mimo_precoding_matrix[rel15->nrOfLayers-1];
+              //i_row =0,...,dl_antenna_port
+              //j_col =0,...,nrOfLayers
+              //mat[pmi][i_rows*2+j_col]
+              int *W_prec;
+              W_prec = (int32_t *)&mat[pmi][ap*rel15->nrOfLayers];
+              for (int i=0; i<NR_NB_SC_PER_RB; i++) {
+                int32_t re_offset = l*frame_parms->ofdm_symbol_size + k;
+                int32_t precodatatx_F = nr_layer_precoder_cm(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset);
+                ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0];
+                ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1];
+  #ifdef DEBUG_DLSCH_MAPPING
+                printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n",
+                       ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)],
+                       ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]);
+  #endif
+                if (++k >= frame_parms->ofdm_symbol_size) {
+                  k -= frame_parms->ofdm_symbol_size;
+                }
+              }
+            }
           }
         } //RB loop
       } // symbol loop
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 54b7c34608511829402c6fab9abbde35ff06add2..8bdd83087a5fb200e290e63be8cad53dbfd26bcf 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -402,7 +402,7 @@ void nr_processDLSegment(void* arg) {
 
       // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
       if (check_crc((uint8_t *)llrProcBuf,length_dec,harq_process->F,crc_type)) {
-        LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
+        LOG_D(PHY,"Segment %u CRC OK\n",r);
 
         if (r==0) {
           for (int i=0; i<10; i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t *)llrProcBuf)[i]);
@@ -412,7 +412,7 @@ void nr_processDLSegment(void* arg) {
         no_iteration_ldpc = dlsch->max_ldpc_iterations;
         rdata->decodeIterations = no_iteration_ldpc;
       } else {
-        LOG_D(PHY,"CRC NOT OK\n\033[0m");
+        LOG_D(PHY,"CRC NOT OK\n");
       }
 
       nb_total_decod++;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index bbb4a1e03a52196ff1fc98551f1c79a4dfa6c96a..69eccaf02e7c541c826a1d99a5c1c4a0faa97d68 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -39,6 +39,7 @@
 #include "PHY/NR_REFSIG/nr_refsig.h"
 #include "PHY/NR_REFSIG/dmrs_nr.h"
 #include "common/utils/nr/nr_common.h"
+#include <complex.h>
 
 /* dynamic shift for LLR computation for TM3/4
  * set as command line argument, see lte-softmodem.c
@@ -79,35 +80,28 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{
 #define print_ints(s,x) printf("%s = %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3])
 #define print_shorts(s,x) printf("%s = [%d+j*%d, %d+j*%d, %d+j*%d, %d+j*%d]\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
 
-static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
-						  int **dl_ch_estimates_ext_i,
-						  int **dl_ch_rho_ext,
-						  unsigned char n_tx,
-						  unsigned char n_rx,
-						  unsigned char output_shift,
-						  int length,
-						  int start_point);
-
-uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
+/* compute H_h_H matrix inversion up to 4x4 matrices */
+uint8_t nr_zero_forcing_rx(int **rxdataF_comp,
                                    int **dl_ch_mag,
                                    int **dl_ch_magb,
                                    int **dl_ch_magr,
                                    int **dl_ch_estimates_ext,
                                    unsigned short nb_rb,
                                    unsigned char n_rx,
+                                   unsigned char n_tx,//number of layer
                                    unsigned char mod_order,
                                    int shift,
                                    unsigned char symbol,
                                    int length);
 
+/* Apply layer demapping */
 static void nr_dlsch_layer_demapping(int16_t **llr_cw,
-				     uint8_t Nl,
-				     uint8_t mod_order,
-				     uint32_t length,
-				     int32_t codeword_TB0,
-				     int32_t codeword_TB1,
-				     int16_t **llr_layers);
-
+                                     uint8_t Nl,
+                                     uint8_t mod_order,
+                                     uint32_t length,
+                                     int32_t codeword_TB0,
+                                     int32_t codeword_TB1,
+                                     int16_t **llr_layers);
 
 /* compute LLR */
 static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
@@ -130,6 +124,7 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         uint8_t nr_slot_rx,
                         uint8_t beamforming_mode);
 
+
 /* Main Function */
 int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                 UE_nr_rxtx_proc_t *proc,
@@ -159,7 +154,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
 
   unsigned char aatx=0,aarx=0;
 
-  unsigned short nb_rb = 0, round;
+  unsigned short round;
   int avgs = 0;// rb;
   NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
 
@@ -176,9 +171,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   //int16_t  *pllr_symbol_cw0_deint;
   //int16_t  *pllr_symbol_cw1_deint;
   //uint16_t bundle_L = 2;
-  uint16_t n_tx=1, n_rx=1;
   int32_t median[16];
-  uint32_t len;
+  uint32_t nb_re_pdsch;
   uint16_t startSymbIdx=0;
   uint16_t nbSymb=0;
   uint16_t pduBitmap=0x0;
@@ -204,7 +198,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
     if (NR_MAX_NB_LAYERS>4)
       dlsch1_harq = dlsch[1]->harq_processes[harq_pid];
-    beamforming_mode = ue->transmission_mode[gNB_id] < 7 ? 0 :ue->transmission_mode[gNB_id];
     break;
 
   default:
@@ -313,130 +306,92 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     return(-1);
   }
 
-  if (dlsch0_harq->mimo_mode>NR_DUALSTREAM) {
-    LOG_E(PHY,"This transmission mode is not yet supported!\n");
-    return(-1);
-  }
-
-  if (dlsch0_harq->mimo_mode==NR_DUALSTREAM)  {
-    DevAssert(dlsch1_harq);
-  }
-
   if(symbol > ue->frame_parms.symbols_per_slot>>1)
   {
       slot = 1;
   }
 
-#ifdef DEBUG_HARQ
-  printf("Demod  dlsch0_harq->pmi_alloc %d\n",  dlsch0_harq->pmi_alloc);
-#endif
-
   uint8_t pilots = (dlsch0_harq->dlDmrsSymbPos >> symbol) & 1;
   uint8_t config_type = dlsch0_harq->dmrsConfigType;
-
-  if (beamforming_mode==0) {//No beamforming
-    start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-    if (dlsch0_harq->Nl > 1)//More than or equal 2 layers
-      nb_rb = nr_dlsch_extract_rbs_multiple(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
-                                            pdsch_vars[gNB_id]->dl_ch_estimates,
-                                            pdsch_vars[gNB_id]->rxdataF_ext,
-                                            pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                            symbol,
-                                            pilots,
-                                            config_type,
-                                            start_rb + dlsch0_harq->BWPStart,
-                                            nb_rb_pdsch,
-                                            dlsch0_harq->n_dmrs_cdm_groups,
-                                            dlsch0_harq->Nl,
-                                            frame_parms,
-                                            dlsch0_harq->dlDmrsSymbPos);
-    else// one layer
-      nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
-                                          pdsch_vars[gNB_id]->dl_ch_estimates,
-                                          pdsch_vars[gNB_id]->rxdataF_ext,
-                                          pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                          symbol,
-                                          pilots,
-                                          config_type,
-                                          start_rb + dlsch0_harq->BWPStart,
-                                          nb_rb_pdsch,
-                                          dlsch0_harq->n_dmrs_cdm_groups,
-                                          frame_parms,
-                                          dlsch0_harq->dlDmrsSymbPos);
-  }
-  else if(beamforming_mode>7) {
-    LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n");
-  }
-  
-  //printf("nb_rb = %d, gNB_id %d\n",nb_rb,gNB_id);
-  if (nb_rb==0) {
-    LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n");
-    return(-1);
-  }
-
-  len = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12);
-
+  //----------------------------------------------------------
+  //--------------------- RBs extraction ---------------------
+  //----------------------------------------------------------
+  start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
+  nr_dlsch_extract_rbs(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
+                       pdsch_vars[gNB_id]->dl_ch_estimates,
+                       pdsch_vars[gNB_id]->rxdataF_ext,
+                       pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                       symbol,
+                       pilots,
+                       config_type,
+                       start_rb + dlsch0_harq->BWPStart,
+                       nb_rb_pdsch,
+                       dlsch0_harq->n_dmrs_cdm_groups,
+                       dlsch0_harq->Nl,
+                       frame_parms,
+                       dlsch0_harq->dlDmrsSymbPos);
   stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
   if (cpumeas(CPUMEAS_GETSTATE))
     LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
 	  frame,nr_slot_rx,slot,symbol,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 
-  
+  int nl = dlsch0_harq->Nl;
+  int n_rx = frame_parms->nb_antennas_rx;
+  nb_re_pdsch = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb_pdsch*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb_pdsch*(12-4*dlsch0_harq->n_dmrs_cdm_groups)) : (nb_rb_pdsch*12);
+  //----------------------------------------------------------
+  //--------------------- Channel Scaling --------------------
+  //----------------------------------------------------------
   start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-  n_tx = dlsch0_harq->Nl;
-  n_rx = frame_parms->nb_antennas_rx;
-  
   nr_dlsch_scale_channel(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
                          frame_parms,
-                         n_tx,
+                         nl,
                          n_rx,
                          dlsch,
                          symbol,
                          pilots,
-                         len,
+                         nb_re_pdsch,
                          nb_rb_pdsch);
+  stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
 
-    stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-    if (cpumeas(CPUMEAS_GETSTATE))
-      LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale  %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
+  if (cpumeas(CPUMEAS_GETSTATE))
+    LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale  %5.2f \n",
+          frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 
-    start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
+  //----------------------------------------------------------
+  //--------------------- Channel Level Calc. ----------------
+  //----------------------------------------------------------
+  start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
   if (first_symbol_flag==1) {
-    if (beamforming_mode==0){
-      nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                             frame_parms,
-                             n_tx,
-                             avg,
-                             symbol,
-                             len,
-                             nb_rb_pdsch);
-      avgs = 0;
-      for (aatx=0;aatx<n_tx;aatx++)
-        for (aarx=0;aarx<n_rx;aarx++) {
-          //LOG_I(PHY, "nb_rb %d len %d avg_%d_%d Power per SC is %d\n",nb_rb, len,aarx, aatx,avg[aatx*frame_parms->nb_antennas_rx+aarx]);
-          avgs = cmax(avgs,avg[(aatx*frame_parms->nb_antennas_rx)+aarx]);
-          //LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
-          median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx];
-        }
-
-      if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
-        nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                      median,
-                                      n_tx,
-                                      n_rx,
-                                      len,
-                                      symbol*nb_rb*12);
-
-        for (aatx = 0; aatx < n_tx; aatx++) {
-          for (aarx = 0; aarx < n_rx; aarx++) {
-            avgs = cmax(avgs, median[aatx*n_rx + aarx]);
-          }
+    nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                           frame_parms,
+                           nl,
+                           avg,
+                           symbol,
+                           nb_re_pdsch,
+                           nb_rb_pdsch);
+    avgs = 0;
+    for (aatx=0;aatx<nl;aatx++)
+      for (aarx=0;aarx<n_rx;aarx++) {
+        //LOG_I(PHY, "nb_rb %d len %d avg_%d_%d Power per SC is %d\n",nb_rb, len,aarx, aatx,avg[aatx*n_rx+aarx]);
+        avgs = cmax(avgs,avg[(aatx*n_rx)+aarx]);
+        //LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
+        median[(aatx*n_rx)+aarx] = avg[(aatx*n_rx)+aarx];
+      }
+    if (dlsch0_harq->Nl > 1) {
+      nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                    median,
+                                    nl,
+                                    n_rx,
+                                    nb_re_pdsch,
+                                    symbol*nb_rb_pdsch*12);
+      for (aatx = 0; aatx < nl; aatx++) {
+        for (aarx = 0; aarx < n_rx; aarx++) {
+          avgs = cmax(avgs, median[aatx*n_rx + aarx]);
         }
       }
-
-      pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
-      //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs,  pdsch_vars[gNB_id]->log2_maxh);
     }
+    pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
+    //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs,  pdsch_vars[gNB_id]->log2_maxh);
     LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
           frame%1024,
           nr_slot_rx,
@@ -446,128 +401,83 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
           avg[0],
           avgs);
   }
+  stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
 
 #if T_TRACER
-    if (type == PDSCH)
-    {
-      T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id),  T_INT(0), T_INT(frame%1024), T_INT(nr_slot_rx),
-                               T_INT(avg[0]), T_INT(avg[1]),    T_INT(avg[2]),             T_INT(avg[3]));
-    }
+  if (type == PDSCH)
+  {
+    T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id),  T_INT(0), T_INT(frame%1024), T_INT(nr_slot_rx),
+                             T_INT(avg[0]), T_INT(avg[1]),    T_INT(avg[2]),             T_INT(avg[3]));
+  }
 #endif
 
-    stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-    if (cpumeas(CPUMEAS_GETSTATE))
-      LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level  %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
-
-    start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-// Now channel compensation
-  if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) {
-    nr_dlsch_channel_compensation(pdsch_vars[gNB_id]->rxdataF_ext,
-                                  pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                  pdsch_vars[gNB_id]->dl_ch_mag0,
-                                  pdsch_vars[gNB_id]->dl_ch_magb0,
-                                  pdsch_vars[gNB_id]->dl_ch_magr0,
-                                  pdsch_vars[gNB_id]->rxdataF_comp0,
-                                  (n_tx>1) ? pdsch_vars[gNB_id]->rho : NULL,
-                                  frame_parms,
-                                  n_tx,
-                                  symbol,
-                                  len,
-                                  first_symbol_flag,
-                                  dlsch0_harq->Qm,
-                                  nb_rb_pdsch,
-                                  pdsch_vars[gNB_id]->log2_maxh,
-                                  measurements); // log2_maxh+I0_shift
-    }
-
-  else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
-    nr_dlsch_channel_compensation_core(pdsch_vars[gNB_id]->rxdataF_ext,
-                                       pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                       pdsch_vars[gNB_id]->dl_ch_mag0,
-                                       pdsch_vars[gNB_id]->dl_ch_magb0,
-                                       pdsch_vars[gNB_id]->rxdataF_comp0, //rxdataF_comp
-                                       NULL,
-                                       n_tx,
-                                       n_rx,
-                                       dlsch0_harq->Qm,
-                                       pdsch_vars[gNB_id]->log2_maxh,
-                                       2*len, // subcarriers Re Im
-                                       0); // we start from the beginning of the vector
-    // compute correlation between signal and interference channels (rho12 and rho21)
-    nr_dlsch_dual_stream_correlation_core(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                          &(pdsch_vars[gNB_id]->dl_ch_estimates_ext[2]),
-                                          pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                          n_tx,
-                                          n_rx,
-                                          pdsch_vars[gNB_id]->log2_maxh,
-                                          2*len,
-                                          0);
-  }
+  if (cpumeas(CPUMEAS_GETSTATE))
+    LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level  %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 
+  //----------------------------------------------------------
+  //--------------------- channel compensation ---------------
+  //----------------------------------------------------------
+  // Disable correlation measurement for optimizing UE
+  start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
+  nr_dlsch_channel_compensation(pdsch_vars[gNB_id]->rxdataF_ext,
+                                pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                pdsch_vars[gNB_id]->dl_ch_mag0,
+                                pdsch_vars[gNB_id]->dl_ch_magb0,
+                                pdsch_vars[gNB_id]->dl_ch_magr0,
+                                pdsch_vars[gNB_id]->rxdataF_comp0,
+                                NULL,//NULL:disable meas. pdsch_vars[gNB_id]->rho:enable meas.
+                                frame_parms,
+                                nl,
+                                symbol,
+                                nb_re_pdsch,
+                                first_symbol_flag,
+                                dlsch0_harq->Qm,
+                                nb_rb_pdsch,
+                                pdsch_vars[gNB_id]->log2_maxh,
+                                measurements); // log2_maxh+I0_shift
     stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
     if (cpumeas(CPUMEAS_GETSTATE))
       LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp  %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 
     start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
 
-  if (frame_parms->nb_antennas_rx > 1) {
-    if (dlsch0_harq->mimo_mode<NR_DUALSTREAM) {
-      nr_dlsch_detection_mrc(pdsch_vars[gNB_id]->rxdataF_comp0,
-                             (n_tx>1)? pdsch_vars[gNB_id]->rho : NULL,
-                             pdsch_vars[gNB_id]->dl_ch_mag0,
-                             pdsch_vars[gNB_id]->dl_ch_magb0,
-                             pdsch_vars[gNB_id]->dl_ch_magr0,
-                             n_tx,
-                             n_rx,
-                             symbol,
-                             nb_rb_pdsch,
-                             len);
-      if (n_tx == 2)//Apply zero forcing for 2 Tx layers
-        nr_zero_forcing_rx_2layers(pdsch_vars[gNB_id]->rxdataF_comp0,
-                                   pdsch_vars[gNB_id]->dl_ch_mag0,
-                                   pdsch_vars[gNB_id]->dl_ch_magb0,
-                                   pdsch_vars[gNB_id]->dl_ch_magr0,
-                                   pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                   nb_rb_pdsch,
-                                   n_rx,
-                                   dlsch0_harq->Qm,
-                                   pdsch_vars[gNB_id]->log2_maxh,
-                                   symbol,
-                                   len);
-    }
-    else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
-      nr_dlsch_detection_mrc_core(pdsch_vars[gNB_id]->rxdataF_comp0,
-                                  NULL,
-                                  pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                  pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                                  pdsch_vars[gNB_id]->dl_ch_mag0,
-                                  pdsch_vars[gNB_id]->dl_ch_magb0,
-                                  NULL,
-                                  NULL,
-                                  n_tx,
-                                  n_rx,
-                                  2*len,
-                                  0);
-    }
+  if (n_rx > 1) {
+    nr_dlsch_detection_mrc(pdsch_vars[gNB_id]->rxdataF_comp0,
+                           (nl>1)? pdsch_vars[gNB_id]->rho : NULL,
+                           pdsch_vars[gNB_id]->dl_ch_mag0,
+                           pdsch_vars[gNB_id]->dl_ch_magb0,
+                           pdsch_vars[gNB_id]->dl_ch_magr0,
+                           nl,
+                           n_rx,
+                           symbol,
+                           nb_rb_pdsch,
+                           nb_re_pdsch);
+    if (nl >= 2)//Apply zero forcing for 2, 3, and 4 Tx layers
+      nr_zero_forcing_rx(pdsch_vars[gNB_id]->rxdataF_comp0,
+                                 pdsch_vars[gNB_id]->dl_ch_mag0,
+                                 pdsch_vars[gNB_id]->dl_ch_magb0,
+                                 pdsch_vars[gNB_id]->dl_ch_magr0,
+                                 pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+                                 nb_rb_pdsch,
+                                 n_rx,
+                                 nl,
+                                 dlsch0_harq->Qm,
+                                 pdsch_vars[gNB_id]->log2_maxh,
+                                 symbol,
+                                 nb_re_pdsch);
   }
+  stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
+
   //printf("start compute LLR\n");
-  if (dlsch0_harq->mimo_mode == NR_DUALSTREAM)  {
-    rxdataF_comp_ptr = pdsch_vars[gNB_id]->rxdataF_comp1[harq_pid][round];
-    dl_ch_mag_ptr = pdsch_vars[gNB_id]->dl_ch_mag1[harq_pid][round];
-  }
-  else {
-    rxdataF_comp_ptr = pdsch_vars[gNB_id_i]->rxdataF_comp0;
-    dl_ch_mag_ptr = pdsch_vars[gNB_id_i]->dl_ch_mag0;
-    //i_mod should have been passed as a parameter
-  }
+  rxdataF_comp_ptr = pdsch_vars[gNB_id_i]->rxdataF_comp0;
+  dl_ch_mag_ptr = pdsch_vars[gNB_id_i]->dl_ch_mag0;
   
-    stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
-    if (cpumeas(CPUMEAS_GETSTATE))
-      LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine  %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
+  if (cpumeas(CPUMEAS_GETSTATE))
+    LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
 
     start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
   /* Store the valid DL RE's */
-    pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = len;
+    pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch;
 
     if(dlsch0_harq->status == ACTIVE) {
       startSymbIdx = dlsch0_harq->start_symbol;
@@ -590,7 +500,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                gNB_id,
                                nr_slot_rx,
                                symbol,
-                               (nb_rb*12),
+                               (nb_rb_pdsch*12),
                                dlsch[0]->rnti,rx_type);
       pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
     }
@@ -612,7 +522,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                      rx_type, harq_pid,
                      gNB_id, gNB_id_i,
                      first_symbol_flag,
-                     i, nb_rb, round,
+                     i, nb_rb_pdsch, round,
                      codeword_TB0, codeword_TB1,
                      pdsch_vars[gNB_id]->dl_valid_re[i-1],
                      nr_slot_rx, beamforming_mode);
@@ -668,14 +578,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
 /*
   for (int i=0; i < 2; i++){
     snprintf(filename, 50,  "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx);
-    write_output(filename,"llr",  &pdsch_vars[gNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm), 1, 0);
+    write_output(filename,"llr",  &pdsch_vars[gNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0);
   }
 */
 #endif
 
 #if T_TRACER
   T(T_UE_PHY_PDSCH_IQ, T_INT(gNB_id), T_INT(ue->Mod_id), T_INT(frame%1024),
-    T_INT(nr_slot_rx), T_INT(nb_rb),
+    T_INT(nr_slot_rx), T_INT(nb_rb_pdsch),
     T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_slot),
     T_BUFFER(&pdsch_vars[gNB_id]->rxdataF_comp0[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_slot*2));
 #endif
@@ -931,16 +841,16 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
     //rho[aarx][nb_aatx*nb_aatx] = [cov(H_aarx_0,H_aarx_0) cov(H_aarx_0,H_aarx_1)
     //                              cov(H_aarx_1,H_aarx_0) cov(H_aarx_1,H_aarx_1)], aarx=0,...,nb_antennas_rx-1
 
-    int avg_rho_re[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
-    int avg_rho_im[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
+    //int avg_rho_re[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
+    //int avg_rho_im[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
 
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
       for (aatx=0; aatx<nb_aatx; aatx++) {
 
         for (atx=0; atx<nb_aatx; atx++) {
-          avg_rho_re[aarx][aatx*nb_aatx+atx] = 0;
-          avg_rho_im[aarx][aatx*nb_aatx+atx] = 0;
+          //avg_rho_re[aarx][aatx*nb_aatx+atx] = 0;
+          //avg_rho_im[aarx][aatx*nb_aatx+atx] = 0;
           rho128        = (__m128i *)&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12];
           dl_ch128      = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
           dl_ch128_2    = (__m128i *)&dl_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
@@ -969,15 +879,14 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
             //print_shorts("ch:",dl_ch128);
             //print_shorts("pack:",rho128);
 
-            avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[0])[0]+
+            /*avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[0])[0]+
               ((int16_t*)&rho128[0])[2] +
               ((int16_t*)&rho128[0])[4] +
-              ((int16_t*)&rho128[0])[6])/16;//
-
-            avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[0])[1]+
+              ((int16_t*)&rho128[0])[6])/16;*/
+            /*avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[0])[1]+
               ((int16_t*)&rho128[0])[3] +
               ((int16_t*)&rho128[0])[5] +
-              ((int16_t*)&rho128[0])[7])/16;//
+              ((int16_t*)&rho128[0])[7])/16;*/
 
             // multiply by conjugated channel
             mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]);
@@ -997,15 +906,14 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
             //print_shorts("pack:",rho128+1);
 
             // multiply by conjugated channel
-            avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[1])[0]+
+            /*avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[1])[0]+
               ((int16_t*)&rho128[1])[2] +
               ((int16_t*)&rho128[1])[4] +
-              ((int16_t*)&rho128[1])[6])/16;
-
-            avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[1])[1]+
+              ((int16_t*)&rho128[1])[6])/16;*/
+            /*avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[1])[1]+
               ((int16_t*)&rho128[1])[3] +
               ((int16_t*)&rho128[1])[5] +
-              ((int16_t*)&rho128[1])[7])/16;
+              ((int16_t*)&rho128[1])[7])/16;*/
 
             mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]);
             // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
@@ -1023,25 +931,28 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
             //print_shorts("rx:",dl_ch128_2+2);
             //print_shorts("ch:",dl_ch128+2);
             //print_shorts("pack:",rho128+2);
-            avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[0]+
+
+            /*avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[0]+
               ((int16_t*)&rho128[2])[2] +
               ((int16_t*)&rho128[2])[4] +
-              ((int16_t*)&rho128[2])[6])/16;
-
-            avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[1]+
+              ((int16_t*)&rho128[2])[6])/16;*/
+            /*avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[1]+
               ((int16_t*)&rho128[2])[3] +
               ((int16_t*)&rho128[2])[5] +
-              ((int16_t*)&rho128[2])[7])/16;
+              ((int16_t*)&rho128[2])[7])/16;*/
 
             dl_ch128+=3;
             dl_ch128_2+=3;
             rho128+=3;
           }
           if (first_symbol_flag==1) {
-            //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],rb*12);
-            avg_rho_re[aarx][aatx*nb_aatx+atx] = 16*avg_rho_re[aarx][aatx*nb_aatx+atx]/(nb_rb*12);
-            avg_rho_im[aarx][aatx*nb_aatx+atx] = 16*avg_rho_im[aarx][aatx*nb_aatx+atx]/(nb_rb*12);
+            //rho_nm = H_arx_n.conj(H_arx_m)
+            //rho_rx_corr[arx][nm] = |H_arx_n|^2.|H_arx_m|^2 &rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12]
+            measurements->rx_correlation[0][aarx][aatx*nb_aatx+atx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],length);
+            //avg_rho_re[aarx][aatx*nb_aatx+atx] = 16*avg_rho_re[aarx][aatx*nb_aatx+atx]/length;
+            //avg_rho_im[aarx][aatx*nb_aatx+atx] = 16*avg_rho_im[aarx][aatx*nb_aatx+atx]/length;
             //printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]);
+            //printf("rho_corr[rx]%d tx%d tx%d = %d ...\n",aarx, aatx,atx, measurements->rx_correlation[0][aarx][aatx*nb_aatx+atx]);
           }
         }
       }
@@ -1694,294 +1605,6 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
 
 }
 
-static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
-                                        int **dl_ch_estimates_ext_i,
-                                        int **dl_ch_rho_ext,
-                                        unsigned char n_tx,
-                                        unsigned char n_rx,
-                                        unsigned char output_shift,
-                                        int length,
-                                        int start_point)
-{
-#if defined(__x86_64__)||defined(__i386__)
-
-  __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
-  unsigned char aarx;
-  int ii, length2, length_mod8;
-
-
-  for (aarx=0; aarx<n_rx; aarx++) {
-
-    dl_ch128          = (__m128i *)&dl_ch_estimates_ext[aarx][start_point];
-
-    if (dl_ch_estimates_ext_i == NULL)
-      dl_ch128i         = (__m128i *)&dl_ch_estimates_ext[aarx + n_rx][start_point];
-    else
-      dl_ch128i         = (__m128i *)&dl_ch_estimates_ext_i[aarx][start_point];
-
-    dl_ch_rho128      = (__m128i *)&dl_ch_rho_ext[aarx][start_point];
-
-    length_mod8 = length&7;
-
-    if (length_mod8 == 0){
-      length2 = length>>3;
-
-      for (ii=0; ii<length2; ++ii) {
-      // multiply by conjugated channel
-        mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]);
-        //      print_ints("re",&mmtmpD0);
-        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
-        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
-        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[0]);
-        //      print_ints("im",&mmtmpD1);
-        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
-        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-        //      print_ints("re(shift)",&mmtmpD0);
-        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
-        //      print_ints("im(shift)",&mmtmpD1);
-        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
-        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
-        //      print_ints("c0",&mmtmpD2);
-        //      print_ints("c1",&mmtmpD3);
-        dl_ch_rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-      // print_shorts("rho 0:",dl_ch_rho128);
-        // multiply by conjugated channel
-        mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]);
-        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
-        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
-        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
-        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[1]);
-        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
-        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
-        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
-        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
-        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
-        dl_ch_rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);
-
-        dl_ch128+=2;
-        dl_ch128i+=2;
-        dl_ch_rho128+=2;
-      }
-
-    }else {
-        printf ("Channel Correlarion: Received number of subcarriers is not multiple of 8, \n"
-                 "need to adapt the code!\n");
-      }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-#elif defined(__arm__)
-
-#endif
-}
-
-void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
-                              int **rxdataF_comp_i,
-                              int **rho,
-                              int **rho_i,
-                              int **dl_ch_mag,
-                              int **dl_ch_magb,
-                              int **dl_ch_mag_i,
-                              int **dl_ch_magb_i,
-                              unsigned char n_tx,
-                              unsigned char n_rx,
-                              int length,
-                              int start_point)
-{
-
-#if defined(__x86_64__)||defined(__i386__)
-
-  unsigned char aatx;
-  int i;
-  __m128i *rxdataF_comp128_0, *rxdataF_comp128_1, *rxdataF_comp128_2, *rxdataF_comp128_3;
-  __m128i *dl_ch_mag128_0, *dl_ch_mag128_1, *dl_ch_mag128_2, *dl_ch_mag128_3;
-  __m128i *dl_ch_mag128_0b, *dl_ch_mag128_1b,  *dl_ch_mag128_2b,  *dl_ch_mag128_3b;
-  __m128i *rho128_0, *rho128_1, *rho128_2=NULL, *rho128_3=NULL;
-  __m128i *rho128_i0, *rho128_i1, *rho128_i2=NULL, *rho128_i3=NULL;
-  int length_mod4 = 0;
-  int length2;
-
-  if (n_rx>1) {
-
-    for (aatx=0; aatx<n_tx; aatx++) {
-
-      rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][start_point];
-      rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][start_point];
-      dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[(aatx<<1)][start_point];
-      dl_ch_mag128_1      = (__m128i *)&dl_ch_mag[(aatx<<1)+1][start_point];
-      dl_ch_mag128_0b     = (__m128i *)&dl_ch_magb[(aatx<<1)][start_point];
-      dl_ch_mag128_1b     = (__m128i *)&dl_ch_magb[(aatx<<1)+1][start_point];
-
-      if (length_mod4 == 0){
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++i) {
-          rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
-          dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1));
-          dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1));
-        }
-      }
-    }
-
-
-    if (rho) {
-      rho128_0 = (__m128i *) &rho[0][start_point];
-      rho128_1 = (__m128i *) &rho[1][start_point];
-
-      if (n_tx == 4){
-        rho128_2 = (__m128i *) &rho[2][start_point];
-        rho128_3 = (__m128i *) &rho[3][start_point];
-      }
-        if (length_mod4 == 0){
-          length2 = length>>2;
-
-          for (i=0; i<length2; ++i) {
-            rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
-          if (n_tx == 4){
-            rho128_2[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_2[i],1),_mm_srai_epi16(rho128_3[i],1));
-          }
-        }
-      }
-    }
-
-    if (rho_i){
-      rho128_i0 = (__m128i *) &rho_i[0][start_point];
-      rho128_i1 = (__m128i *) &rho_i[1][start_point];
-      if (n_tx == 4){
-        rho128_i2 = (__m128i *) &rho_i[2][start_point];
-        rho128_i3 = (__m128i *) &rho_i[3][start_point];
-      }
-      if (length_mod4 == 0){
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++i){
-          rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
-          if (n_tx == 4){
-            rho128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i2[i],1),_mm_srai_epi16(rho128_i3[i],1));
-          }
-        }
-      }
-    }
-
-      if (n_tx == 4){
-
-      rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][start_point];
-      rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[2][start_point];
-      rxdataF_comp128_2 = (__m128i *)&rxdataF_comp[4][start_point];
-      rxdataF_comp128_3 = (__m128i *)&rxdataF_comp[6][start_point];
-
-      dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][start_point];
-      dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[2][start_point];
-      dl_ch_mag128_2 = (__m128i *)&dl_ch_mag[4][start_point];
-      dl_ch_mag128_3 = (__m128i *)&dl_ch_mag[6][start_point];
-
-      dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[0][start_point];
-      dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[2][start_point];
-      dl_ch_mag128_2b = (__m128i *)&dl_ch_magb[4][start_point];
-      dl_ch_mag128_3b = (__m128i *)&dl_ch_magb[6][start_point];
-
-      rho128_0 = (__m128i *)&rho[0][start_point];
-      rho128_1 = (__m128i *)&rho[2][start_point];
-
-      rho128_i0 = (__m128i *)&rho_i[0][start_point];
-      rho128_i1 = (__m128i *)&rho_i[2][start_point];
-
-
-      if (length_mod4 == 0){
-
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++i) {
-          rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
-          rxdataF_comp128_2[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_2[i],1),_mm_srai_epi16(rxdataF_comp128_3[i],1));
-
-          dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1));
-          dl_ch_mag128_2[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_2[i],1),_mm_srai_epi16(dl_ch_mag128_3[i],1));
-
-          dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1));
-          dl_ch_mag128_2b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_2b[i],1),_mm_srai_epi16(dl_ch_mag128_3b[i],1));
-
-          rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
-
-          rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
-        }
-    }
-  }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-#elif defined(__arm__)
-
-  unsigned char aatx;
-  int i;
-  int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
-  int length_mod4 = 0;
-  int length2;
-  int ii=0;
-
-  if (n_rx>1) {
-
-    for (aatx=0; aatx<n_tx; aatx++) {
-
-      rxdataF_comp128_0   = (int16x8_t *)&rxdataF_comp[(aatx<<1)][start_point];
-      rxdataF_comp128_1   = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][start_point];
-      dl_ch_mag128_0      = (int16x8_t *)&dl_ch_mag[(aatx<<1)][start_point];
-      dl_ch_mag128_1      = (int16x8_t *)&dl_ch_mag[(aatx<<1)+1][start_point];
-      dl_ch_mag128_0b     = (int16x8_t *)&dl_ch_magb[(aatx<<1)][start_point];
-      dl_ch_mag128_1b     = (int16x8_t *)&dl_ch_magb[(aatx<<1)+1][start_point];
-
-      if (length_mod4 == 0){
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++ii) {
-          rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
-          dl_ch_mag128_0[i]    = vhaddq_s16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]);
-          dl_ch_mag128_0b[i]   = vhaddq_s16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]);
-        }
-      }
-
-    if (rho) {
-      rho128_0 = (int16x8_t *) &rho[0][start_point];
-      rho128_1 = (int16x8_t *) &rho[1][start_point];
-
-      if (length_mod4 == 0){
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++i) {
-          rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]);
-        }
-      }
-    }
-
-    if (rho_i){
-
-      rho128_i0 = (__m128i *) &rho_i[0][start_point];
-      rho128_i1 = (__m128i *) &rho_i[1][start_point];
-
-      if (length_mod4 == 0){
-        length2 = length>>2;
-
-        for (i=0; i<length2; ++i)
-          rho128_i0[i] = vhaddq_s16(rho128_i0[i],rho128_i1[i]);
-
-      }
-    }
-  }
-
-  }
-
-#endif
-}
-
 //==============================================================================================
 // Extraction functions
 //==============================================================================================
@@ -2083,19 +1706,19 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
   return nb_rb_pdsch;
 }
 
-unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
-                                             int **dl_ch_estimates,
-                                             int **rxdataF_ext,
-                                             int **dl_ch_estimates_ext,
-                                             unsigned char symbol,
-                                             uint8_t pilots,
-                                             uint8_t config_type,
-                                             unsigned short start_rb,
-                                             unsigned short nb_rb_pdsch,
-                                             uint8_t n_dmrs_cdm_groups,
-                                             uint8_t Nl,
-                                             NR_DL_FRAME_PARMS *frame_parms,
-                                             uint16_t dlDmrsSymbPos)
+void nr_dlsch_extract_rbs(int **rxdataF,
+                          int **dl_ch_estimates,
+                          int **rxdataF_ext,
+                          int **dl_ch_estimates_ext,
+                          unsigned char symbol,
+                          uint8_t pilots,
+                          uint8_t config_type,
+                          unsigned short start_rb,
+                          unsigned short nb_rb_pdsch,
+                          uint8_t n_dmrs_cdm_groups,
+                          uint8_t Nl,
+                          NR_DL_FRAME_PARMS *frame_parms,
+                          uint16_t dlDmrsSymbPos)
 {
 
   unsigned short k,rb;
@@ -2180,7 +1803,6 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
       }//rb
     }//aatx
   }//aarx
-  return(nb_rb_pdsch);
 }
 
 void nr_dlsch_detection_mrc(int **rxdataF_comp,
@@ -2247,108 +1869,351 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp,
 #endif
 }
 
-/* Zero Forcing Rx function: nr_det_HhH()
+/* Zero Forcing Rx function: nr_a_sum_b()
+ * Compute the complex addition x=x+y
  *
+ * */
+void nr_a_sum_b(__m128i *input_x,
+                __m128i *input_y,
+                unsigned short nb_rb)
+{
+  unsigned short rb;
+
+  for (rb=0; rb<nb_rb; rb++) {
+
+    input_x[0] = _mm_adds_epi16(input_x[0],input_y[0]);
+    input_x[1] = _mm_adds_epi16(input_x[1],input_y[1]);
+    input_x[2] = _mm_adds_epi16(input_x[2],input_y[2]);
+
+    input_x+=3;
+    input_y+=3;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+/* Zero Forcing Rx function: nr_a_mult_b()
+ * Compute the complex Multiplication c=a*b
  *
  * */
-void nr_det_HhH(int32_t *after_mf_00,//a
-                int32_t *after_mf_01,//b
-                int32_t *after_mf_10,//c
-                int32_t *after_mf_11,//d
-                int32_t *det_fin,//1/ad-bc
-                unsigned short nb_rb,
-                unsigned char symbol,
-                int32_t shift)
+void nr_a_mult_b(int *a,
+                 int *b,
+                 int32_t *c,
+                 unsigned short nb_rb,
+                 unsigned char output_shift0)
 {
-  int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
+  //This function is used to compute complex multiplications
+  short nr_conjugate[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
   unsigned short rb;
-  __m128i *after_mf_00_128,*after_mf_01_128, *after_mf_10_128, *after_mf_11_128, ad_re_128, bc_re_128; //ad_im_128, bc_im_128;
-  __m128i *det_fin_128, det_re_128; //det_im_128, tmp_det0, tmp_det1;
+  __m128i *a_128,*b_128, *c_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
 
-  after_mf_00_128 = (__m128i *)after_mf_00;
-  after_mf_01_128 = (__m128i *)after_mf_01;
-  after_mf_10_128 = (__m128i *)after_mf_10;
-  after_mf_11_128 = (__m128i *)after_mf_11;
+  a_128 = (__m128i *)a;
+  b_128 = (__m128i *)b;
 
-  det_fin_128 = (__m128i *)det_fin;
+  c_128 = (__m128i *)c;
 
   for (rb=0; rb<3*nb_rb; rb++) {
+    // the real part
+    mmtmpD0 = _mm_sign_epi16(a_128[0],*(__m128i*)&nr_conjugate[0]);
+    mmtmpD0 = _mm_madd_epi16(mmtmpD0,b_128[0]); //Re: (a_re*b_re - a_im*b_im)
+
+    // the imag part
+    mmtmpD1 = _mm_shufflelo_epi16(a_128[0],_MM_SHUFFLE(2,3,0,1));
+    mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+    mmtmpD1 = _mm_madd_epi16(mmtmpD1,b_128[0]);//Im: (x_im*y_re + x_re*y_im)
+
+    mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
+    mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
+    mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+    mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
 
-    //complex multiplication (I_a+jQ_a)(I_d+jQ_d) = (I_aI_d - Q_aQ_d) + j(Q_aI_d + I_aQ_d)
-    //The imag part is often zero, we compute only the real part
-    ad_re_128 = _mm_sign_epi16(after_mf_00_128[0],*(__m128i*)&nr_conjug2[0]);
-    ad_re_128 = _mm_madd_epi16(ad_re_128,after_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1
-    //ad_im_128 = _mm_shufflelo_epi16(after_mf_00_128[0],_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-    //ad_im_128 = _mm_shufflehi_epi16(ad_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-    //ad_im_128 = _mm_madd_epi16(ad_im_128,after_mf_11_128[0]);//Im: (Q_aI_d + I_aQ_d)
+    c_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+
+    /*printf("\n Computing mult \n");
+    print_shorts("a:",(int16_t*)&a_128[0]);
+    print_shorts("b:",(int16_t*)&b_128[0]);
+    print_shorts("pack:",(int16_t*)&c_128[0]);*/
+
+    a_128+=1;
+    b_128+=1;
+    c_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
 
-    //complex multiplication (I_b+jQ_b)(I_c+jQ_c) = (I_bI_c - Q_bQ_c) + j(Q_bI_c + I_bQ_c)
-    //The imag part is often zero, we compute only the real part
-    bc_re_128 = _mm_sign_epi16(after_mf_01_128[0],*(__m128i*)&nr_conjug2[0]);
-    bc_re_128 = _mm_madd_epi16(bc_re_128,after_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1
-    //bc_im_128 = _mm_shufflelo_epi16(after_mf_01_128[0],_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_b0 Q_b1 I_b2 Q_b3]_64bits to [Q_b1 I_b0 Q_b3 I_b2]_64bits
-    //bc_im_128 = _mm_shufflehi_epi16(bc_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_b0 Q_b1 I_b2 Q_b3]_64bits to [Q_b1 I_b0 Q_b3 I_b2]_64bits
-    //bc_im_128 = _mm_madd_epi16(bc_im_128,after_mf_10_128[0]);//Im: (Q_bI_c + I_bQ_c)
+/* Zero Forcing Rx function: nr_element_sign()
+ * Compute b=sign*a
+ *
+ * */
+void nr_element_sign(int32_t *a,//a
+                     int32_t *b,//b
+                     unsigned short nb_rb,
+                     int32_t sign)
+{
+  int16_t nr_sign[8]__attribute__((aligned(16))) = {-1,-1,-1,-1,-1,-1,-1,-1} ;
+  unsigned short rb;
+  __m128i *a_128,*b_128;
 
-    det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128);
-    //det_im_128 = _mm_sub_epi32(ad_im_128, bc_im_128);
+  a_128 = (__m128i *)a;
+  b_128 = (__m128i *)b;
 
-    //det in Q30 format
-    det_fin_128[0] = _mm_abs_epi32(det_re_128);
+  for (rb=0; rb<3*nb_rb; rb++) {
 
+    if (sign < 0)
+      b_128[0] = _mm_sign_epi16(a_128[0],*(__m128i*)&nr_sign[0]);
+    else
+      b_128[0] = a_128[0];
 
 #ifdef DEBUG_DLSCH_DEMOD
-     printf("\n Computing det_HhH_inv \n");
+     printf("\n Out \n");
      //print_ints("det_re_128:",(int32_t*)&det_re_128);
      //print_ints("det_im_128:",(int32_t*)&det_im_128);
-     print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]);
+     print_shorts("b:",(int32_t*)&b_128[0]);
 #endif
-    det_fin_128+=1;
-    after_mf_00_128+=1;
-    after_mf_01_128+=1;
-    after_mf_10_128+=1;
-    after_mf_11_128+=1;
+    a_128+=1;
+    b_128+=1;
   }
   _mm_empty();
   _m_empty();
 }
 
-/* Zero Forcing Rx function: nr_inv_comp_muli
- * Complex number multi: z = x*y
- *                         = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im)
+/* Zero Forcing Rx function: nr_det_4x4()
+ * Compute the matrix determinant for 4x4 Matrix
+ *
  * */
-__m128i nr_inv_comp_muli(__m128i input_x,
-                         __m128i input_y)
-{
-  int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
-
-  __m128i xy_re_128, xy_im_128;
-  __m128i output_z, tmp_z0, tmp_z1;
+void nr_determin(int32_t **a44,//
+                 int32_t *ad_bc,//ad-bc
+                 int32_t size,
+                 unsigned short nb_rb,
+                 int32_t sign,
+                 int32_t shift0){
+
+  int32_t outtemp[12*nb_rb] __attribute__((aligned(32)));
+  int32_t outtemp1[12*nb_rb] __attribute__((aligned(32)));
+  int32_t **sub_matrix;
+  sub_matrix = (int32_t **)malloc16_clear( (size-1)*(size-1)*sizeof(int32_t *) );
+  for (int rtx=0;rtx<(size-1);rtx++) {//row
+    for (int ctx=0;ctx<(size-1);ctx++) {//column
+      sub_matrix[ctx*(size-1)+rtx] = (int32_t *)malloc16_clear( 12*nb_rb*sizeof(int32_t) );
+    }
+  }
+  int16_t k,rr[size-1],cc[size-1];
 
-  // complex multiplication (x_re + jx_im)*(y_re + jy_im) = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im)
+  if(size==1) {
+    nr_element_sign(a44[0],//a
+                    ad_bc,//b
+                    nb_rb,
+                    sign);
+  } else {
 
-  // the real part
-  xy_re_128 = _mm_sign_epi16(input_x,*(__m128i*)&nr_conjug2[0]);
-  xy_re_128 = _mm_madd_epi16(xy_re_128,input_y); //Re: (x_re*y_re - x_im*y_im)
+    for (int rtx=0;rtx<size;rtx++) {//row calculation for determin
+      int ctx=0;
+      //find the submatrix row and column indices
+      k=0;
+      for(int rrtx=0;rrtx<size;rrtx++)
+        if(rrtx != rtx) rr[k++] = rrtx;
+      k=0;
+      for(int cctx=0;cctx<size;cctx++)
+        if(cctx != ctx) cc[k++] = cctx;
+      //fill out the sub matrix corresponds to this element
+       for (int ridx=0;ridx<(size-1);ridx++)
+         for (int cidx=0;cidx<(size-1);cidx++)
+           sub_matrix[cidx*(size-1)+ridx]= (int32_t *)&a44[cc[cidx]*size+rr[ridx]][0];
+
+       nr_determin(sub_matrix,//a33
+                   outtemp,
+                   size-1,
+                   nb_rb,
+                   ((rtx&1)==1?-1:1)*((ctx&1)==1?-1:1)*sign,
+                   shift0);
+       nr_a_mult_b(a44[ctx*size+rtx],
+                   outtemp,
+                   rtx==0? ad_bc:outtemp1,
+                   nb_rb,
+                   shift0);
+
+       if (rtx != 0)
+         nr_a_sum_b((__m128i *)ad_bc,
+                    (__m128i *)outtemp1,
+                    nb_rb);
+    }
+  }
+  _mm_empty();
+  _m_empty();
+}
 
-  // the imag part
-  xy_im_128 = _mm_shufflelo_epi16(input_x,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  xy_im_128 = _mm_shufflehi_epi16(xy_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  xy_im_128 = _mm_madd_epi16(xy_im_128,input_y);//Im: (x_im*y_re + x_re*y_im)
+double complex nr_determin_cpx(double complex *a44_cpx,//
+                               int32_t size,//size
+                               int32_t sign){
+  double complex outtemp, outtemp1;
+  //Allocate the submatrix elements
+  double complex sub_matrix[(size-1)*(size-1)];
+  int16_t k,rr[size-1],cc[size-1];
+
+  if(size==1) {
+    return((double complex)a44_cpx[0]*sign);
+  }else {
+    outtemp1 = 0;
+    for (int rtx=0;rtx<size;rtx++) {//row calculation for determin
+      int ctx=0;
+      //find the submatrix row and column indices
+      k=0;
+      for(int rrtx=0;rrtx<size;rrtx++)
+        if(rrtx != rtx) rr[k++] = rrtx;
+      k=0;
+      for(int cctx=0;cctx<size;cctx++)
+        if(cctx != ctx) cc[k++] = cctx;
+      //fill out the sub matrix corresponds to this element
+       for (int ridx=0;ridx<(size-1);ridx++)
+         for (int cidx=0;cidx<(size-1);cidx++)
+           sub_matrix[cidx*(size-1)+ridx]= a44_cpx[cc[cidx]*size+rr[ridx]];
+
+       outtemp = nr_determin_cpx(sub_matrix,//a33
+                             size-1,
+                             ((rtx&1)==1?-1:1)*((ctx&1)==1?-1:1)*sign);
+       outtemp1 += a44_cpx[ctx*size+rtx]*outtemp;
+    }
 
-  //convert back to Q15 before packing
-  xy_re_128 = _mm_srai_epi32(xy_re_128,4);//(2^15/64*2*16)
-  xy_im_128 = _mm_srai_epi32(xy_im_128,4);
+    return((double complex)outtemp1);
+  }
+}
 
-  tmp_z0  = _mm_unpacklo_epi32(xy_re_128,xy_im_128);
-  //print_ints("unpack lo:",&tmp_z0[0]);
-  tmp_z1  = _mm_unpackhi_epi32(xy_re_128,xy_im_128);
-  //print_ints("unpack hi:",&tmp_z1[0]);
-  output_z = _mm_packs_epi32(tmp_z0,tmp_z1);
+/* Zero Forcing Rx function: nr_matrix_inverse()
+ * Compute the matrix inverse and determinant up to 4x4 Matrix
+ *
+ * */
+uint8_t nr_matrix_inverse(int32_t **a44,//Input matrix//conjH_H_elements[0]
+                          int32_t **inv_H_h_H,//Inverse
+                          int32_t *ad_bc,//determin
+                          int32_t size,
+                          unsigned short nb_rb,
+                          int32_t flag,//fixed point or floating flag
+                          int32_t shift0){
+
+  int16_t k,rr[size-1],cc[size-1];
+
+  if(flag) {//fixed point SIMD calc.
+    //Allocate the submatrix elements
+    int32_t **sub_matrix;
+    sub_matrix = (int32_t **)malloc16_clear( (size-1)*(size-1)*sizeof(int32_t *) );
+    for (int rtx=0;rtx<(size-1);rtx++) {//row
+      for (int ctx=0;ctx<(size-1);ctx++) {//column
+        sub_matrix[ctx*(size-1)+rtx] = (int32_t *)malloc16_clear( 12*nb_rb*sizeof(int32_t) );
+      }
+    }
 
-  _mm_empty();
-  _m_empty();
-  return(output_z);
+    //Compute Matrix determinant
+    nr_determin(a44,//
+                ad_bc,//determinant
+                size,//size
+                nb_rb,
+                +1,
+                shift0);
+    //print_shorts("nr_det_",(int16_t*)&ad_bc[0]);
+
+    //Compute Inversion of the H^*H matrix
+    /* For 2x2 MIMO matrix, we compute
+     * *        |(conj_H_00xH_00+conj_H_10xH_10)   (conj_H_00xH_01+conj_H_10xH_11)|
+     * * H_h_H= |                                                                 |
+     * *        |(conj_H_01xH_00+conj_H_11xH_10)   (conj_H_01xH_01+conj_H_11xH_11)|
+     * *
+     * *inv(H_h_H) =(1/det)*[d  -b
+     * *                     -c  a]
+     * **************************************************************************/
+    for (int rtx=0;rtx<size;rtx++) {//row
+      k=0;
+      for(int rrtx=0;rrtx<size;rrtx++)
+        if(rrtx != rtx) rr[k++] = rrtx;
+      for (int ctx=0;ctx<size;ctx++) {//column
+        k=0;
+        for(int cctx=0;cctx<size;cctx++)
+          if(cctx != ctx) cc[k++] = cctx;
+
+        //fill out the sub matrix corresponds to this element
+        for (int ridx=0;ridx<(size-1);ridx++)
+          for (int cidx=0;cidx<(size-1);cidx++)
+            sub_matrix[cidx*(size-1)+ridx]= (int32_t *)&a44[cc[cidx]*size+rr[ridx]][0];
+
+        nr_determin(sub_matrix,
+                    inv_H_h_H[rtx*size+ctx],//out transpose
+                    size-1,//size
+                    nb_rb,
+                    ((rtx&1)==1?-1:1)*((ctx&1)==1?-1:1),
+                    shift0);
+        //printf("H_h_H(r%d,c%d)=%d+j%d --> inv_H_h_H(%d,%d) = %d+j%d \n",rtx,ctx,((short *)a44[ctx*size+rtx])[0],((short *)a44[ctx*size+rtx])[1],ctx,rtx,((short *)inv_H_h_H[rtx*size+ctx])[0],((short *)inv_H_h_H[rtx*size+ctx])[1]);
+      }
+    }
+    _mm_empty();
+    _m_empty();
+  }
+  else {//floating point calc.
+    //Allocate the submatrix elements
+    double complex sub_matrix_cpx[(size-1)*(size-1)];
+    //Convert the IQ samples (in Q15 format) to float complex
+    double complex a44_cpx[size*size];
+    double complex inv_H_h_H_cpx[size*size];
+    double complex determin_cpx;
+    for (int i=0; i<12*nb_rb; i++) {
+
+      //Convert Q15 to floating point
+      for (int rtx=0;rtx<size;rtx++) {//row
+        for (int ctx=0;ctx<size;ctx++) {//column
+          a44_cpx[ctx*size+rtx]= ((double)((short *)a44[ctx*size+rtx])[(i<<1)])/(1<<(shift0-1)) + I*((double)((short *)a44[ctx*size+rtx])[(i<<1)+1])/(1<<(shift0-1));
+          //if (i<4) printf("a44_cpx(%d,%d)= ((FP %d))%lf+(FP %d)j%lf \n",ctx,rtx,((short *)a44[ctx*size+rtx])[(i<<1)],creal(a44_cpx[ctx*size+rtx]),((short *)a44[ctx*size+rtx])[(i<<1)+1],cimag(a44_cpx[ctx*size+rtx]));
+        }
+      }
+      //Compute Matrix determinant (copy real value only)
+      determin_cpx = nr_determin_cpx(a44_cpx,//
+                                     size,//size
+                                     +1);
+      //if (i<4) printf("order %d nr_det_cpx = %lf+j%lf \n",log2_approx(creal(determin_cpx)),creal(determin_cpx),cimag(determin_cpx));
+
+      //Round and convert to Q15 (Out in the same format as Fixed point).
+      if (creal(determin_cpx)>0) {//determin of the symmetric matrix is real part only
+        ((short*) ad_bc)[i<<1] = (short) ((creal(determin_cpx)*(1<<(shift0)))+0.5);//
+        //((short*) ad_bc)[(i<<1)+1] = (short) ((cimag(determin_cpx)*(1<<(shift0)))+0.5);//
+      } else {
+        ((short*) ad_bc)[i<<1] = (short) ((creal(determin_cpx)*(1<<(shift0)))-0.5);//
+        //((short*) ad_bc)[(i<<1)+1] = (short) ((cimag(determin_cpx)*(1<<(shift0)))-0.5);//
+      }
+      //if (i<4) printf("nr_det_FP= %d+j%d \n",((short*) ad_bc)[i<<1],((short*) ad_bc)[(i<<1)+1]);
+      //Compute Inversion of the H^*H matrix (normalized output divide by determinant)
+      for (int rtx=0;rtx<size;rtx++) {//row
+        k=0;
+        for(int rrtx=0;rrtx<size;rrtx++)
+          if(rrtx != rtx) rr[k++] = rrtx;
+        for (int ctx=0;ctx<size;ctx++) {//column
+          k=0;
+          for(int cctx=0;cctx<size;cctx++)
+            if(cctx != ctx) cc[k++] = cctx;
+
+          //fill out the sub matrix corresponds to this element
+          for (int ridx=0;ridx<(size-1);ridx++)
+            for (int cidx=0;cidx<(size-1);cidx++)
+              sub_matrix_cpx[cidx*(size-1)+ridx]= a44_cpx[cc[cidx]*size+rr[ridx]];
+
+          inv_H_h_H_cpx[rtx*size+ctx] = nr_determin_cpx(sub_matrix_cpx,//
+                                                        size-1,//size
+                                                        ((rtx&1)==1?-1:1)*((ctx&1)==1?-1:1));
+          //if (i==0) printf("H_h_H(r%d,c%d)=%lf+j%lf --> inv_H_h_H(%d,%d) = %lf+j%lf \n",rtx,ctx,creal(a44_cpx[ctx*size+rtx]),cimag(a44_cpx[ctx*size+rtx]),ctx,rtx,creal(inv_H_h_H_cpx[rtx*size+ctx]),cimag(inv_H_h_H_cpx[rtx*size+ctx]));
+
+          if (creal(inv_H_h_H_cpx[rtx*size+ctx])>0)
+            ((short *) inv_H_h_H[rtx*size+ctx])[i<<1] = (short) ((creal(inv_H_h_H_cpx[rtx*size+ctx])*(1<<(shift0-1)))+0.5);//Convert to Q 18
+          else
+            ((short *) inv_H_h_H[rtx*size+ctx])[i<<1] = (short) ((creal(inv_H_h_H_cpx[rtx*size+ctx])*(1<<(shift0-1)))-0.5);//
+
+          if (cimag(inv_H_h_H_cpx[rtx*size+ctx])>0)
+            ((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1] = (short) ((cimag(inv_H_h_H_cpx[rtx*size+ctx])*(1<<(shift0-1)))+0.5);//
+          else
+            ((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1] = (short) ((cimag(inv_H_h_H_cpx[rtx*size+ctx])*(1<<(shift0-1)))-0.5);//
+
+          //if (i<4) printf("inv_H_h_H_FP(%d,%d)= %d+j%d \n",ctx,rtx, ((short *) inv_H_h_H[rtx*size+ctx])[i<<1],((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1]);
+        }
+      }
+    }
+  }
+  return(0);
 }
 
 /* Zero Forcing Rx function: nr_conjch0_mult_ch1()
@@ -2397,451 +2262,121 @@ void nr_conjch0_mult_ch1(int *ch0,
   _mm_empty();
   _m_empty();
 }
-__m128i nr_comp_muli_sum(__m128i input_x,
-                         __m128i input_y,
-                         __m128i input_w,
-                         __m128i input_z,
-                         __m128i det)
-{
-  int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
-
-  __m128i xy_re_128, xy_im_128, wz_re_128, wz_im_128;
-  __m128i output, tmp_z0, tmp_z1;
-
-  // complex multiplication (x_re + jx_im)*(y_re + jy_im) = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im)
-  // the real part
-  xy_re_128 = _mm_sign_epi16(input_x,*(__m128i*)&nr_conjug2[0]);
-  xy_re_128 = _mm_madd_epi16(xy_re_128,input_y); //Re: (x_re*y_re - x_im*y_im)
-
-  // the imag part
-  xy_im_128 = _mm_shufflelo_epi16(input_x,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  xy_im_128 = _mm_shufflehi_epi16(xy_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  xy_im_128 = _mm_madd_epi16(xy_im_128,input_y);//Im: (x_im*y_re + x_re*y_im)
-
-  // complex multiplication (w_re + jw_im)*(z_re + jz_im) = (w_re*z_re - w_im*z_im) + j(w_im*z_re + w_re*z_im)
-  // the real part
-  wz_re_128 = _mm_sign_epi16(input_w,*(__m128i*)&nr_conjug2[0]);
-  wz_re_128 = _mm_madd_epi16(wz_re_128,input_z); //Re: (w_re*z_re - w_im*z_im)
-
-  // the imag part
-  wz_im_128 = _mm_shufflelo_epi16(input_w,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  wz_im_128 = _mm_shufflehi_epi16(wz_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits
-  wz_im_128 = _mm_madd_epi16(wz_im_128,input_z);//Im: (w_im*z_re + w_re*z_im)
-
-
-  xy_re_128 = _mm_sub_epi32(xy_re_128, wz_re_128);
-  xy_im_128 = _mm_sub_epi32(xy_im_128, wz_im_128);
-  //print_ints("rx_re:",(int32_t*)&xy_re_128[0]);
-  //print_ints("rx_Img:",(int32_t*)&xy_im_128[0]);
-  //divide by matrix det and convert back to Q15 before packing
-  int sum_det =0;
-  for (int k=0; k<4;k++) {
-    sum_det += ((((int *)&det[0])[k])>>2);
-    //printf("det_%d = %d log2 =%d \n",k,(((int *)&det[0])[k]),log2_approx(((int *)&det[0])[k]));
-    }
-
-  xy_re_128 = _mm_slli_epi32(xy_re_128,5);
-  xy_re_128 = _mm_srai_epi32(xy_re_128,log2_approx(sum_det));
-  xy_re_128 = _mm_slli_epi32(xy_re_128,5);
 
-  xy_im_128 = _mm_slli_epi32(xy_im_128,5);
-  xy_im_128 = _mm_srai_epi32(xy_im_128,log2_approx(sum_det));
-  xy_im_128 = _mm_slli_epi32(xy_im_128,5);
-
-  tmp_z0  = _mm_unpacklo_epi32(xy_re_128,xy_im_128);
-  //print_ints("unpack lo:",&tmp_z0[0]);
-  tmp_z1  = _mm_unpackhi_epi32(xy_re_128,xy_im_128);
-  //print_ints("unpack hi:",&tmp_z1[0]);
-  output = _mm_packs_epi32(tmp_z0,tmp_z1);
-
-  _mm_empty();
-  _m_empty();
-  return(output);
-}
-/* Zero Forcing Rx function: nr_construct_HhH_elements()
+/* Zero Forcing Rx function: up to 4 layers
  *
  *
  * */
-void nr_construct_HhH_elements(int *conjch00_ch00,
-                               int *conjch01_ch01,
-                               int *conjch11_ch11,
-                               int *conjch10_ch10,//
-                               int *conjch20_ch20,
-                               int *conjch21_ch21,
-                               int *conjch30_ch30,
-                               int *conjch31_ch31,
-                               int *conjch00_ch01,//00_01
-                               int *conjch01_ch00,//01_00
-                               int *conjch10_ch11,//10_11
-                               int *conjch11_ch10,//11_10
-                               int *conjch20_ch21,
-                               int *conjch21_ch20,
-                               int *conjch30_ch31,
-                               int *conjch31_ch30,
-                               int32_t *after_mf_00,
-                               int32_t *after_mf_01,
-                               int32_t *after_mf_10,
-                               int32_t *after_mf_11,
-                               unsigned short nb_rb,
-                               unsigned char symbol)
+uint8_t nr_zero_forcing_rx(int **rxdataF_comp,
+                           int **dl_ch_mag,
+                           int **dl_ch_magb,
+                           int **dl_ch_magr,
+                           int **dl_ch_estimates_ext,
+                           unsigned short nb_rb,
+                           unsigned char n_rx,
+                           unsigned char n_tx,//number of layer
+                           unsigned char mod_order,
+                           int shift,
+                           unsigned char symbol,
+                           int length)
 {
-  //This function is used to construct the (H_hermitian * H matrix) matrix elements
-  unsigned short rb;
-  __m128i *conjch00_ch00_128, *conjch01_ch01_128, *conjch11_ch11_128, *conjch10_ch10_128;
-  __m128i *conjch20_ch20_128, *conjch21_ch21_128, *conjch30_ch30_128, *conjch31_ch31_128;
-  __m128i *conjch00_ch01_128, *conjch01_ch00_128, *conjch10_ch11_128, *conjch11_ch10_128;
-  __m128i *conjch20_ch21_128, *conjch21_ch20_128, *conjch30_ch31_128, *conjch31_ch30_128;
-  __m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128;
-
-  conjch00_ch00_128 = (__m128i *)conjch00_ch00;
-  conjch01_ch01_128 = (__m128i *)conjch01_ch01;
-  conjch11_ch11_128 = (__m128i *)conjch11_ch11;
-  conjch10_ch10_128 = (__m128i *)conjch10_ch10;
-
-  conjch20_ch20_128 = (__m128i *)conjch20_ch20;
-  conjch21_ch21_128 = (__m128i *)conjch21_ch21;
-  conjch30_ch30_128 = (__m128i *)conjch30_ch30;
-  conjch31_ch31_128 = (__m128i *)conjch31_ch31;
-
-  conjch00_ch01_128 = (__m128i *)conjch00_ch01;
-  conjch01_ch00_128 = (__m128i *)conjch01_ch00;
-  conjch10_ch11_128 = (__m128i *)conjch10_ch11;
-  conjch11_ch10_128 = (__m128i *)conjch11_ch10;
-
-  conjch20_ch21_128 = (__m128i *)conjch20_ch21;
-  conjch21_ch20_128 = (__m128i *)conjch21_ch20;
-  conjch30_ch31_128 = (__m128i *)conjch30_ch31;
-  conjch31_ch30_128 = (__m128i *)conjch31_ch30;
-
-  after_mf_00_128 = (__m128i *)after_mf_00;
-  after_mf_01_128 = (__m128i *)after_mf_01;
-  after_mf_10_128 = (__m128i *)after_mf_10;
-  after_mf_11_128 = (__m128i *)after_mf_11;
-
-  for (rb=0; rb<3*nb_rb; rb++) {
-
-    after_mf_00_128[0] =_mm_adds_epi16(conjch00_ch00_128[0],conjch10_ch10_128[0]);//00_00 + 10_10
-    if (conjch20_ch20 != NULL) after_mf_00_128[0] =_mm_adds_epi16(after_mf_00_128[0],conjch20_ch20_128[0]);
-    if (conjch30_ch30 != NULL) after_mf_00_128[0] =_mm_adds_epi16(after_mf_00_128[0],conjch30_ch30_128[0]);
-
-    after_mf_11_128[0] =_mm_adds_epi16(conjch01_ch01_128[0], conjch11_ch11_128[0]); //01_01 + 11_11
-    if (conjch21_ch21 != NULL) after_mf_11_128[0] =_mm_adds_epi16(after_mf_11_128[0],conjch21_ch21_128[0]);
-    if (conjch31_ch31 != NULL) after_mf_11_128[0] =_mm_adds_epi16(after_mf_11_128[0],conjch31_ch31_128[0]);
-
-    after_mf_01_128[0] =_mm_adds_epi16(conjch00_ch01_128[0], conjch10_ch11_128[0]);//00_01 + 10_11
-    if (conjch20_ch21 != NULL) after_mf_01_128[0] =_mm_adds_epi16(after_mf_01_128[0],conjch20_ch21_128[0]);
-    if (conjch30_ch31 != NULL) after_mf_01_128[0] =_mm_adds_epi16(after_mf_01_128[0],conjch30_ch31_128[0]);
-
-    after_mf_10_128[0] =_mm_adds_epi16(conjch01_ch00_128[0], conjch11_ch10_128[0]);//01_00 + 11_10
-    if (conjch21_ch20 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch21_ch20_128[0]);
-    if (conjch31_ch30 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch31_ch30_128[0]);
-
-#ifdef DEBUG_DLSCH_DEMOD
-    if ((rb<=30))
-    {
-      printf(" \n construct_HhH_elements \n");
-      print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]);
-      print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]);
-      print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]);
-      print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]);
+  int *ch0r, *ch0c;
+  int32_t *** conjH_H_elements;
+  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
+  int32_t determ_fin[12*nb_rb_0] __attribute__((aligned(32)));
+
+  ///Allocate H^*H matrix elements and sub elements
+  conjH_H_elements        = (int32_t ***)malloc16_clear( n_rx*sizeof(int32_t **) );
+  for (int aarx=0;aarx<n_rx;aarx++) {
+    conjH_H_elements[aarx] = (int32_t **)malloc16_clear( n_tx*n_tx*sizeof(int32_t) );
+    for (int rtx=0;rtx<n_tx;rtx++) {//row
+      for (int ctx=0;ctx<n_tx;ctx++) {//column
+        conjH_H_elements[aarx][ctx*n_tx+rtx] = (int32_t *)malloc16_clear( 12*nb_rb_0*sizeof(int32_t *) );
+      }
     }
-#endif
-    conjch00_ch00_128+=1;
-    conjch10_ch10_128+=1;
-    conjch01_ch01_128+=1;
-    conjch11_ch11_128+=1;
-
-    if (conjch20_ch20 != NULL) conjch20_ch20_128+=1;
-    if (conjch21_ch21 != NULL) conjch21_ch21_128+=1;
-    if (conjch30_ch30 != NULL) conjch30_ch30_128+=1;
-    if (conjch31_ch31 != NULL) conjch31_ch31_128+=1;
-
-    conjch00_ch01_128+=1;
-    conjch01_ch00_128+=1;
-    conjch10_ch11_128+=1;
-    conjch11_ch10_128+=1;
-
-    if (conjch20_ch21 != NULL) conjch20_ch21_128+=1;
-    if (conjch21_ch20 != NULL) conjch21_ch20_128+=1;
-    if (conjch30_ch31 != NULL) conjch30_ch31_128+=1;
-    if (conjch31_ch30 != NULL) conjch31_ch30_128+=1;
-
-    after_mf_00_128 += 1;
-    after_mf_01_128 += 1;
-    after_mf_10_128 += 1;
-    after_mf_11_128 += 1;
   }
-  _mm_empty();
-  _m_empty();
-}
 
-/* Zero Forcing Rx function: nr_zero_forcing_rx_2layers()
- *
- *
- * */
-uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
-                                   int **dl_ch_mag,
-                                   int **dl_ch_magb,
-                                   int **dl_ch_magr,
-                                   int **dl_ch_estimates_ext,
-                                   unsigned short nb_rb,
-                                   unsigned char n_rx,
-                                   unsigned char mod_order,
-                                   int shift,
-                                   unsigned char symbol,
-                                   int length)
-{
-  int *ch00, *ch01, *ch10, *ch11;
-  int *ch20, *ch30, *ch21, *ch31;
-  uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
-  /* we need at least alignment to 16 bytes, let's put 32 to be sure
-   * (maybe not necessary but doesn't hurt)
-   */
-  int32_t conjch00_ch01[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch01_ch00[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch10_ch11[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch11_ch10[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch00_ch00[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch01_ch01[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch10_ch10[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch11_ch11[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch20_ch20[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch21_ch21[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch30_ch30[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch31_ch31[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch20_ch21[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch30_ch31[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch21_ch20[12*nb_rb] __attribute__((aligned(32)));
-  int32_t conjch31_ch30[12*nb_rb] __attribute__((aligned(32)));
-
-  int32_t af_mf_00[12*nb_rb] __attribute__((aligned(32)));
-  int32_t af_mf_01[12*nb_rb] __attribute__((aligned(32)));
-  int32_t af_mf_10[12*nb_rb] __attribute__((aligned(32)));
-  int32_t af_mf_11[12*nb_rb] __attribute__((aligned(32)));
-  int32_t determ_fin[12*nb_rb] __attribute__((aligned(32)));
-
-  switch (n_rx) {
-    case 2://
-      ch00 = (int *)&dl_ch_estimates_ext[0][symbol*nb_rb*12];
-      ch01 = (int *)&dl_ch_estimates_ext[2][symbol*nb_rb*12];
-      ch10 = (int *)&dl_ch_estimates_ext[1][symbol*nb_rb*12];
-      ch11 = (int *)&dl_ch_estimates_ext[3][symbol*nb_rb*12];
-      ch20 = NULL;
-      ch21 = NULL;
-      ch30 = NULL;
-      ch31 = NULL;
-      break;
-
-    case 4://
-      ch00 = (int *)&dl_ch_estimates_ext[0][symbol*nb_rb*12];
-      ch01 = (int *)&dl_ch_estimates_ext[4][symbol*nb_rb*12];
-      ch10 = (int *)&dl_ch_estimates_ext[1][symbol*nb_rb*12];
-      ch11 = (int *)&dl_ch_estimates_ext[5][symbol*nb_rb*12];
-      ch20 = (int *)&dl_ch_estimates_ext[2][symbol*nb_rb*12];
-      ch21 = (int *)&dl_ch_estimates_ext[6][symbol*nb_rb*12];
-      ch30 = (int *)&dl_ch_estimates_ext[3][symbol*nb_rb*12];
-      ch31 = (int *)&dl_ch_estimates_ext[7][symbol*nb_rb*12];
-      break;
-
-    default:
-      return -1;
-      break;
+  //Compute H^*H matrix elements and sub elements:(1/2^log2_maxh)*conjH_H_elements
+  for (int rtx=0;rtx<n_tx;rtx++) {//row
+    for (int ctx=0;ctx<n_tx;ctx++) {//column
+      for (int aarx=0;aarx<n_rx;aarx++)  {
+        ch0r = (int *)&dl_ch_estimates_ext[rtx*n_rx+aarx][symbol*nb_rb*12];//[]//conjch00,01,02,03
+        ch0c = (int *)&dl_ch_estimates_ext[ctx*n_rx+aarx][symbol*nb_rb*12];//[aatx*n_rx+aarx]//ch00: 01,02,03
+        nr_conjch0_mult_ch1(ch0r,
+                            ch0c,
+                            conjH_H_elements[aarx][ctx*n_tx+rtx],
+                            nb_rb_0,
+                            shift);
+        if (aarx !=0) nr_a_sum_b((__m128i *)conjH_H_elements[0][ctx*n_tx+rtx],
+                                 (__m128i *)conjH_H_elements[aarx][ctx*n_tx+rtx],
+                                 nb_rb_0);
+      }
+    }
   }
 
-  /* 1- Compute the rx channel matrix after compensation: (1/2^log2_max)x(H_herm x H)
-   * for n_rx = 2
-   * |conj_H_00       conj_H_10|    | H_00         H_01|   |(conj_H_00xH_00+conj_H_10xH_10)   (conj_H_00xH_01+conj_H_10xH_11)|
-   * |                         |  x |                  | = |                                                                 |
-   * |conj_H_01       conj_H_11|    | H_10         H_11|   |(conj_H_01xH_00+conj_H_11xH_10)   (conj_H_01xH_01+conj_H_11xH_11)|
-   *
-   */
-
-  if (n_rx>=2){
-    // (1/2^log2_maxh)*conj_H_00xH_00: (1/(64*2))conjH_00*H_00*2^15
-    nr_conjch0_mult_ch1(ch00,
-                        ch00,
-                        conjch00_ch00,
-                        nb_rb_0,
-                        shift);
-    // (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15
-    nr_conjch0_mult_ch1(ch10,
-                        ch10,
-                        conjch10_ch10,
-                        nb_rb_0,
-                        shift);
-    // conj_H_00xH_01
-    nr_conjch0_mult_ch1(ch00,
-                        ch01,
-                        conjch00_ch01,
-                        nb_rb_0,
-                        shift); // this shift is equal to the channel level log2_maxh
-    // conj_H_10xH_11
-    nr_conjch0_mult_ch1(ch10,
-                        ch11,
-                        conjch10_ch11,
-                        nb_rb_0,
-                        shift);
-    // conj_H_01xH_01
-    nr_conjch0_mult_ch1(ch01,
-                        ch01,
-                        conjch01_ch01,
-                        nb_rb_0,
-                        shift);
-    // conj_H_11xH_11
-    nr_conjch0_mult_ch1(ch11,
-                        ch11,
-                        conjch11_ch11,
-                        nb_rb_0,
-                        shift);
-    // conj_H_01xH_00
-    nr_conjch0_mult_ch1(ch01,
-                        ch00,
-                        conjch01_ch00,
-                        nb_rb_0,
-                        shift);
-    // conj_H_11xH_10
-    nr_conjch0_mult_ch1(ch11,
-                        ch10,
-                        conjch11_ch10,
-                        nb_rb_0,
-                        shift);
-  }
-  if (n_rx==4){
-    // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2*16))conjH_20*H_20*2^15
-    nr_conjch0_mult_ch1(ch20,
-                        ch20,
-                        conjch20_ch20,
-                        nb_rb_0,
-                        shift);
-
-    // (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15
-    nr_conjch0_mult_ch1(ch30,
-                        ch30,
-                        conjch30_ch30,
-                        nb_rb_0,
-                        shift);
-
-    // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15
-    nr_conjch0_mult_ch1(ch20,
-                        ch21,
-                        conjch20_ch21,
-                        nb_rb_0,
-                        shift);
-
-    nr_conjch0_mult_ch1(ch30,
-                        ch31,
-                        conjch30_ch31,
-                        nb_rb_0,
-                        shift);
-
-    nr_conjch0_mult_ch1(ch21,
-                        ch21,
-                        conjch21_ch21,
-                        nb_rb_0,
-                        shift);
-
-    nr_conjch0_mult_ch1(ch31,
-                        ch31,
-                        conjch31_ch31,
-                        nb_rb_0,
-                        shift);
-
-    // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15
-    nr_conjch0_mult_ch1(ch21,
-                        ch20,
-                        conjch21_ch20,
-                        nb_rb_0,
-                        shift);
-
-    nr_conjch0_mult_ch1(ch31,
-                        ch30,
-                        conjch31_ch30,
-                        nb_rb_0,
-                        shift);
-
-    nr_construct_HhH_elements(conjch00_ch00,
-                              conjch01_ch01,
-                              conjch11_ch11,
-                              conjch10_ch10,//
-                              conjch20_ch20,
-                              conjch21_ch21,
-                              conjch30_ch30,
-                              conjch31_ch31,
-                              conjch00_ch01,
-                              conjch01_ch00,
-                              conjch10_ch11,
-                              conjch11_ch10,//
-                              conjch20_ch21,
-                              conjch21_ch20,
-                              conjch30_ch31,
-                              conjch31_ch30,
-                              af_mf_00,
-                              af_mf_01,
-                              af_mf_10,
-                              af_mf_11,
-                              nb_rb_0,
-                              symbol);
-  }
-  if (n_rx==2){
-    nr_construct_HhH_elements(conjch00_ch00,
-                              conjch01_ch01,
-                              conjch11_ch11,
-                              conjch10_ch10,//
-                              NULL,
-                              NULL,
-                              NULL,
-                              NULL,
-                              conjch00_ch01,
-                              conjch01_ch00,
-                              conjch10_ch11,
-                              conjch11_ch10,//
-                              NULL,
-                              NULL,
-                              NULL,
-                              NULL,
-                              af_mf_00,
-                              af_mf_01,
-                              af_mf_10,
-                              af_mf_11,
-                              nb_rb_0,
-                              symbol);
+  //Compute the inverse and determinant of the H^*H matrix
+  //Allocate the inverse matrix
+  int32_t ** inv_H_h_H;
+  inv_H_h_H = (int32_t **)malloc16_clear( n_tx*n_tx*sizeof(int32_t *) );
+  for (int rtx=0;rtx<n_tx;rtx++) {//row
+    for (int ctx=0;ctx<n_tx;ctx++) {//column
+      inv_H_h_H[ctx*n_tx+rtx] = (int32_t *)malloc16_clear( 12*nb_rb_0*sizeof(int32_t) );
+    }
   }
-  //det_HhH = ad -bc
-  nr_det_HhH(af_mf_00,//a
-             af_mf_01,//b
-             af_mf_10,//c
-             af_mf_11,//d
-             determ_fin,
-             nb_rb_0,
-             symbol,
-             shift);
-  /* 2- Compute the channel matrix inversion **********************************
-   *
-     *    |(conj_H_00xH_00+conj_H_10xH_10)   (conj_H_00xH_01+conj_H_10xH_11)|
-     * A= |                                                                 |
-     *    |(conj_H_01xH_00+conj_H_11xH_10)   (conj_H_01xH_01+conj_H_11xH_11)|
-     *
-     *
-     *
-     *inv(A) =(1/det)*[d  -b
-     *                 -c  a]
-     *
-     *
-     **************************************************************************/
-  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0=NULL,*dl_ch_mag128b_0=NULL,*dl_ch_mag128r_0=NULL,*determ_fin_128;//*dl_ch_mag128_1,*dl_ch_mag128b_1,*dl_ch_mag128r_1
-  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
-  __m128i *after_mf_a_128,*after_mf_b_128, *after_mf_c_128, *after_mf_d_128;
-  __m128i QAM_amp128={0},QAM_amp128b={0},QAM_amp128r={0};
-
-  determ_fin_128      = (__m128i *)&determ_fin[0];
+  int fp_flag = 1;//0: float point calc 1: Fixed point calc
+  nr_matrix_inverse(conjH_H_elements[0],//Input matrix
+                    inv_H_h_H,//Inverse
+                    determ_fin,//determin
+                    n_tx,//size
+                    nb_rb_0,
+                    fp_flag,//fixed point flag
+                    shift-(fp_flag==1?2:0));//the out put is Q15
+
+  // multiply Matrix inversion pf H_h_H by the rx signal vector
+  int32_t outtemp[12*nb_rb_0] __attribute__((aligned(32)));
+  int32_t **rxdataF_zforcing;
+  //Allocate rxdataF for zforcing out
+  rxdataF_zforcing        = (int32_t **)malloc16_clear( n_tx*sizeof(int32_t *) );
+   for (int rtx=0;rtx<n_tx;rtx++) {//row
+     rxdataF_zforcing[rtx] = (int32_t *)malloc16_clear( 12*nb_rb_0*sizeof(int32_t) );
+   }
+
+  for (int rtx=0;rtx<n_tx;rtx++) {//Output Layers row
+    // loop over Layers rtx=0,...,N_Layers-1
+      for (int ctx=0;ctx<n_tx;ctx++) {//column multi
+        //printf("Computing r_%d c_%d\n",rtx,ctx);
+        //print_shorts(" H_h_H=",(int16_t*)&conjH_H_elements[ctx*n_tx+rtx][0][0]);
+        //print_shorts(" Inv_H_h_H=",(int16_t*)&inv_H_h_H[ctx*n_tx+rtx][0]);
+        nr_a_mult_b(inv_H_h_H[ctx*n_tx+rtx],
+                    (int *)&rxdataF_comp[ctx*n_rx][symbol*nb_rb*12],
+                    outtemp,
+                    nb_rb_0,
+                    shift-(fp_flag==1?2:0));
+        nr_a_sum_b((__m128i *)rxdataF_zforcing[rtx],
+                   (__m128i *)outtemp,
+                   nb_rb_0);//a =a + b
+        }
+#ifdef DEBUG_DLSCH_DEMOD
+    printf("Computing layer_%d \n",rtx);;
+    print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][0]);
+    print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][4]);
+    print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][8]);
+#endif
+    }
 
-  rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12];//aatx=0 @ aarx =0
-  rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12];//aatx=1 @ aarx =0
+  //Copy zero_forcing out to output array
+  for (int rtx=0;rtx<n_tx;rtx++)
+    nr_element_sign(rxdataF_zforcing[rtx],
+                    (int *)&rxdataF_comp[rtx*n_rx][symbol*nb_rb*12],
+                    nb_rb_0,
+                    +1);
 
-  after_mf_a_128 = (__m128i *)af_mf_00;
-  after_mf_b_128 = (__m128i *)af_mf_01;
-  after_mf_c_128 = (__m128i *)af_mf_10;
-  after_mf_d_128 = (__m128i *)af_mf_11;
+  //Update LLR thresholds with the Matrix determinant
+  __m128i *dl_ch_mag128_0=NULL,*dl_ch_mag128b_0=NULL,*dl_ch_mag128r_0=NULL,*determ_fin_128;
+  __m128i mmtmpD2,mmtmpD3;
+  __m128i QAM_amp128={0},QAM_amp128b={0},QAM_amp128r={0};
+  short nr_realpart[8]__attribute__((aligned(16))) = {1,0,1,0,1,0,1,0};
+  determ_fin_128      = (__m128i *)&determ_fin[0];
 
   if (mod_order>2) {
     if (mod_order == 4) {
@@ -2856,88 +2391,41 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp,
       QAM_amp128 = _mm_set1_epi16(QAM256_n1); //8/sqrt{170}
       QAM_amp128b = _mm_set1_epi16(QAM256_n2);//4/sqrt{170}
       QAM_amp128r = _mm_set1_epi16(QAM256_n3);//2/sqrt{170}
-      }
+    }
     dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[0][symbol*nb_rb*12];
     dl_ch_mag128b_0     = (__m128i *)&dl_ch_magb[0][symbol*nb_rb*12];
     dl_ch_mag128r_0     = (__m128i *)&dl_ch_magr[0][symbol*nb_rb*12];
-  }
-
-  for (int rb=0; rb<3*nb_rb_0; rb++) {
-    if (mod_order>2) {
-      int sum_det =0;
-      for (int k=0; k<4;k++) {
-        sum_det += ((((int *)&determ_fin_128[0])[k])>>2);
-        //printf("det_%d = %d\n",k,sum_det);
-        }
-
-      mmtmpD2 = _mm_slli_epi32(determ_fin_128[0],5);
-      mmtmpD2 = _mm_srai_epi32(mmtmpD2,log2_approx(sum_det));
-      mmtmpD2 = _mm_slli_epi32(mmtmpD2,5);
-
-      mmtmpD3 = _mm_unpacklo_epi32(mmtmpD2,mmtmpD2);
 
-      mmtmpD2 = _mm_unpackhi_epi32(mmtmpD2,mmtmpD2);
+    for (int rb=0; rb<3*nb_rb_0; rb++) {
+      //for symmetric H_h_H matrix, the determinant is only real values
+        mmtmpD2 = _mm_sign_epi16(determ_fin_128[0],*(__m128i*)&nr_realpart[0]);//set imag part to 0
+        mmtmpD3 = _mm_shufflelo_epi16(mmtmpD2,_MM_SHUFFLE(2,3,0,1));
+        mmtmpD3 = _mm_shufflehi_epi16(mmtmpD3,_MM_SHUFFLE(2,3,0,1));
+        mmtmpD2 = _mm_add_epi16(mmtmpD2,mmtmpD3);
 
-      mmtmpD2 = _mm_packs_epi32(mmtmpD3,mmtmpD2);
+        dl_ch_mag128_0[0] = mmtmpD2;
+        dl_ch_mag128b_0[0] = mmtmpD2;
+        dl_ch_mag128r_0[0] = mmtmpD2;
 
-      dl_ch_mag128_0[0] = mmtmpD2;
-      dl_ch_mag128b_0[0] = mmtmpD2;
-      dl_ch_mag128r_0[0] = mmtmpD2;
+        dl_ch_mag128_0[0] = _mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128);
+        dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);
 
-      dl_ch_mag128_0[0] = _mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128);
-      dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);
+        dl_ch_mag128b_0[0] = _mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b);
+        dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1);
+        dl_ch_mag128r_0[0] = _mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r);
+        dl_ch_mag128r_0[0] = _mm_slli_epi16(dl_ch_mag128r_0[0],1);
 
-      dl_ch_mag128b_0[0] = _mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b);
-      dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1);
 
-      dl_ch_mag128r_0[0] = _mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r);
-      dl_ch_mag128r_0[0] = _mm_slli_epi16(dl_ch_mag128r_0[0],1);
-
-      //print_shorts("mag layer 1:",(int16_t*)&dl_ch_mag128_0[0]);
-      //print_shorts("mag layer 2:",(int16_t*)&dl_ch_mag128_1[0]);
-      //print_shorts("magb layer 1:",(int16_t*)&dl_ch_mag128b_0[0]);
-      //print_shorts("magb layer 2:",(int16_t*)&dl_ch_mag128b_1[0]);
-      //print_shorts("magr layer 1:",(int16_t*)&dl_ch_mag128r_0[0]);
-      //print_shorts("magr layer 2:",(int16_t*)&dl_ch_mag128r_1[0]);
+      determ_fin_128 += 1;
+      dl_ch_mag128_0 += 1;
+      dl_ch_mag128b_0 += 1;
+      dl_ch_mag128r_0 += 1;
     }
-    // multiply by channel Inv
-    //rxdataF_zf128_0 = rxdataF_comp128_0*d - b*rxdataF_comp128_1
-    //rxdataF_zf128_1 = rxdataF_comp128_1*a - c*rxdataF_comp128_0
-    //printf("layer_1 \n");
-    mmtmpD0 = nr_comp_muli_sum(rxdataF_comp128_0[0],
-                               after_mf_d_128[0],
-                               rxdataF_comp128_1[0],
-                               after_mf_b_128[0],
-                               determ_fin_128[0]);
-
-    //printf("layer_2 \n");
-    mmtmpD1 = nr_comp_muli_sum(rxdataF_comp128_1[0],
-                               after_mf_a_128[0],
-                               rxdataF_comp128_0[0],
-                               after_mf_c_128[0],
-                               determ_fin_128[0]);
-
-    rxdataF_comp128_0[0] = mmtmpD0;
-    rxdataF_comp128_1[0] = mmtmpD1;
-#ifdef DEBUG_DLSCH_DEMOD
-    printf("\n Rx signal after ZF l%d rb%d\n",symbol,rb);
-    print_shorts(" Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]);
-    print_shorts(" Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]);
-#endif
-    determ_fin_128 += 1;
-    dl_ch_mag128_0 += 1;
-    dl_ch_mag128b_0 += 1;
-    dl_ch_mag128r_0 += 1;
-    rxdataF_comp128_0 += 1;
-    rxdataF_comp128_1 += 1;
-    after_mf_a_128 += 1;
-    after_mf_b_128 += 1;
-    after_mf_c_128 += 1;
-    after_mf_d_128 += 1;
   }
+
   _mm_empty();
   _m_empty();
-   return(0);
+  return(0);
 }
 
 static void nr_dlsch_layer_demapping(int16_t **llr_cw,
@@ -2998,26 +2486,12 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         uint8_t nr_slot_rx,
                         uint8_t beamforming_mode)
 {
-
-  int16_t  *pllr_symbol_cw0;
-  int16_t  *pllr_symbol_cw1;
-  int16_t  *pllr_symbol_layer0;
-  int16_t  *pllr_symbol_layer1;
   uint32_t llr_offset_symbol;
   
-  if (first_symbol_flag==1) pdsch_vars[gNB_id]->llr_offset[symbol-1] = 0;
+  if (first_symbol_flag==1)
+    pdsch_vars[gNB_id]->llr_offset[symbol-1] = 0;
   llr_offset_symbol = pdsch_vars[gNB_id]->llr_offset[symbol-1];
-  //pllr_symbol_cw0_deint  = (int8_t*)pdsch_vars[gNB_id]->llr[0];
-  //pllr_symbol_cw1_deint  = (int8_t*)pdsch_vars[gNB_id]->llr[1];
-  pllr_symbol_layer0 = pdsch_vars[gNB_id]->layer_llr[0];
-  pllr_symbol_layer1 = pdsch_vars[gNB_id]->layer_llr[1];
-  pllr_symbol_layer0 += llr_offset_symbol;
-  pllr_symbol_layer1 += llr_offset_symbol;
-  pllr_symbol_cw0 = pdsch_vars[gNB_id]->llr[0];
-  pllr_symbol_cw1 = pdsch_vars[gNB_id]->llr[1];
-  pllr_symbol_cw0 += llr_offset_symbol;
-  pllr_symbol_cw1 += llr_offset_symbol;
-    
+
   pdsch_vars[gNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol;
  
   /*LOG_I(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n",
@@ -3027,14 +2501,6 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
     pdsch_vars[gNB_id]->llr_offset[symbol],
     (int16_t*)pdsch_vars[gNB_id]->llr[0],
     pllr_symbol_cw0);*/
-             
-  /*printf("compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n",
-    symbol,
-    nb_rb,dlsch0_harq->Qm,
-    pdsch_vars[gNB_id]->llr_length[symbol],
-    pdsch_vars[gNB_id]->llr_offset[symbol],
-    pdsch_vars[gNB_id]->llr[0],
-    pllr_symbol_cw0);*/
 
   switch (dlsch0_harq->Qm) {
   case 2 :
@@ -3050,27 +2516,14 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                             nb_rb,
                             beamforming_mode);
         break;
-      case rx_IC_single_stream ://not implemented yet
-        /*nr_dlsch_qpsk_qpsk_llr(frame_parms,
-                               pdsch_vars[gNB_id]->rxdataF_comp0,
-                               rxdataF_comp_ptr,
-                               pdsch_vars[gNB_id]->dl_ch_rho2_ext,
-                               pdsch_vars[gNB_id]->layer_llr[0],
-                               symbol,len,first_symbol_flag,nb_rb,
-                               adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                               pdsch_vars[gNB_id]->llr128);*/
+      case rx_IC_single_stream ://From LTE Code!!
+        //not implemented yet
         break;
-      case rx_IC_dual_stream ://not implemented yet
-        /*nr_dlsch_qpsk_qpsk_llr(frame_parms,
-                               rxdataF_comp_ptr,
-                               pdsch_vars[gNB_id]->rxdataF_comp0,
-                               pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round],
-                               pdsch_vars[gNB_id]->layer_llr[1],
-                               symbol,len,first_symbol_flag,nb_rb,
-                               adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
-                               pdsch_vars[gNB_id]->llr128_2ndstream);*/
+      case rx_IC_dual_stream :
+        //not implemented yet
         break;
-      case rx_SIC_dual_stream ://not implemented yet
+      case rx_SIC_dual_stream :
+        //not implemented yet
         break;
     }
     break;
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 aac59a7da15350a442658bc6f2b6b906724e2fff..e1df279abf47f7c5935bcef0e0a7d3e102e23419 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -733,7 +733,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
     @param n_dmrs_cdm_groups
     @param frame_parms Pointer to frame descriptor
 */
-unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
+void nr_dlsch_extract_rbs(int **rxdataF,
                                         int **dl_ch_estimates,
                                         int **rxdataF_ext,
                                         int **dl_ch_estimates_ext,
@@ -824,28 +824,12 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
                                      int start_point);
 
 void nr_dlsch_deinterleaving(uint8_t symbol,
-							uint8_t start_symbol,
-							uint16_t L,
-							uint16_t *llr,
-							uint16_t *llr_deint,
-							uint16_t nb_rb_pdsch);
-
-void dlsch_dual_stream_correlation(NR_DL_FRAME_PARMS *frame_parms,
-                                   unsigned char symbol,
-                                   unsigned short nb_rb,
-                                   int **dl_ch_estimates_ext,
-                                   int **dl_ch_estimates_ext_i,
-                                   int **dl_ch_rho_ext,
-                                   unsigned char output_shift);
-
-void dlsch_dual_stream_correlationTM34(NR_DL_FRAME_PARMS *frame_parms,
-                                   unsigned char symbol,
-                                   unsigned short nb_rb,
-                                   int **dl_ch_estimates_ext,
-                                   int **dl_ch_estimates_ext_i,
-                                   int **dl_ch_rho_ext,
-                                   unsigned char output_shift0,
-                                   unsigned char output_shift1);
+                             uint8_t start_symbol,
+                             uint16_t L,
+                             uint16_t *llr,
+                             uint16_t *llr_deint,
+                             uint16_t nb_rb_pdsch);
+
 //This function is used to compute multiplications in Hhermitian * H matrix
 void conjch0_mult_ch1(int *ch0,
                       int *ch1,
@@ -897,19 +881,6 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp,
                             unsigned short nb_rb,
                             int length);
 
-void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
-                              int **rxdataF_comp_i,
-                              int **rho,
-                              int **rho_i,
-                              int **dl_ch_mag,
-                              int **dl_ch_magb,
-                              int **dl_ch_mag_i,
-                              int **dl_ch_magb_i,
-                              unsigned char n_tx,
-                              unsigned char n_rx,
-                              int length,
-                              int start_point);
-
 void det_HhH(int32_t *after_mf_00,
              int32_t *after_mf_01,
              int32_t *after_mf_10,
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 6dcce5df0a238ca61ad7f08a565e2a2bac1e9133..9be2d0208d5c4e4e2e21cb8de525561db2238c5b 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -800,6 +800,13 @@ typedef struct PHY_VARS_gNB_s {
   /// PDSCH DMRS sequence
   uint32_t ****nr_gold_pdsch_dmrs;
 
+  /// PDSCH codebook I precoding LUTs
+  /// first dimension: Rank number [0,...,noOfLayers-1[
+  /// second dimension: PMI [0,...,CodeSize-1[
+  /// third dimension: [i_rows*noOfLayers+j_col], i_rows=0,...pdsch_AntennaPorts-1 and j_col=0,...,noOfLayers-1
+  int32_t ***nr_mimo_precoding_matrix;
+  int pmiq_size[NR_MAX_NB_LAYERS];
+
   /// PUSCH DMRS
   uint32_t ****nr_gold_pusch_dmrs;
 
@@ -845,6 +852,9 @@ typedef struct PHY_VARS_gNB_s {
   /// counter to average prach energh over first 100 prach opportunities
   int prach_energy_counter;
 
+  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 04080e72150326f7046a971084135750990836c1..8a533be5eb1ab9a11a88bcc80f32f5a46f0897e5 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -183,7 +183,7 @@ typedef struct {
   //! estimated rssi (dBm)
   short          rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX];
   //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
-  int            rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][4][4];
+  int            rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS];//
   //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
   int            rx_correlation_dB[NUMBER_OF_CONNECTED_gNB_MAX][2];
 
@@ -271,12 +271,6 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **rxdataF_comp0;
-  /// \brief Received frequency-domain signal after extraction and channel compensation for the second stream. For the SIC receiver we need to store the history of this for each harq process and round
-  /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid
-  /// - second index: ? [0..7] (hard coded) accessed via \c round
-  /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - fourth index: ? [0..168*N_RB_DL[
-  int32_t **rxdataF_comp1[8][8];
   /// \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)[
@@ -289,12 +283,6 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_ch_ptrs_estimates_ext;
-  /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round
-  /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid
-  /// - second index: ? [0..7] (hard coded) accessed via \c round
-  /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - fourth index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_rho_ext[8][8];
   /// \brief Downlink beamforming 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)[
@@ -303,10 +291,6 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_bf_ch_estimates_ext;
-  /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_rho2_ext;
   /// \brief Downlink PMIs extracted in PRBS and grouped in subbands.
   /// - first index: ressource block [0..N_RB_DL[
   uint8_t *pmi_ext;
@@ -314,18 +298,10 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_ch_mag0;
-  /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level).
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_mag1[8][8];
   /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level).
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_ch_magb0;
-  /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level).
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_magb1[8][8];
   /// \brief Magnitude of Downlink Channel, first layer (256QAM level).
   int32_t **dl_ch_magr0;
   /// \brief Cross-correlation Matrix of the gNB Tx channel signals.
@@ -595,10 +571,6 @@ typedef struct {
   /// - 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: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_rho_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;
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index 0a58ff3dc18311ea05047866f5f29f5a3078d54c..561e2f3d93f65a9789f6844a6eafe5a26b97df8d 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -322,7 +322,7 @@ struct NR_DL_FRAME_PARMS {
   uint32_t samples_per_frame_wCP;
   /// NR numerology index [0..5] as specified in 38.211 Section 4 (mu). 0=15khZ SCS, 1=30khZ, 2=60kHz, etc
   uint8_t numerology_index;
-  /// Number of Physical transmit antennas in node
+  /// Number of Physical transmit antennas in node (corresponds to nrOfAntennaPorts)
   uint8_t nb_antennas_tx;
   /// Number of Receive antennas in node
   uint8_t nb_antennas_rx;
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index c3ff79ab071ec316797df97d6354ab7c73185f5c..fdd0d2295e34c06ba186be35191436a023c0d055 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -207,7 +207,7 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
 
 void config_common(int Mod_idP,
                    int ssb_SubcarrierOffset,
-                   int pdsch_AntennaPorts,
+                   rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
                    int pusch_AntennaPorts,
 		   NR_ServingCellConfigCommon_t *scc
 		   );
@@ -537,8 +537,8 @@ int main(int argc, char **argv)
     case 'x':
       g_nrOfLayers=atoi(optarg);
 
-      if ((g_nrOfLayers!=1) &&
-          (g_nrOfLayers!=2)) {
+      if ((g_nrOfLayers==0) ||
+          (g_nrOfLayers>4)) {
         printf("Unsupported nr Of Layers %d\n",g_nrOfLayers);
         exit(-1);
       }
@@ -784,12 +784,27 @@ int main(int argc, char **argv)
   fix_scc(scc,ssb_bitmap);
   prepare_scd(scd);
 
+  rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts;
+  pdsch_AntennaPorts.N1 = n_tx>1 ? n_tx>>1 : 1;
+  pdsch_AntennaPorts.N2 = 1;
+  pdsch_AntennaPorts.XP = n_tx>1 ? 2 : 1;
+  gNB->ap_N1 = pdsch_AntennaPorts.N1;
+  gNB->ap_N2 = pdsch_AntennaPorts.N2;
+  gNB->ap_XP = pdsch_AntennaPorts.XP;
+
   NR_UE_NR_Capability_t* UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
   prepare_sim_uecap(UE_Capability_nr,scc,mu,
                     N_RB_DL,g_mcsTableIdx);
 
   // TODO do a UECAP for phy-sim
-  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, UE_Capability_nr, 0, 1, n_tx, 6, 0, 0, 0);
+  const gNB_RrcConfigurationReq conf = {
+    .pdsch_AntennaPorts = pdsch_AntennaPorts,
+    .minRXTXTIME = 6,
+    .do_CSIRS = 0,
+    .do_SRS = 0,
+    .force_256qam_off = false
+  };
+  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, UE_Capability_nr, 0, 1, &conf, 0);
 
   /* RRC parameter validation for secondaryCellGroup */
   fix_scd(scd);
@@ -807,10 +822,11 @@ int main(int argc, char **argv)
 
   AssertFatal((gNB->if_inst         = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
   gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
+
   // common configuration
-  rrc_mac_config_req_gNB(0,0, n_tx, n_tx, 0, 6, scc, NULL, 0, 0, NULL);
+  rrc_mac_config_req_gNB(0,0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, 0, 0, NULL);
   // UE dedicated configuration
-  rrc_mac_config_req_gNB(0,0, n_tx, n_tx, 0, 6, scc, NULL, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
+  rrc_mac_config_req_gNB(0,0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
   // reset preprocessor to the one of DLSIM after it has been set during
   // rrc_mac_config_req_gNB
   gNB_mac->pre_processor_dl = nr_dlsim_preprocessor;
@@ -1202,10 +1218,10 @@ int main(int argc, char **argv)
                              frame_length_complex_samples,
                              0);
 
-        double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0
-                                   {0.5, 1.0, 0.5, 0.25},  //rx 1
-                                   {0.25, 0.5, 1.0, 0.5},  //rx 2
-                                   {0.125, 0.25, 0.5, 1.0}};//rx 3
+        double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0
+                                   {0.2, 1.0, 0.2, 0.1}, //rx 1
+                                   {0.1, 0.2, 1.0, 0.2}, //rx 2
+                                   {0.05, 0.1, 0.2, 1.0}};//rx 3
 
         for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); 
              i<frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0);
@@ -1260,7 +1276,7 @@ int main(int argc, char **argv)
       TBS                  = UE_harq_process->TBS;//rel15->TBSize[0];
       uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
       uint16_t nb_rb       = rel15->rbSize;
-      uint8_t  nb_re_dmrs  = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
+      uint8_t  nb_re_dmrs  = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*UE_harq_process->n_dmrs_cdm_groups : 4*UE_harq_process->n_dmrs_cdm_groups;
       uint8_t  mod_order   = rel15->qamModOrder[0];
       uint8_t  nb_symb_sch = rel15->NrOfSymbols;
 
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 5e4ae2deb7acf4b4ee3b81b41fdd9ef9e24e9538..bc612457c0af95e005c2b13c29212ee071a138f3 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -731,7 +731,14 @@ int main(int argc, char **argv)
   prepare_scd(scd);
 
   // TODO do a UECAP for phy-sim
-  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, NULL, 0, 1, n_tx, 0, 0, 0, 0);
+  const gNB_RrcConfigurationReq conf = {
+    .pdsch_AntennaPorts = { .N1 = n_tx, .N2 = 1, .XP = 1 },
+    .minRXTXTIME = 0,
+    .do_CSIRS = 0,
+    .do_SRS = 0,
+    .force_256qam_off = false
+  };
+  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, NULL, 0, 1, &conf, 0);
 
   // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
 
@@ -742,9 +749,9 @@ int main(int argc, char **argv)
 
   gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
   // common configuration
-  rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, 6, scc, &rrc.carrier.mib,0, 0, NULL);
+  rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib,0, 0, NULL);
   // UE dedicated configuration
-  rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, 6, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
+  rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
   frame_parms->nb_antennas_tx = n_tx;
   frame_parms->nb_antennas_rx = n_rx;
   nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 769bc7d01d3bffd3569651dc1cb34d0bda946b8d..6b41970735d140ee46c882eb95ca8e1a1e21decc 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -401,6 +401,12 @@ typedef struct NbIoTRrcConfigurationReq_s {
   long                    ue_TimersAndConstants_n311_NB;
 } NbIoTRrcConfigurationReq;
 
+typedef struct {
+  int N1;
+  int N2;
+  int XP;
+} rrc_pdsch_AntennaPorts_t;
+
 // gNB: GNB_APP -> RRC messages
 typedef struct NRRrcConfigurationReq_s {
   uint64_t                cell_identity;
@@ -413,11 +419,12 @@ typedef struct NRRrcConfigurationReq_s {
   NR_ServingCellConfig_t  *scd;
   int                     ssb_SubcarrierOffset;
   int                     sib1_tda;
-  int                     pdsch_AntennaPorts;
+  rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts;
   int                     pusch_AntennaPorts;
   int                     minRXTXTIME;
   int                     do_CSIRS;
   int                     do_SRS;
+  bool                    force_256qam_off;
   int                     pusch_TargetSNRx10;
   int                     pucch_TargetSNRx10;
 } gNB_RrcConfigurationReq;
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index f5ff7ddf9e6ebd05324cc4e27f0ff721e4532a41..e9fcee662289808d21ec527da1720872ed7e629a 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -621,8 +621,11 @@ void RCconfig_NR_L1(void) {
   int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
   AssertFatal (num_gnbs > 0,"Failed to parse config file no gnbs %s \n",GNB_CONFIG_STRING_ACTIVE_GNBS);
 
-  config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL); 
-  char *ulprbbl = *GNBParamList.paramarray[0][GNB_ULPRBBLACKLIST_IDX].strptr; 
+  config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
+  int N1 = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr;
+  int N2 = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_N2_IDX].iptr;
+  int XP = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_XP_IDX].iptr;
+  char *ulprbbl = *GNBParamList.paramarray[0][GNB_ULPRBBLACKLIST_IDX].strptr;
   if (ulprbbl) LOG_I(NR_PHY,"PRB blacklist %s\n",ulprbbl);
   char *save = NULL;
   char *pt = strtok_r(ulprbbl, ",", &save);
@@ -669,6 +672,9 @@ void RCconfig_NR_L1(void) {
       RC.gNB[j]->prach_thres        = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD].uptr);
       RC.gNB[j]->pusch_thres        = *(L1_ParamList.paramarray[j][L1_PUSCH_DTX_THRESHOLD].uptr);
       RC.gNB[j]->num_ulprbbl        = num_prbbl;
+      RC.gNB[j]->ap_N1              = N1;
+      RC.gNB[j]->ap_N2              = N2;
+      RC.gNB[j]->ap_XP              = XP;
       LOG_I(NR_PHY,"Copying %d blacklisted PRB to L1 context\n",num_prbbl);
       memcpy(RC.gNB[j]->ulprbbl,prbbl,275*sizeof(int));
       if(strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) {
@@ -1166,8 +1172,12 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
 	}
         LOG_I(RRC,"SSB SCO %d\n",*GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr);
         NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = *GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr;
-        LOG_I(RRC,"pdsch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr);
-        NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr;
+        LOG_I(RRC,"pdsch_AntennaPorts N1 %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr);
+        NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts.N1 = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr;
+        LOG_I(RRC,"pdsch_AntennaPorts N2 %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N2_IDX].iptr);
+        NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts.N2 = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N2_IDX].iptr;
+        LOG_I(RRC,"pdsch_AntennaPorts XP %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_XP_IDX].iptr);
+        NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts.XP = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_XP_IDX].iptr;
         LOG_I(RRC,"pusch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_ANTENNAPORTS_IDX].iptr);
         NRRRC_CONFIGURATION_REQ (msg_p).pusch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PUSCH_ANTENNAPORTS_IDX].iptr;
         LOG_I(RRC,"minTXRXTIME %d\n",*GNBParamList.paramarray[i][GNB_MINRXTXTIME_IDX].iptr);
@@ -1176,8 +1186,10 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
         NRRRC_CONFIGURATION_REQ (msg_p).sib1_tda = *GNBParamList.paramarray[i][GNB_SIB1_TDA_IDX].iptr;
         LOG_I(RRC,"Do CSI-RS %d\n",*GNBParamList.paramarray[i][GNB_DO_CSIRS_IDX].iptr);
         NRRRC_CONFIGURATION_REQ (msg_p).do_CSIRS = *GNBParamList.paramarray[i][GNB_DO_CSIRS_IDX].iptr;
-        printf("Do SRS %d\n",*GNBParamList.paramarray[i][GNB_DO_SRS_IDX].iptr);
+        LOG_I(RRC, "Do SRS %d\n",*GNBParamList.paramarray[i][GNB_DO_SRS_IDX].iptr);
         NRRRC_CONFIGURATION_REQ (msg_p).do_SRS = *GNBParamList.paramarray[i][GNB_DO_SRS_IDX].iptr;
+        NRRRC_CONFIGURATION_REQ (msg_p).force_256qam_off = *GNBParamList.paramarray[i][GNB_FORCE256QAMOFF_IDX].iptr;
+        LOG_I(RRC, "256 QAM: %s\n", NRRRC_CONFIGURATION_REQ (msg_p).force_256qam_off ? "force off" : "may be on");
         NRRRC_CONFIGURATION_REQ (msg_p).scc = scc;
         NRRRC_CONFIGURATION_REQ (msg_p).scd = scd;
 	  
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index cde7819e2556070fd095a0195e17db6fd60a43e6..e1d3d93d0b2f91d569e127fc122e518e5779d9f8 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -114,7 +114,9 @@ typedef enum {
 #define GNB_CONFIG_STRING_LOCAL_S_PORTD                 "local_s_portd"
 #define GNB_CONFIG_STRING_REMOTE_S_PORTD                "remote_s_portd"
 #define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET           "ssb_SubcarrierOffset"
-#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS             "pdsch_AntennaPorts"
+#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N1          "pdsch_AntennaPorts_N1"
+#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N2          "pdsch_AntennaPorts_N2"
+#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_XP          "pdsch_AntennaPorts_XP"
 #define GNB_CONFIG_STRING_PUSCHANTENNAPORTS             "pusch_AntennaPorts"
 #define GNB_CONFIG_STRING_SIB1TDA                       "sib1_tda"
 #define GNB_CONFIG_STRING_DOCSIRS                       "do_CSIRS"
@@ -122,8 +124,11 @@ typedef enum {
 #define GNB_CONFIG_STRING_NRCELLID                      "nr_cellid"
 #define GNB_CONFIG_STRING_MINRXTXTIME                   "min_rxtxtime"
 #define GNB_CONFIG_STRING_ULPRBBLACKLIST                "ul_prbblacklist"
+#define GNB_CONFIG_STRING_FORCE256QAMOFF                "force_256qam_off"
 
 
+#define GNB_CONFIG_HLP_FORCE256QAMOFF                   "suppress activation of 256 QAM despite UE support"
+
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            cell configuration parameters                                                                */
 /*   optname                                   helpstr   paramflags    XXXptr        defXXXval                   type           numelt     */
@@ -144,14 +149,17 @@ typedef enum {
 {GNB_CONFIG_STRING_LOCAL_S_PORTD,                NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
 {GNB_CONFIG_STRING_REMOTE_S_PORTD,               NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
 {GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET,          NULL,   0,            iptr:NULL,   defintval:31,                TYPE_INT,       0},  \
-{GNB_CONFIG_STRING_PDSCHANTENNAPORTS,            NULL,   0,            iptr:NULL,   defintval:1,                 TYPE_INT,       0},  \
+{GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N1, "horiz. log. antenna ports", 0, iptr:NULL, defintval:1,                 TYPE_INT,       0},  \
+{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_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},  \
 {GNB_CONFIG_STRING_MINRXTXTIME,                  NULL,   0,            iptr:NULL,   defintval:2,                 TYPE_INT,       0},  \
-{GNB_CONFIG_STRING_ULPRBBLACKLIST,               NULL,   0,            strptr:NULL, defstrval:"",                TYPE_STRING,    0}   \
+{GNB_CONFIG_STRING_ULPRBBLACKLIST,               NULL,   0,            strptr:NULL, defstrval:"",                TYPE_STRING,    0},  \
+{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, iptr:NULL, defintval:0,        TYPE_INT,       0}   \
 }
 
 #define GNB_GNB_ID_IDX                  0
@@ -169,14 +177,17 @@ typedef enum {
 #define GNB_LOCAL_S_PORTD_IDX           12
 #define GNB_REMOTE_S_PORTD_IDX          13
 #define GNB_SSB_SUBCARRIEROFFSET_IDX    14
-#define GNB_PDSCH_ANTENNAPORTS_IDX      15
-#define GNB_PUSCH_ANTENNAPORTS_IDX      16
-#define GNB_SIB1_TDA_IDX                17
-#define GNB_DO_CSIRS_IDX                18
-#define GNB_DO_SRS_IDX                  19
-#define GNB_NRCELLID_IDX                20
-#define GNB_MINRXTXTIME_IDX             21
-#define GNB_ULPRBBLACKLIST_IDX          22
+#define GNB_PDSCH_ANTENNAPORTS_N1_IDX   15
+#define GNB_PDSCH_ANTENNAPORTS_N2_IDX   16
+#define GNB_PDSCH_ANTENNAPORTS_XP_IDX   17
+#define GNB_PUSCH_ANTENNAPORTS_IDX      18
+#define GNB_SIB1_TDA_IDX                19
+#define GNB_DO_CSIRS_IDX                20
+#define GNB_DO_SRS_IDX                  21
+#define GNB_NRCELLID_IDX                22
+#define GNB_MINRXTXTIME_IDX             23
+#define GNB_ULPRBBLACKLIST_IDX          24
+#define GNB_FORCE256QAMOFF_IDX          25
 
 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
 #define GNBPARAMS_CHECK {                                         \
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 3bc45b42ca87e86620145d1cfc93531eb144815b..988dc7ca0ff67d0b6b10c5bb9cb8f065bed59c33 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -160,11 +160,11 @@ void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sche
 
 }
 
-void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
+void config_common(int Mod_idP, int ssb_SubcarrierOffset, rrc_pdsch_AntennaPorts_t dl_antenna_ports_struct, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
 
   nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0];
   RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc;
-  int i;
+  int pdsch_AntennaPorts = dl_antenna_ports_struct.N1 * dl_antenna_ports_struct.N2 * dl_antenna_ports_struct.XP;
 
   // Carrier configuration
 
@@ -181,7 +181,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
   cfg->carrier_config.dl_frequency.tl.tag = NFAPI_NR_CONFIG_DL_FREQUENCY_TAG;
   cfg->num_tlv++;
 
-  for (i=0; i<5; i++) {
+  for (int i=0; i<5; i++) {
     if (i==scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
       cfg->carrier_config.dl_grid_size[i].value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
       cfg->carrier_config.dl_k0[i].value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
@@ -215,7 +215,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
   cfg->carrier_config.uplink_frequency.tl.tag = NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG;
   cfg->num_tlv++;
 
-  for (i=0; i<5; i++) {
+  for (int i=0; i<5; i++) {
     if (i==scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
       cfg->carrier_config.ul_grid_size[i].value = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
       cfg->carrier_config.ul_k0[i].value = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
@@ -306,7 +306,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
   cfg->num_tlv++;
 
   cfg->prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions.value*sizeof(nfapi_nr_num_prach_fd_occasions_t));
-  for (i=0; i<cfg->prach_config.num_prach_fd_occasions.value; i++) {
+  for (int i=0; i<cfg->prach_config.num_prach_fd_occasions.value; i++) {
 //    cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
     if (cfg->prach_config.prach_sequence_length.value)
       cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139; 
@@ -375,7 +375,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
     case 3 :
       cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = 0;
       cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0;
-      for (i=0; i<4; i++) {
+      for (int i=0; i<4; i++) {
         cfg->ssb_table.ssb_mask_list[0].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<<i*8);
         cfg->ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<<i*8);
       }
@@ -414,7 +414,8 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
   cfg->carrier_config.num_rx_ant.value = pusch_AntennaPorts;
   AssertFatal(pusch_AntennaPorts > 0 && pusch_AntennaPorts < 13, "pusch_AntennaPorts in 1...12\n");
   cfg->carrier_config.num_rx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_RX_ANT_TAG;
-  LOG_I(NR_MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value);
+  LOG_I(NR_MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",
+        cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value);
   AssertFatal(cfg->carrier_config.num_tx_ant.value > 0,"carrier_config.num_tx_ant.value %d !\n",cfg->carrier_config.num_tx_ant.value );
   cfg->num_tlv++;
   cfg->num_tlv++;
@@ -451,7 +452,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
 
 int rrc_mac_config_req_gNB(module_id_t Mod_idP,
                            int ssb_SubcarrierOffset,
-                           int pdsch_AntennaPorts,
+                           rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
                            int pusch_AntennaPorts,
                            int sib1_tda,
                            int minRXTXTIMEpdsch,
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 8b734e3b950b7f50212c7c514a3a5cabf7a60ea8..c9b8be2c4a26613105509b5724925299697a3e41 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -40,14 +40,14 @@ void mac_top_init_gNB(void);
 
 void config_common(int Mod_idP,
                    int ssb_SubcarrierOffset,
-                   int pdsch_AntennaPorts,
+                   rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
                    int pusch_AntennaPorts,
 		   NR_ServingCellConfigCommon_t *scc
 		   );
 
 int rrc_mac_config_req_gNB(module_id_t Mod_idP,
                            int ssb_SubcarrierOffset,
-                           int pdsch_AntennaPorts,
+                           rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
                            int pusch_AntennaPorts,
                            int sib1_tda,
                            int minRXTXTIMEpdsch,
diff --git a/openair2/PHY_INTERFACE/queue_t.h b/openair2/PHY_INTERFACE/queue_t.h
index 4678e310301ac4934ca1f7e2c241e18f481a01c4..5c644a320cf6ace6da00c7a4aa596c400d310ea6 100644
--- a/openair2/PHY_INTERFACE/queue_t.h
+++ b/openair2/PHY_INTERFACE/queue_t.h
@@ -24,7 +24,8 @@
     }
 */
 
-#pragma once
+#ifndef __OPENAIR2_PHY_INTERFACE_QUEUE_T__H__
+#define __OPENAIR2_PHY_INTERFACE_QUEUE_T__H__
 
 #include <stdbool.h>
 #include <stdint.h>
@@ -62,3 +63,5 @@ typedef bool queue_matcher_t(void *wanted, void *candidate);
    Look only at the last `max_depth` items on the queue, at most.
    Returns the candidate item, or NULL if none matches */
 void *unqueue_matching(queue_t *q, size_t max_depth, queue_matcher_t *matcher, void *wanted);
+
+#endif  /* __OPENAIR2_PHY_INTERFACE_QUEUE_T__H__ */
diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h
index d1d1d3febe15254bac219f28f439bd1578b8a749..8373bb53f330b0c7bae733322ea0ace7089fd318 100644
--- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h
@@ -28,6 +28,9 @@
 * \email: raymond.knopp@eurecom.fr and  navid.nikaein@eurecom.fr
 */
 
+#ifndef __RRC_LTE_MESSAGES_ASN1_MSG__H__
+#define __RRC_LTE_MESSAGES_ASN1_MSG__H__
+
 #include <stdio.h>
 #include <sys/types.h>
 #include <stdlib.h> /* for atoi(3) */
@@ -405,3 +408,5 @@ uint8_t do_SecurityModeCommand(
   const uint8_t Transaction_id,
   const uint8_t cipheringAlgorithm,
   const uint8_t integrityProtAlgorithm);
+
+#endif  /* __RRC_LTE_MESSAGES_ASN1_MSG__H__ */
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index 1cf690ac0c064ac68e1d8b35f64ff77507a3ed97..e30b55cc94dfe346f132f8cd095ec2c841848cd0 100644
--- a/openair2/RRC/NR/L2_nr_interface.c
+++ b/openair2/RRC/NR/L2_nr_interface.c
@@ -321,7 +321,7 @@ int8_t nr_mac_rrc_data_ind(const module_id_t     module_idP,
     ue_context_p->ue_context.Srb0.Active        = 1;
     RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[module_idP]->rrc_ue_head, ue_context_p);
 
-    fill_initial_cellGroupConfig(ue_context_p->local_uid,&cellGroupConfig,scc,&RC.nrrrc[module_idP]->carrier);
+    fill_initial_cellGroupConfig(ue_context_p->local_uid,&cellGroupConfig,scc, &RC.nrrrc[module_idP]->configuration);
 
     MessageDef* tmp=itti_alloc_new_message_sized(TASK_RRC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE, sizeof(f1ap_initial_ul_rrc_message_t) + sdu_lenP);
     f1ap_initial_ul_rrc_message_t *msg = &F1AP_INITIAL_UL_RRC_MESSAGE(tmp);
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index d04ed78270f0efd56ef135bd6b3cd2760128b4ff..9a59d1977ac2754ca03a150fe450c8d4d0312ecc 100755
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -197,6 +197,7 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) {
 
   asn_enc_rval_t enc_rval;
   rrc_gNB_carrier_data_t *carrier = &rrc->carrier;  
+  const gNB_RrcConfigurationReq *configuration = &rrc->configuration;
 
   NR_BCCH_BCH_Message_t *mib = &carrier->mib;
   NR_ServingCellConfigCommon_t *scc = carrier->servingcellconfigcommon;
@@ -220,7 +221,7 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) {
   mib->message.choice.mib->spare.size = 1;
   mib->message.choice.mib->spare.bits_unused = 7;  // This makes a spare of 1 bits
 
-  mib->message.choice.mib->ssb_SubcarrierOffset = (carrier->ssb_SubcarrierOffset)&15;
+  mib->message.choice.mib->ssb_SubcarrierOffset = (configuration->ssb_SubcarrierOffset)&15;
 
   /*
   * The SIB1 will be sent in this allocation (Type0-PDCCH) : 38.213, 13-4 Table and 38.213 13-11 to 13-14 tables
@@ -1007,8 +1008,8 @@ long rrc_get_max_nr_csrs(uint8_t max_rbs, long b_SRS) {
 void fill_initial_SpCellConfig(int uid,
                                NR_SpCellConfig_t *SpCellConfig,
                                NR_ServingCellConfigCommon_t *scc,
-                               rrc_gNB_carrier_data_t *carrier) {
-
+                               const gNB_RrcConfigurationReq *configuration)
+{
   // This assert will never happen in the current implementation because NUMBER_OF_UE_MAX = 4.
   // However, if in the future NUMBER_OF_UE_MAX is increased, it will be necessary to improve the allocation of SRS resources,
   // where the startPosition = 2 or 3 and sl160 = 17, 17, 27 ... 157 only give us 30 different allocations.
@@ -1139,7 +1140,7 @@ void fill_initial_SpCellConfig(int uid,
   ASN_SEQUENCE_ADD(&srs_resset0->srs_ResourceIdList->list,srs_resset0_id);
   srs_Config->srs_ResourceToReleaseList=NULL;
 
-  if(carrier->do_SRS) {
+  if (configuration->do_SRS) {
     srs_resset0->resourceType.present =  NR_SRS_ResourceSet__resourceType_PR_periodic;
     srs_resset0->resourceType.choice.periodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.periodic));
     srs_resset0->resourceType.choice.periodic->associatedCSI_RS = NULL;
@@ -1183,7 +1184,7 @@ void fill_initial_SpCellConfig(int uid,
       srs_res0->freqHopping.b_SRS);
   srs_res0->groupOrSequenceHopping=NR_SRS_Resource__groupOrSequenceHopping_neither;
 
-  if(carrier->do_SRS) {
+  if (configuration->do_SRS) {
     srs_res0->resourceType.present= NR_SRS_Resource__resourceType_PR_periodic;
     srs_res0->resourceType.choice.periodic=calloc(1,sizeof(*srs_res0->resourceType.choice.periodic));
     srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl160;
@@ -1229,9 +1230,9 @@ void fill_initial_SpCellConfig(int uid,
  long *delay[8];
  for (int i=0;i<8;i++) {
    delay[i] = calloc(1,sizeof(*delay[i]));
-   AssertFatal(carrier->minRXTXTIME >=2 && carrier->minRXTXTIME <7,
-               "check minRXTXTIME %d\n",carrier->minRXTXTIME);
-   *delay[i] = (i+carrier->minRXTXTIME);
+   AssertFatal(configuration->minRXTXTIME >= 2 && configuration->minRXTXTIME < 7,
+               "minRXTXTIME is %d but should be within [2,7)\n", configuration->minRXTXTIME);
+   *delay[i] = i + configuration->minRXTXTIME;
    ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]);
  }
 
@@ -1453,8 +1454,9 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGr
 
 void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
                             rrc_gNB_carrier_data_t *carrier,
-                            NR_UE_NR_Capability_t *uecap) {
-
+                            NR_UE_NR_Capability_t *uecap,
+                            const gNB_RrcConfigurationReq* configuration)
+{
   NR_SpCellConfig_t *SpCellConfig = cellGroupConfig->spCellConfig;
   if (SpCellConfig == NULL) return;
 
@@ -1462,14 +1464,14 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
 
   NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP;
   set_dl_mcs_table(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing,
-                   uecap, bwp_Dedicated, scc);
+                   configuration->force_256qam_off ? NULL : uecap, bwp_Dedicated, scc);
 
   struct NR_ServingCellConfig__downlinkBWP_ToAddModList *DL_BWP_list = SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
   if (DL_BWP_list) {
     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, uecap, bwp->bwp_Dedicated, carrier->servingcellconfigcommon);
+      set_dl_mcs_table(scs, configuration->force_256qam_off ? NULL : uecap, bwp->bwp_Dedicated, carrier->servingcellconfigcommon);
     }
   }
 }
@@ -1478,8 +1480,8 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
 void fill_initial_cellGroupConfig(int uid,
                                   NR_CellGroupConfig_t *cellGroupConfig,
                                   NR_ServingCellConfigCommon_t *scc,
-                                  rrc_gNB_carrier_data_t *carrier) {
-
+                                  const gNB_RrcConfigurationReq *configuration)
+{
   NR_RLC_BearerConfig_t                            *rlc_BearerConfig     = NULL;
   NR_RLC_Config_t                                  *rlc_Config           = NULL;
   NR_LogicalChannelConfig_t                        *logicalChannelConfig = NULL;
@@ -1569,7 +1571,7 @@ void fill_initial_cellGroupConfig(int uid,
   
   cellGroupConfig->spCellConfig                                             = calloc(1,sizeof(*cellGroupConfig->spCellConfig));
   
-  fill_initial_SpCellConfig(uid,cellGroupConfig->spCellConfig,scc,carrier);
+  fill_initial_SpCellConfig(uid,cellGroupConfig->spCellConfig,scc,configuration);
   
   cellGroupConfig->sCellToAddModList                                        = NULL;
   cellGroupConfig->sCellToReleaseList                                       = NULL;
@@ -1581,7 +1583,7 @@ uint8_t do_RRCSetup(rrc_gNB_ue_context_t         *const ue_context_pP,
                     const uint8_t                transaction_id,
                     OCTET_STRING_t               *masterCellGroup_from_DU,
                     NR_ServingCellConfigCommon_t *scc,
-                    rrc_gNB_carrier_data_t *carrier)
+                    const gNB_RrcConfigurationReq *configuration)
 //------------------------------------------------------------------------------
 {
     asn_enc_rval_t                                   enc_rval;
@@ -1648,7 +1650,7 @@ uint8_t do_RRCSetup(rrc_gNB_ue_context_t         *const ue_context_pP,
     }
     else {
       cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
-      fill_initial_cellGroupConfig(ue_context_pP->local_uid,cellGroupConfig,scc,carrier);
+      fill_initial_cellGroupConfig(ue_context_pP->local_uid, cellGroupConfig, scc, configuration);
 
       enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
 				       NULL,
@@ -1896,6 +1898,7 @@ int16_t do_RRCReconfiguration(
     struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList,
     rrc_gNB_ue_context_t         *const ue_context_pP,
     rrc_gNB_carrier_data_t       *carrier,
+    const gNB_RrcConfigurationReq *configuration,
     NR_MAC_CellGroupConfig_t     *mac_CellGroupConfig,
     NR_CellGroupConfig_t         *cellGroupConfig)
 //------------------------------------------------------------------------------
@@ -1949,7 +1952,8 @@ int16_t do_RRCReconfiguration(
     if(cellGroupConfig!=NULL){
       update_cellGroupConfig(cellGroupConfig,
                              carrier,
-                             ue_context_pP->ue_context.UE_Capability_nr);
+                             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 7fe08704c2bdb64d0f90ea71e48a851ed34553ec..52efba6f45dba44099631f0f840f818d4c47fcb7 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h
@@ -28,7 +28,8 @@
 * \email: raymond.knopp@eurecom.fr and  navid.nikaein@eurecom.fr, kroempa@gmail.com
 */
 
-#pragma once
+#ifndef __RRC_NR_MESSAGES_ASN1_MSG__H__
+#define __RRC_NR_MESSAGES_ASN1_MSG__H__
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -101,18 +102,19 @@ uint8_t do_RRCReject(uint8_t Mod_id,
                      uint8_t *const buffer);
 
 void fill_initial_SpCellConfig(int uid,
-			       NR_SpCellConfig_t *SpCellConfig,
-			       NR_ServingCellConfigCommon_t *scc,
-                               rrc_gNB_carrier_data_t *carrier);
+                               NR_SpCellConfig_t *SpCellConfig,
+                               NR_ServingCellConfigCommon_t *scc,
+                               const gNB_RrcConfigurationReq *configuration);
 
 void fill_initial_cellGroupConfig(int uid,
-				  NR_CellGroupConfig_t *cellGroupConfig,
-				  NR_ServingCellConfigCommon_t *scc,
-                                  rrc_gNB_carrier_data_t *carrier);
+                                  NR_CellGroupConfig_t *cellGroupConfig,
+                                  NR_ServingCellConfigCommon_t *scc,
+                                  const gNB_RrcConfigurationReq *configuration);
 
 void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
                             rrc_gNB_carrier_data_t *carrier,
-                            NR_UE_NR_Capability_t *uecap);
+                            NR_UE_NR_Capability_t *uecap,
+                            const gNB_RrcConfigurationReq *configuration);
 
 void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup);
 
@@ -121,7 +123,7 @@ uint8_t do_RRCSetup(rrc_gNB_ue_context_t         *const ue_context_pP,
                     const uint8_t                transaction_id,
                     OCTET_STRING_t               *masterCellGroup_from_DU,
                     NR_ServingCellConfigCommon_t *scc,
-                    rrc_gNB_carrier_data_t *carrier);
+                    const gNB_RrcConfigurationReq *configuration);
 
 uint8_t do_NR_SecurityModeCommand(
                     const protocol_ctxt_t *const ctxt_pP,
@@ -151,6 +153,7 @@ int16_t do_RRCReconfiguration(
     struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList,
     rrc_gNB_ue_context_t         *const ue_context_pP,
     rrc_gNB_carrier_data_t       *carrier,
+    const gNB_RrcConfigurationReq *configuration,
     NR_MAC_CellGroupConfig_t     *mac_CellGroupConfig,
     NR_CellGroupConfig_t         *cellGroupConfig);
 
@@ -205,3 +208,4 @@ do_RRCReestablishmentComplete(
     uint8_t *buffer, size_t buffer_size,
     int64_t rrc_TransactionIdentifier);
 
+#endif  /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index 1b2c38c8356e90cc5a4daff789b2d86f9e2797ae..b26f8243a073195e47f4e02eece9ce61f5a89709 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -424,7 +424,6 @@ typedef struct rrc_gNB_ue_context_s {
   struct gNB_RRC_UE_s   ue_context;
 } rrc_gNB_ue_context_t;
 
-
 typedef struct {
 
   // buffer that contains the encoded messages
@@ -449,13 +448,6 @@ typedef struct {
   NR_SIB2_t                                *sib2;
   NR_SIB3_t                                *sib3;
   NR_BCCH_DL_SCH_Message_t                  systemInformation; // SIB23
-  int ssb_SubcarrierOffset;
-  int sib1_tda;
-  int pdsch_AntennaPorts;
-  int pusch_AntennaPorts;
-  int minRXTXTIME;
-  int do_CSIRS;
-  int do_SRS;
   NR_BCCH_DL_SCH_Message_t                  *siblock1;
   NR_ServingCellConfigCommon_t              *servingcellconfigcommon;
   NR_PDCCH_ConfigSIB1_t                     *pdcch_ConfigSIB1;
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index 7dceb55a4bb98444e7534708665e3419dcaa880b..f1462fee341012b4b07aa2fe51f81dd908481446 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -79,10 +79,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
                                      NR_UE_NR_Capability_t *uecap,
                                      int scg_id,
                                      int servCellIndex,
-                                     int dl_antenna_ports,
-                                     int minRXTXTIMEpdsch,
-                                     int do_csirs,
-                                     int do_srs,
+                                     const gNB_RrcConfigurationReq *configuration,
                                      int uid);
 
 void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
@@ -96,10 +93,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
                            NR_RRCReconfiguration_IEs_t *reconfig,
                            NR_CellGroupConfig_t *secondaryCellGroup,
                            NR_UE_NR_Capability_t *uecap,
-                           int dl_antenna_ports,
-                           int minRXTXTIMEpdsch,
-                           int do_csirs,
-                           int do_srs,
+                           const gNB_RrcConfigurationReq *configuration,
                            int uid);
 
 void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index d6c658f01d1f3fa61780b30a5a155ff0e7ddac57..86b767f83cd39d0bfe76ceacc4b361c14326339a 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -166,17 +166,16 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
 
   if (NODE_IS_MONOLITHIC(rrc->node_type)){
     rrc_mac_config_req_gNB(rrc->module_id,
-			   rrc->carrier.ssb_SubcarrierOffset,
-			   rrc->carrier.pdsch_AntennaPorts,
-			   rrc->carrier.pusch_AntennaPorts,
-                           rrc->carrier.sib1_tda,
-                           rrc->carrier.minRXTXTIME,
-			   (NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon,
-			   &rrc->carrier.mib,
-			   0,
-			   0, // WIP hardcoded rnti
-			   (NR_CellGroupConfig_t *)NULL
-			   );
+                           rrc->configuration.ssb_SubcarrierOffset,
+                           rrc->configuration.pdsch_AntennaPorts,
+                           rrc->configuration.pusch_AntennaPorts,
+                           rrc->configuration.sib1_tda,
+                           rrc->configuration.minRXTXTIME,
+                           rrc->carrier.servingcellconfigcommon,
+                           &rrc->carrier.mib,
+                           0,
+                           0, // WIP hardcoded rnti
+                           NULL);
   }
 
   /* set flag to indicate that cell information is configured. This is required
@@ -216,14 +215,8 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
   rrc->s1ap_id2_s1ap_ids    = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL);
   rrc->initial_id2_ngap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL);
   rrc->ngap_id2_ngap_ids    = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL);
+  rrc->configuration = *configuration;
   rrc->carrier.servingcellconfigcommon = configuration->scc;
-  rrc->carrier.ssb_SubcarrierOffset = configuration->ssb_SubcarrierOffset;
-  rrc->carrier.pdsch_AntennaPorts = configuration->pdsch_AntennaPorts;
-  rrc->carrier.pusch_AntennaPorts = configuration->pusch_AntennaPorts;
-  rrc->carrier.minRXTXTIME = configuration->minRXTXTIME;
-  rrc->carrier.sib1_tda = configuration->sib1_tda;
-  rrc->carrier.do_CSIRS = configuration->do_CSIRS;
-  rrc->carrier.do_SRS = configuration->do_SRS;
   nr_rrc_config_ul_tda(configuration->scc,configuration->minRXTXTIME);
    /// System Information INIT
   pthread_mutex_init(&rrc->cell_info_mutex,NULL);
@@ -279,24 +272,25 @@ void apply_macrlc_config(gNB_RRC_INST *rrc,
                          rrc_gNB_ue_context_t         *const ue_context_pP,
                          const protocol_ctxt_t        *const ctxt_pP ) {
 
-      rrc_mac_config_req_gNB(rrc->module_id,
-			     rrc->carrier.ssb_SubcarrierOffset,
-			     rrc->carrier.pdsch_AntennaPorts,
-			     rrc->carrier.pusch_AntennaPorts,
-			     rrc->carrier.sib1_tda,
-                             rrc->carrier.minRXTXTIME,
-			     NULL,
-                             NULL,
-			     0,
-			     ue_context_pP->ue_context.rnti,
-			     get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : (NR_CellGroupConfig_t *)NULL);
+  NR_CellGroupConfig_t *cgc = get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : NULL;
+  rrc_mac_config_req_gNB(rrc->module_id,
+                         rrc->configuration.ssb_SubcarrierOffset,
+                         rrc->configuration.pdsch_AntennaPorts,
+                         rrc->configuration.pusch_AntennaPorts,
+                         rrc->configuration.sib1_tda,
+                         rrc->configuration.minRXTXTIME,
+                         NULL,
+                         NULL,
+                         0,
+                         ue_context_pP->ue_context.rnti,
+                         cgc);
 
-      nr_rrc_rlc_config_asn1_req(ctxt_pP,
-                                 ue_context_pP->ue_context.SRB_configList,
-                                 ue_context_pP->ue_context.DRB_configList,
-                                 NULL,
-                                 NULL,
-                                 get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
+  nr_rrc_rlc_config_asn1_req(ctxt_pP,
+                             ue_context_pP->ue_context.SRB_configList,
+                             ue_context_pP->ue_context.DRB_configList,
+                             NULL,
+                             NULL,
+                             get_softmodem_params()->sa ? cgc->rlc_BearerToAddModList : NULL);
 
 }
 
@@ -340,10 +334,11 @@ rrc_gNB_generate_RRCSetup(
   gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
   gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
   ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ue_context_pP,
-						  (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
-						  rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
-						  masterCellGroup_from_DU,
-						  scc,&rrc->carrier);
+                                                  (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
+                                                  rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
+                                                  masterCellGroup_from_DU,
+                                                  scc,
+                                                  &rrc->configuration);
 
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC,
               (char *)(ue_p->Srb0.Tx_buffer.Payload),
@@ -450,10 +445,11 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
 
   gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
   ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ue_context_pP,
-						  (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
-						  rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
-						  NULL,
-						  scc,&rrc_instance_p->carrier);
+                                                  (uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
+                                                  rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
+                                                  NULL,
+                                                  scc,
+                                                  &rrc_instance_p->configuration);
 
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC,
               (char *)(ue_p->Srb0.Tx_buffer.Payload),
@@ -465,17 +461,16 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
           PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
 
   rrc_mac_config_req_gNB(rrc_instance_p->module_id,
-                         rrc_instance_p->carrier.ssb_SubcarrierOffset,
-                         rrc_instance_p->carrier.pdsch_AntennaPorts,
-                         rrc_instance_p->carrier.pusch_AntennaPorts,
-                         rrc_instance_p->carrier.sib1_tda,
-                         rrc_instance_p->carrier.minRXTXTIME,
-                         (NR_ServingCellConfigCommon_t *)rrc_instance_p->carrier.servingcellconfigcommon,
+                         rrc_instance_p->configuration.ssb_SubcarrierOffset,
+                         rrc_instance_p->configuration.pdsch_AntennaPorts,
+                         rrc_instance_p->configuration.pusch_AntennaPorts,
+                         rrc_instance_p->configuration.sib1_tda,
+                         rrc_instance_p->configuration.minRXTXTIME,
+                         rrc_instance_p->carrier.servingcellconfigcommon,
                          &rrc_instance_p->carrier.mib,
                          0,
                          ue_context_pP->ue_context.rnti,
-                         (NR_CellGroupConfig_t *)NULL
-			 );
+                         NULL);
 
   LOG_I(NR_RRC,
         PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n",
@@ -723,6 +718,7 @@ rrc_gNB_generate_defaultRRCReconfiguration(
                                 dedicatedNAS_MessageList,
                                 ue_context_pP,
                                 &rrc->carrier,
+                                &rrc->configuration,
                                 NULL,
                                 ue_p->masterCellGroup);
 
@@ -986,6 +982,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
                                 dedicatedNAS_MessageList,
                                 ue_context_pP,
                                 &rrc->carrier,
+                                &rrc->configuration,
                                 NULL,
                                 cellGroupConfig);
   LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Reconfiguration\n");
@@ -1159,6 +1156,7 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
                                 NULL,
                                 NULL,
                                 NULL,
+                                NULL,
                                 NULL);
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
 
@@ -1259,6 +1257,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
                                NULL,
                                NULL,
                                NULL,
+                               NULL,
                                NULL);
 
   ue_context_pP->ue_context.pdu_session_release_command_flag = 1;
@@ -1362,17 +1361,16 @@ rrc_gNB_process_RRCReconfigurationComplete(
 
   if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
     rrc_mac_config_req_gNB(rrc->module_id,
-                           rrc->carrier.ssb_SubcarrierOffset,
-                           rrc->carrier.pdsch_AntennaPorts,
-                           rrc->carrier.pusch_AntennaPorts,
-                           rrc->carrier.sib1_tda,
-                           rrc->carrier.minRXTXTIME,
+                           rrc->configuration.ssb_SubcarrierOffset,
+                           rrc->configuration.pdsch_AntennaPorts,
+                           rrc->configuration.pusch_AntennaPorts,
+                           rrc->configuration.sib1_tda,
+                           rrc->configuration.minRXTXTIME,
                            NULL,
                            NULL,
                            0,
                            ue_context_pP->ue_context.rnti,
-                           ue_context_pP->ue_context.masterCellGroup
-                           );
+                           ue_context_pP->ue_context.masterCellGroup);
     LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti);
     nr_rrc_rlc_config_asn1_req(ctxt_pP,
                                SRB_configList, // NULL,
@@ -1810,6 +1808,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
                                 NULL,
                                 NULL,
                                 NULL,
+                                NULL,
                                 NULL);
   LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,
               "[MSG] RRC Reconfiguration\n");
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index 70dfebaaf7d60a5a1f7520babfee1ed492dc90bb..ea34cdd65a7c2c651153fc4dbeaec4ed97844906 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -116,6 +116,7 @@ RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries,
 void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m) {
   // generate nr-Config-r15 containers for LTE RRC : inside message for X2 EN-DC (CG-Config Message from 38.331)
   rrc_gNB_carrier_data_t *carrier=&rrc->carrier;
+  const gNB_RrcConfigurationReq *configuration = &rrc->configuration;
   MessageDef *msg;
   msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ_ACK);
   gtpv1u_enb_create_tunnel_req_t  create_tunnel_req;
@@ -240,29 +241,16 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
                           cipher_algo,
                           NR_SecurityConfig__keyToUse_secondary);
   }
-  if (ue_context_p->ue_context.spCellConfig) {
-    fill_default_reconfig(carrier->servingcellconfigcommon,
-                          ue_context_p->ue_context.spCellConfig->spCellConfigDedicated,
-                          reconfig_ies,
-                          ue_context_p->ue_context.secondaryCellGroup,
-                          ue_context_p->ue_context.UE_Capability_nr,
-                          carrier->pdsch_AntennaPorts,
-                          carrier->minRXTXTIME,
-                          carrier->do_CSIRS,
-                          carrier->do_SRS,
-                          ue_context_p->local_uid);
-  } else {
-    fill_default_reconfig(carrier->servingcellconfigcommon,
-                          NULL,
-                          reconfig_ies,
-                          ue_context_p->ue_context.secondaryCellGroup,
-                          ue_context_p->ue_context.UE_Capability_nr,
-                          carrier->pdsch_AntennaPorts,
-                          carrier->minRXTXTIME,
-                          carrier->do_CSIRS,
-                          carrier->do_SRS,
-                          ue_context_p->local_uid);
-  }
+  NR_ServingCellConfig_t *scc = ue_context_p->ue_context.spCellConfig
+      ? ue_context_p->ue_context.spCellConfig->spCellConfigDedicated
+      : NULL;
+  fill_default_reconfig(carrier->servingcellconfigcommon,
+                        scc,
+                        reconfig_ies,
+                        ue_context_p->ue_context.secondaryCellGroup,
+                        ue_context_p->ue_context.UE_Capability_nr,
+                        configuration,
+                        ue_context_p->local_uid);
   ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
   NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config));
   memset((void *)CG_Config,0,sizeof(*CG_Config));
@@ -359,11 +347,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
   // configure MAC and RLC
   if (NODE_IS_DU(rrc->node_type)) {
     rrc_mac_config_req_gNB(rrc->module_id,
-                           rrc->carrier.ssb_SubcarrierOffset,
-                           rrc->carrier.pdsch_AntennaPorts,
-			   rrc->carrier.pusch_AntennaPorts,
-                           rrc->carrier.sib1_tda,
-                           rrc->carrier.minRXTXTIME,
+                           rrc->configuration.ssb_SubcarrierOffset,
+                           rrc->configuration.pdsch_AntennaPorts,
+                           rrc->configuration.pusch_AntennaPorts,
+                           rrc->configuration.sib1_tda,
+                           rrc->configuration.minRXTXTIME,
                            rrc->carrier.servingcellconfigcommon,
                            &rrc->carrier.mib,
                            1, // add_ue flag
@@ -371,11 +359,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
                            ue_context_p->ue_context.secondaryCellGroup);
   } else {
     rrc_mac_config_req_gNB(rrc->module_id,
-                           rrc->carrier.ssb_SubcarrierOffset,
-                           rrc->carrier.pdsch_AntennaPorts,
-                           rrc->carrier.pusch_AntennaPorts,
-                           rrc->carrier.sib1_tda,
-                           rrc->carrier.minRXTXTIME,
+                           rrc->configuration.ssb_SubcarrierOffset,
+                           rrc->configuration.pdsch_AntennaPorts,
+                           rrc->configuration.pusch_AntennaPorts,
+                           rrc->configuration.sib1_tda,
+                           rrc->configuration.minRXTXTIME,
                            NULL,
                            NULL,
                            1, // add_ue flag
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index 1a67a9c164df38d3dbf76e01d9bb99ff7ac8e916..a112afbb960ca16b8a914a647fb0a44e4566046b 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -56,11 +56,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
                                      NR_UE_NR_Capability_t *uecap,
                                      int scg_id,
                                      int servCellIndex,
-                                     int dl_antenna_ports,
-                                     int minRXTXTIME,
-                                     int do_csirs,
-                                     int do_srs,
-                                     int uid) {
+                                     const gNB_RrcConfigurationReq *configuration,
+                                     int uid)
+{
+  const rrc_pdsch_AntennaPorts_t* pdschap = &configuration->pdsch_AntennaPorts;
+  const int dl_antenna_ports = pdschap->N1 * pdschap->N2 * pdschap->XP;
+  const int do_csirs = configuration->do_CSIRS;
 
   AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
   AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
@@ -603,7 +604,10 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup1=NULL;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1;
- set_dl_mcs_table(bwp->bwp_Common->genericParameters.subcarrierSpacing, uecap, bwp->bwp_Dedicated, servingcellconfigcommon);
+ set_dl_mcs_table(bwp->bwp_Common->genericParameters.subcarrierSpacing,
+                  configuration->force_256qam_off ? NULL : uecap,
+                  bwp->bwp_Dedicated,
+                  servingcellconfigcommon);
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI));
  *bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1;
  bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling;
@@ -768,7 +772,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  ASN_SEQUENCE_ADD(&srs_resset0->srs_ResourceIdList->list,srs_resset0_id);
  srs_Config->srs_ResourceToReleaseList=NULL;
 
-  if(do_srs) {
+  if (configuration->do_SRS) {
     srs_resset0->resourceType.present =  NR_SRS_ResourceSet__resourceType_PR_periodic;
     srs_resset0->resourceType.choice.periodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.periodic));
     srs_resset0->resourceType.choice.periodic->associatedCSI_RS = NULL;
@@ -812,7 +816,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
      srs_res0->freqHopping.b_SRS);
  srs_res0->groupOrSequenceHopping=NR_SRS_Resource__groupOrSequenceHopping_neither;
 
-  if(do_srs) {
+  if (configuration->do_SRS) {
     srs_res0->resourceType.present= NR_SRS_Resource__resourceType_PR_periodic;
     srs_res0->resourceType.choice.periodic=calloc(1,sizeof(*srs_res0->resourceType.choice.periodic));
     srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl160;
@@ -933,7 +937,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
  long *delay[8];
  for (int i=0;i<8;i++) {
    delay[i] = calloc(1,sizeof(*delay[i]));
-   *delay[i] = i+minRXTXTIME;
+   *delay[i] = i + configuration->minRXTXTIME;
    ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]);
  }
  pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList));
@@ -1178,19 +1182,50 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
    csirep1->codebookConfig->codebookType.choice.type1 = calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1));
    csirep1->codebookConfig->codebookType.choice.type1->subType.present=NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel;
    csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel=calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel));
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present=
-     NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two=
-     calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two));
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.size=1;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.bits_unused=2;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf=malloc(1);
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf[0]=0xfc;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.size=1;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.bits_unused=0;
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf=malloc(1);
-   csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]=0x03;
-   csirep1->codebookConfig->codebookType.choice.type1->codebookMode=1;
+   if (dl_antenna_ports == 2) {
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present=
+       NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two=
+       calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two));
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.size=1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.bits_unused=2;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf=malloc(1);
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf[0]=0xfc;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.size=1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.bits_unused=0;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf=malloc(1);
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]=0x03;
+     csirep1->codebookConfig->codebookType.choice.type1->codebookMode=1;
+   } else if (dl_antenna_ports < 16) {
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present=
+       NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo=
+       calloc(1,sizeof(*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo));
+     if(dl_antenna_ports == 4)
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present=
+       NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction;
+     else if(dl_antenna_ports == 8)
+       csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present=
+         NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction;
+     else if(dl_antenna_ports == 12)
+       csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present=
+         NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction;
+     else//default
+       csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present=
+         NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction;
+
+     /*csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.size=1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.bits_unused=1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.buf=malloc(1);
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.buf[0]=0xc0; //'00000011'B
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->typeI_SinglePanel_codebookSubsetRestriction_i2->size = 1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->typeI_SinglePanel_codebookSubsetRestriction_i2->bits_unused=1;
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->typeI_SinglePanel_codebookSubsetRestriction_i2->buf=malloc(1);
+     csirep1->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo->typeI_SinglePanel_codebookSubsetRestriction_i2->buf[0]=0xc0;*/
+     csirep1->codebookConfig->codebookType.choice.type1->codebookMode=1;
+   } else {//32 antennas are Not implemented yet
+     csirep1->codebookConfig->codebookType.choice.type1->codebookMode=2;
+   }
    csirep1->dummy = NULL;
    csirep1->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled;
    csirep1->groupBasedBeamReporting.choice.disabled=calloc(1,sizeof(*csirep1->groupBasedBeamReporting.choice.disabled));
@@ -1341,10 +1376,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
                            NR_RRCReconfiguration_IEs_t *reconfig,
                            NR_CellGroupConfig_t *secondaryCellGroup,
                            NR_UE_NR_Capability_t *uecap,
-                           int dl_antenna_ports,
-                           int minRXTXTIME,
-                           int do_csirs,
-                           int do_srs,
+                           const gNB_RrcConfigurationReq *configuration,
                            int uid) {
   AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
   AssertFatal(reconfig!=NULL,"reconfig is null\n");
@@ -1358,10 +1390,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
                                   uecap,
                                   1,
                                   1,
-                                  dl_antenna_ports,
-                                  minRXTXTIME,
-                                  do_csirs,
-                                  do_srs,
+                                  configuration,
                                   uid);
 
   xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 013e542689a54ea0982bbde323c1154d71f5ed7b..24a0348d35d6857f13bdfda34dc0f175de3aab96 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -736,10 +736,10 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
                       CirSize
                     );
         else { // no channel modeling
-          double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0
-                                     {0.5, 1.0, 0.5, 0.25},  //rx 1
-                                     {0.25, 0.5, 1.0, 0.5},  //rx 2
-                                     {0.125, 0.25, 0.5, 1.0}};//rx 3
+          double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0
+                                      {0.2, 1.0, 0.2, 0.1}, //rx 1
+                                     {0.1, 0.2, 1.0, 0.2}, //rx 2
+                                     {0.05, 0.1, 0.2, 1.0}};//rx 3
 
           sample_t *out=(sample_t *)samplesVoid[a];
           int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
index f13f20efbab0eba909eac48ade4f9fb2e773fad9..d14267dcd84f89441248b2655789c433c8a7f268 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
@@ -23,8 +23,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
index 483aac6deb9a45c8e936c233054945009c4ed73a..52e4eec30e89325f4eb7f246441ff4cf6e9eb2e7 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
index 9a91640a080d2b2ab14ed402759a35f0ba42fdd4..ab435c9686684d4b97a7b58d017dbd300eea48ee 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
index 05c81b5c512f4e6aa62e2f8ebaa237334cb931a8..a04e0e6123f398948b5bd9f85345998f83a2c0d0 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
index fbae1136b0b786c3abcdbff49ad683943e2a7a45..426f9e782b1a0cc3196af816495c936646b0828e 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
index e5685d00a4af4575bebdd277d403e236465d174e..216728577a775fb8db3a4375894753ba49c3435f 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
index b0126589cd81461716074401e5bd1494c24908c7..59d466656c66319d08cec18df5c3d9619b20c907 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
index 683cdaeb2c40885393fc285eeddff5e5e34f1631..2ae4df07d9c80b3bc2dff2ee4414799279cbcef1 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
index 2d85f446d7b319c79f300f85c92dd27fdc6899f4..21267870bd5e8b468c41afe7fcdd2b2cab91290e 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
index e1c9e9e167814760fc4dd204a2c17c8d0b8ae4db..a0fd0bda9f0221dc5c36419a17e9add1fa8f26bf 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf
index 367ced1c8a936c55fd7b8e8c49910b284c118327..5c8f90d9b5555a1ce02aa3ee8c3743c3d9c20b6f 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf
@@ -22,8 +22,6 @@ gNBs =
    ////////// Physical parameters:
 
    ssb_SubcarrierOffset                                           = 0;
-   pdsch_AntennaPorts                                             = 1;
-   pusch_AntennaPorts                                             = 1;
 
    servingCellConfigCommon = (
    {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
index e7d671e6a438f031d5acd08c4d546325039a8cd2..7bf3626870a6604c8a6c576347ceb7425ce6c386 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
index c9363da7f8e9658b03d2c39aa1108e95b17f7831..1773e1fb7921be8a563c70001243c37e547b2e44 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
@@ -203,7 +201,7 @@ L1s = (
 RUs = (
     {		  
          local_rf       = "yes"
-         nb_tx          = 1
+         nb_tx          = 4
          nb_rx          = 1
          att_tx         = 0
          att_rx         = 0;
@@ -217,8 +215,10 @@ RUs = (
          #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
          ## beamforming 2x2 matrix:
          #bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
-         ## beamforming 4x4 matrix:
-         #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
+         ## beamforming 2x4 matrix:
+         #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000];
+         #beamforming 4x4 matrix:
+         bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
          sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
          clock_src = "external";
     }
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
index 0e5ee33950fa5a5a269c9a1c3dfd71666e4cb4fc..d0f394be16a648c0efba3d26bd474647f435e674 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
index 019a0f0a363664d43f2059018e740e3ce05bbb5f..0438e61337210d1e37ec783d253b983f41d40e26 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
index 35e742900ad5d65cd4af11ceb0bc15c6ea3021fe..66c2151eb83997cabe07d0016c269a01b71c9a10 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf
index 37cde2feb1d1217615ddae9bc591e48ce12d35ee..c6ea066fc48aa0c9dae1d446f9f4d6962d438373 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf
index f3922404010f4d0cbb13ce684c83cea580d8a863..fcfe58a3c024e059e0417d927962531f6c16e4c6 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf
@@ -22,9 +22,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
-	
+
     servingCellConfigCommon = (
     {
  #spCellConfigCommon
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf
index 59af2a9187fbc74c0ed21f68f72a69f330fa5a7d..2ad9757cb132fa517500d2d746d4c09572ec08c3 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
index 9358c3370f5fa522554f64e96d72c38a556f8311..44074f3fd91e18a00bfe60080484594be6014ecf 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
index 004ad4db78ce18775dafe89b569f09c482143d01..7ce150506f0da42c6f2f5c67763e1ce347004dd3 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
index 4ec53064f11c2400c3c0ab53cd069c7cd717c08f..306e652eaa9b5d1e763b3d0e97867173d03565e1 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf
index 7c0fa96adbb12b2ed16fcee3bcc23181e69d6165..d08c0f14a08ad55c3b0c30daf6388c416ab59cc4 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
index 57aa459d49e7b00c33eafe565b1f52caa68af29e..e3204db8faeb657aca5ea06d1da289c947266351 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 	
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf
index 89dca2a75c4892f999aa0df87a81875e7199bc46..030dc102267bafc37ce9a97b16d57cad20ae0737 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf
@@ -22,8 +22,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 31; //0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     pusch_TargetSNRx10                                        = 200;
     pucch_TargetSNRx10                                        = 200;
 
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf
index c30805a2d9b6021db0df7b3c38186a0fd70b0e3d..256d724f3ff9898e942244b2cdc8443de355e515 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf
@@ -37,8 +37,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
     sib1_tda                                                  = 0;
 
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf
index b0e02ff2bc340a24667934a8a706cfc9c1f19144..726e43d7ad333ed90f1b2f86f3b4eba33d4baf85 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf
@@ -37,8 +37,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     sib1_tda                                                  = 0;
     servingCellConfigCommon = (
     {
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
index 9bf20b54aba8c63e71dcb7ddae9aefee8d54ec63..7e2db64aaa72bc1cb5f6e506313e13fd4aeaec6b 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
@@ -33,8 +33,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
     sib1_tda                                                  = 0;
     do_SRS                                                    = 1;
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
index 9452f00eed10a9e21117a6522df566b9811c47cb..f2c550e7662d7a0bfd4a7c64d01fcc6f8a3bfc01 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
@@ -33,7 +33,7 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
     sib1_tda                                                  = 0;
     do_SRS                                                    = 1;
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
index 09cf892b917b009d9dc2729a5744330f9f242868..1dc903b811232d2b01bcacba686646823f480b34 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
@@ -33,8 +33,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
     min_rxtxtime                                              = 6;
     sib1_tda                                                  = 0;
 
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf
index 280461d2abf9be9d65343625afbbe7a5e601081e..8ca0c0887692f7c0a0747556334c245cfc1e4cab 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf
@@ -31,8 +31,6 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
-    pusch_AntennaPorts                                        = 1;
 
      pdcch_ConfigSIB1 = (
       {
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf
index fac54a298b7cf9901c6673efcb97cad30951af6b..4b9fdf84ae35fd5d837dfc8b3b4f016d547d3cc5 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf
@@ -33,10 +33,8 @@ gNBs =
     ////////// Physical parameters:
 
     ssb_SubcarrierOffset                                      = 0;
-    pdsch_AntennaPorts                                        = 1;
+    pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
-#    do_CSIRS                                                  = 1;
-    min_rxtxtime_pdsch                                        = 2;
     ul_prbblacklist                                           = "79,80,81,82"
     pdcch_ConfigSIB1 = (
       {
@@ -66,7 +64,7 @@ gNBs =
      #initialDownlinkBWP
       #genericParameters
        # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart))
-       initialDLBWPlocationAndBandwidth                                        = 31899;
+       initialDLBWPlocationAndBandwidth                                        = 31624;
        #
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
@@ -100,7 +98,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                                        = 31899;
+        initialULBWPlocationAndBandwidth                                        = 31624;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialULBWPsubcarrierSpacing                                           = 1;