diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 61e44bdd55..7a8634f468 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,13 +2,12 @@
We want to make contributing to this project as easy and transparent as possible.
-Please refer to the steps described on our website: [How to contribute to OAI](https://www.openairinterface.org/?page_id=112)
-
1. Sign and return a Contributor License Agreement to OAI team.
-2. Create an account on [Eurecom GitLab Server](https://gitlab.eurecom.fr).
-3. Provide the identifiant of this account to the OAI team (mailto:contact@openairinterface.org) so you have developer rights on this repository.
+2. We recommend that you provide us with a professional or student email address
+2. Register on [Eurecom GitLab Server](https://gitlab.eurecom.fr/users/sign_in)
+3. Provide the OAI team with the **username** of this account to (mailto:contact@openairinterface.org) ; we will give you the developer rights on this repository.
4. The policies are described in these wiki pages: [OAI Policies](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/oai-policies-home)
- - PLEASE DO NOT FORK the OAI repository on your own Eurecom GitLab account. It just eats up space on our servers.
+ - PLEASE DO NOT FORK the OAI repository on your own Eurecom GitLab account. It just eats up space on our servers.
- You can fork onto another hosting system. But we will NOT accept a merge request from a forked repository.
* This decision was made for the license reasons.
* The Continuous Integration will reject your merge request.
diff --git a/ci-scripts/.gitignore b/ci-scripts/.gitignore
index dc5e7c7476..34d19403a7 100644
--- a/ci-scripts/.gitignore
+++ b/ci-scripts/.gitignore
@@ -1,3 +1,4 @@
+r*.raw
enb_*.log
ue_*.log
ping_*.*
diff --git a/ci-scripts/checkAddedWarnings.sh b/ci-scripts/checkAddedWarnings.sh
index d366059a85..bda8287a78 100755
--- a/ci-scripts/checkAddedWarnings.sh
+++ b/ci-scripts/checkAddedWarnings.sh
@@ -110,7 +110,7 @@ MODIFIED_FILES=`git log $TARGET_INIT_COMMIT..$MERGE_COMMMIT --oneline --name-sta
NB_WARNINGS_FILES=0
# Retrieve list of warnings
-LIST_WARNING_FILES=`egrep "error:|warning:" archives/*/*.Rel15.txt archives/*/basic_simulator_*txt | egrep -v "jobserver unavailable|Clock skew detected.|flexran.proto" | sed -e "s#^.*/home/ubuntu/tmp/##" -e "s#^.*/tmp/CI-eNB/##" -e "s#common/utils/.*/itti#common/utils/itti#" | awk -F ":" '{print $1}' | sort | uniq`
+LIST_WARNING_FILES=`egrep "error:|warning:" archives/*/*.Rel15.txt | egrep -v "jobserver unavailable|Clock skew detected.|flexran.proto" | sed -e "s#^.*/home/ubuntu/tmp/##" -e "s#^.*/tmp/CI-eNB/##" -e "s#common/utils/.*/itti#common/utils/itti#" | awk -F ":" '{print $1}' | sort | uniq`
echo ""
echo "List of files that have been modified by the Merge Request AND"
diff --git a/ci-scripts/constants.py b/ci-scripts/constants.py
index 1e7e84fb32..c5698c5a3e 100644
--- a/ci-scripts/constants.py
+++ b/ci-scripts/constants.py
@@ -57,6 +57,7 @@ OAI_UE_PROCESS_ASSERTION = -22
OAI_UE_PROCESS_FAILED = -23
OAI_UE_PROCESS_NO_TUNNEL_INTERFACE = -24
OAI_UE_PROCESS_SEG_FAULT = -25
+OAI_UE_PROCESS_NO_MBMS_MSGS = -26
OAI_UE_PROCESS_OK = +6
UE_STATUS_DETACHED = 0
diff --git a/ci-scripts/cppcheck_suppressions.list b/ci-scripts/cppcheck_suppressions.list
index cad2aab88b..727fd22e74 100644
--- a/ci-scripts/cppcheck_suppressions.list
+++ b/ci-scripts/cppcheck_suppressions.list
@@ -37,6 +37,7 @@ memleak:openair2/UTIL/OMG/omg_hashtable.c
// _emm_as_encode function creates the encoded buffer
//
memleak:openair3/NAS/UE/EMM/SAP/emm_as.c
+memleak:openair1/PHY/INIT/nr_init_ue.c
//-----------------------------------------------------------------------------
//*****************************************************************************
// section for files not used in oai exec's included in CI.
diff --git a/ci-scripts/doc/vm_based_simulator_env.md b/ci-scripts/doc/vm_based_simulator_env.md
index 5dbcfbd931..95b9d920d5 100644
--- a/ci-scripts/doc/vm_based_simulator_env.md
+++ b/ci-scripts/doc/vm_based_simulator_env.md
@@ -38,7 +38,6 @@ Last point, this documentation is valid for all CI-supported branches:
* `master`
* `develop`
-* `develop-nr`
But the feature set may not be aligned. **The principles still apply.**
diff --git a/ci-scripts/html.py b/ci-scripts/html.py
index 1a6e3f8fdb..8fa99fa61b 100644
--- a/ci-scripts/html.py
+++ b/ci-scripts/html.py
@@ -326,7 +326,7 @@ class HTMLManagement():
continue
self.htmlFile.write('
\n')
- self.htmlFile.write(' | ' + str('eNB') + ' Server Characteristics | \n')
+ self.htmlFile.write(' ' + str(machine) + ' Server Characteristics | \n')
self.htmlFile.write('
\n')
self.htmlFile.write(' \n')
self.htmlFile.write(' | OS Version | \n')
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index e9313051fc..63358eca38 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -30,6 +30,7 @@
import constants as CONST
+
#-----------------------------------------------------------
# Import
#-----------------------------------------------------------
@@ -332,12 +333,6 @@ class OaiCiTest():
logging.debug('Found a N3xx device --> resetting it')
SSH.command('cd ' + self.UESourceCodePath, '\$', 5)
# Initialize_OAI_UE_args usually start with -C and followed by the location in repository
- # in case of NR-UE, we may have rrc_config_path (Temporary?)
- modifiedUeOptions = str(self.Initialize_OAI_UE_args)
- if RAN.Getair_interface() == 'nr':
- result = re.search('--rrc_config_path ', modifiedUeOptions)
- if result is not None:
- modifiedUeOptions = modifiedUeOptions.replace('rrc_config_path ', 'rrc_config_path ' + self.UESourceCodePath + '/')
SSH.command('source oaienv', '\$', 5)
SSH.command('cd cmake_targets/ran_build/build', '\$', 5)
if RAN.Getair_interface() == 'lte':
@@ -352,7 +347,17 @@ class OaiCiTest():
SSH.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5)
SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5)
SSH.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5)
- SSH.command('echo "ulimit -c unlimited && ./'+ RAN.Getair_interface() +'-uesoftmodem ' + modifiedUeOptions + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+ else:
+ SSH.command('if [ -e rbconfig.raw ]; then echo ' + self.UEPassword + ' | sudo -S rm rbconfig.raw; fi', '\$', 5)
+ SSH.command('if [ -e reconfig.raw ]; then echo ' + self.UEPassword + ' | sudo -S rm reconfig.raw; fi', '\$', 5)
+ # Copy the RAW files from gNB running directory (maybe on another machine)
+ copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/rbconfig.raw', '.')
+ if (copyin_res == 0):
+ SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './rbconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build')
+ copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/reconfig.raw', '.')
+ if (copyin_res == 0):
+ SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './reconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build')
+ SSH.command('echo "ulimit -c unlimited && ./'+ RAN.Getair_interface() +'-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
self.UELogFile = 'ue_' + self.testCase_id + '.log'
@@ -2432,6 +2437,7 @@ class OaiCiTest():
nrCRCOK = 0
mbms_messages = 0
HTML.SethtmlUEFailureMsg('')
+ global_status = CONST.ALL_PROCESSES_OK
for line in ue_log_file.readlines():
result = re.search('nr_synchro_time', str(line))
if result is not None:
@@ -2554,14 +2560,14 @@ class OaiCiTest():
logging.debug('\033[94m' + mibMsg + '\033[0m')
except Exception as e:
logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m')
- result = re.search("DL Carrier Frequency/ARFCN : (?P\d{1,15}/\d{1,4})", str(line))
+ result = re.search("DL Carrier Frequency/ARFCN : \-*(?P\d{1,15}/\d{1,4})", str(line))
if result is not None:
try:
freq = result.group('carrier_frequency')
new_freq = re.sub('/[0-9]+','',freq)
float_freq = float(new_freq) / 1000000
- HTMLSethtmlUEFailureMsg(HTMLGethtmlUEFailureMsg() + 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz')
- logging.debug('\033[94m' + " DL Carrier Frequency is: " + freq + '\033[0m')
+ HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz')
+ logging.debug('\033[94m' + " DL Carrier Frequency is: " + str(freq) + '\033[0m')
except Exception as e:
logging.error('\033[91m' + " DL Carrier Frequency not found" + '\033[0m')
result = re.search("AllowedMeasBandwidth : (?P\d{1,7})", str(line))
@@ -2625,36 +2631,36 @@ class OaiCiTest():
else:
statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)'
logging.debug('\u001B[1;30;41m ' + statMsg + ' \u001B[0m')
+ global_status = OAI_UE_PROCESS_NO_MBMS_MSGS
HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
if foundSegFault:
logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m')
if not nrUEFlag:
- return CONST.OAI_UE_PROCESS_SEG_FAULT
+ global_status = CONST.OAI_UE_PROCESS_SEG_FAULT
else:
if not frequency_found:
- return CONST.OAI_UE_PROCESS_SEG_FAULT
+ global_status = CONST.OAI_UE_PROCESS_SEG_FAULT
if foundAssertion:
logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m')
HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE showed an assertion!\n')
if not nrUEFlag:
if not mib_found or not frequency_found:
- return CONST.OAI_UE_PROCESS_ASSERTION
+ global_status = CONST.OAI_UE_PROCESS_ASSERTION
else:
if not frequency_found:
- return CONST.OAI_UE_PROCESS_ASSERTION
+ global_status = CONST.OAI_UE_PROCESS_ASSERTION
if foundRealTimeIssue:
logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m')
HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE faced real time issues!\n')
- #return CONST.ENB_PROCESS_REALTIME_ISSUE
if nrUEFlag:
if not frequency_found:
- return CONST.OAI_UE_PROCESS_COULD_NOT_SYNC
+ global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC
else:
if no_cell_sync_found and not mib_found:
logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m')
HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE could not synchronize!\n')
- return CONST.OAI_UE_PROCESS_COULD_NOT_SYNC
- return 0
+ global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC
+ return global_status
def TerminateFlexranCtrl(self):
@@ -3061,7 +3067,7 @@ class OaiCiTest():
logging.debug('\u001B[1m----------------------------------------\u001B[0m')
def CheckClassValidity(action,id):
- if action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover':
+ if action!='Build_PhySim' and action!='Run_PhySim' and action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover':
logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action)
return False
return True
@@ -3208,6 +3214,19 @@ def GetParametersFromXML(action):
else:
CiTestObj.x2_ho_options = string_field
+ if action == 'Build_PhySim':
+ ldpc.buildargs = test.findtext('physim_build_args')
+ forced_workspace_cleanup = test.findtext('forced_workspace_cleanup')
+ if (forced_workspace_cleanup is None):
+ ldpc.forced_workspace_cleanup=False
+ else:
+ if re.match('true', forced_workspace_cleanup, re.IGNORECASE):
+ ldpc.forced_workspace_cleanup=True
+ else:
+ ldpc.forced_workspace_cleanup=False
+
+ if action == 'Run_PhySim':
+ ldpc.runargs = test.findtext('physim_run_args')
#check if given test is in list
#it is in list if one of the strings in 'list' is at the beginning of 'test'
@@ -3243,6 +3262,9 @@ EPC.SetHtmlObj(HTML)
RAN.SetHtmlObj(HTML)
RAN.SetEpcObj(EPC)
+import cls_physim #class PhySim for physical simulators build and test
+ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU build
+
argvs = sys.argv
argc = len(argvs)
cwd = os.getcwd()
@@ -3264,12 +3286,14 @@ while len(argvs) > 1:
CiTestObj.ranRepository = matchReg.group(1)
RAN.SetranRepository(matchReg.group(1))
HTML.SetranRepository(matchReg.group(1))
+ ldpc.ranRepository=matchReg.group(1)
elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
else:
matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE)
doMerge = matchReg.group(1)
+ ldpc.ranAllowMerge=matchReg.group(1)
if ((doMerge == 'true') or (doMerge == 'True')):
CiTestObj.ranAllowMerge = True
RAN.SetranAllowMerge(True)
@@ -3282,6 +3306,7 @@ while len(argvs) > 1:
CiTestObj.ranBranch = matchReg.group(1)
RAN.SetranBranch(matchReg.group(1))
HTML.SetranBranch(matchReg.group(1))
+ ldpc.ranBranch=matchReg.group(1)
elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
@@ -3290,6 +3315,7 @@ while len(argvs) > 1:
CiTestObj.ranCommitID = matchReg.group(1)
RAN.SetranCommitID(matchReg.group(1))
HTML.SetranCommitID(matchReg.group(1))
+ ldpc.ranCommitID=matchReg.group(1)
elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
@@ -3298,10 +3324,12 @@ while len(argvs) > 1:
CiTestObj.ranTargetBranch = matchReg.group(1)
RAN.SetranTargetBranch(matchReg.group(1))
HTML.SetranTargetBranch(matchReg.group(1))
+ ldpc.ranTargetBranch=matchReg.group(1)
elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.SeteNBIPAddress(matchReg.group(1))
+ ldpc.eNBIpAddr=matchReg.group(1)
elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.SeteNB1IPAddress(matchReg.group(1))
@@ -3312,6 +3340,7 @@ while len(argvs) > 1:
if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
RAN.SeteNBUserName(matchReg.group(1))
+ ldpc.eNBUserName=matchReg.group(1)
elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
RAN.SeteNB1UserName(matchReg.group(1))
@@ -3322,6 +3351,7 @@ while len(argvs) > 1:
if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
RAN.SeteNBPassword(matchReg.group(1))
+ ldpc.eNBPassWord=matchReg.group(1)
elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
RAN.SeteNB1Password(matchReg.group(1))
@@ -3332,6 +3362,7 @@ while len(argvs) > 1:
if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.SeteNBSourceCodePath(matchReg.group(1))
+ ldpc.eNBSourceCodePath=matchReg.group(1)
elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.SeteNB1SourceCodePath(matchReg.group(1))
@@ -3499,7 +3530,7 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE):
foundCount += 1
count += 1
if foundCount != HTML.GetnbTestXMLfiles():
- HTML.SetnbTestXMLfiles(foundcount)
+ HTML.SetnbTestXMLfiles(foundCount)
if (CiTestObj.ADBIPAddress != 'none'):
terminate_ue_flag = False
@@ -3702,6 +3733,11 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
CiTestObj.IdleSleep()
elif action == 'Perform_X2_Handover':
CiTestObj.Perform_X2_Handover()
+ elif action == 'Build_PhySim':
+ HTML=ldpc.Build_PhySim(HTML,CONST)
+ if ldpc.exitStatus==1:sys.exit()
+ elif action == 'Run_PhySim':
+ HTML=ldpc.Run_PhySim(HTML,CONST,id)
else:
sys.exit('Invalid action')
CiTestObj.FailReportCnt += 1
diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
index 9d6349077f..9b9fe462f1 100755
--- a/ci-scripts/oai-ci-vm-tool
+++ b/ci-scripts/oai-ci-vm-tool
@@ -186,7 +186,7 @@ function variant__v3__phy_sim {
BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=8192
VM_DISK=20
- RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111\" -q -np -b"
+ RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111 015112\" -q -np -b"
}
function variant__v4__cppcheck {
@@ -197,7 +197,7 @@ function variant__v4__cppcheck {
}
function variant__v5__gnb_usrp {
- VM_MEMORY=8192
+ VM_MEMORY=10240
VM_CPU=8
NB_PATTERN_FILES=9
BUILD_OPTIONS="--gNB -w USRP"
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 5b5add0adb..287c18021e 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -366,7 +366,7 @@ class RANManagement():
count = 40
buildOAIprocess = True
while (count > 0) and buildOAIprocess:
- mySSH.command('ps aux | grep --color=never build_ | grep -v grep', '\$', 3)
+ mySSH.command('ps aux | grep --color=never build_ | grep -v grep', '\$', 6)
result = re.search('build_oai', mySSH.getBefore())
if result is None:
buildOAIprocess = False
@@ -546,6 +546,9 @@ class RANManagement():
# Launch eNB with the modified config file
mySSH.command('source oaienv', '\$', 5)
mySSH.command('cd cmake_targets', '\$', 5)
+ if self.air_interface == 'nr':
+ mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm rbconfig.raw; fi', '\$', 5)
+ mySSH.command('if [ -e reconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm reconfig.raw; fi', '\$', 5)
mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface + '-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
@@ -607,7 +610,11 @@ class RANManagement():
enbDidSync = True
time.sleep(10)
- if enbDidSync and eNBinNoS1:
+ rruCheck = False
+ result = re.search('^rru|^du.band', str(config_file))
+ if result is not None:
+ rruCheck = True
+ if enbDidSync and eNBinNoS1 and not rruCheck:
mySSH.command('ifconfig oaitun_enb1', '\$', 4)
mySSH.command('ifconfig oaitun_enb1', '\$', 4)
result = re.search('inet addr:1|inet 1', mySSH.getBefore())
@@ -774,7 +781,7 @@ class RANManagement():
mySSH.command('cd ' + self.eNBSourceCodePath, '\$', 5)
mySSH.command('cd cmake_targets', '\$', 5)
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 core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 60)
+ mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap enb_*txt physim_*.log', '\$', 60)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 5)
mySSH.close()
@@ -800,8 +807,11 @@ class RANManagement():
uciStatMsgCount = 0
pdcpFailure = 0
ulschFailure = 0
+ ulschAllocateCCEerror = 0
+ uplinkSegmentsAborted = 0
ulschReceiveOK = 0
gnbRxTxWakeUpFailure = 0
+ gnbTxWriteThreadEnabled = False
cdrxActivationMessageCount = 0
dropNotEnoughRBs = 0
mbmsRequestMsg = 0
@@ -812,6 +822,7 @@ class RANManagement():
X2HO_state = CONST.X2_HO_REQ_STATE__IDLE
X2HO_inNbProcedures = 0
X2HO_outNbProcedures = 0
+ global_status = CONST.ALL_PROCESSES_OK
for line in enb_log_file.readlines():
if X2HO_state == CONST.X2_HO_REQ_STATE__IDLE:
result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line))
@@ -914,9 +925,18 @@ class RANManagement():
result = re.search('could not wakeup gNB rxtx process', str(line))
if result is not None:
gnbRxTxWakeUpFailure += 1
+ result = re.search('tx write thread ready', str(line))
+ if result is not None:
+ gnbTxWriteThreadEnabled = True
result = re.search('ULSCH in error in round|ULSCH 0 in error', str(line))
if result is not None:
ulschFailure += 1
+ result = re.search('ERROR ALLOCATING CCEs', str(line))
+ if result is not None:
+ ulschAllocateCCEerror += 1
+ result = re.search('uplink segment error.*aborted [1-9] segments', str(line))
+ if result is not None:
+ uplinkSegmentsAborted += 1
result = re.search('ULSCH received ok', str(line))
if result is not None:
ulschReceiveOK += 1
@@ -948,6 +968,10 @@ class RANManagement():
statMsg = nodeB_prefix + 'NB showed ' + str(gnbRxTxWakeUpFailure) + ' "could not wakeup gNB rxtx process" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
htmleNBFailureMsg += statMsg + '\n'
+ if gnbTxWriteThreadEnabled:
+ statMsg = nodeB_prefix + 'NB ran with TX Write thread enabled'
+ logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+ htmleNBFailureMsg += statMsg + '\n'
if uciStatMsgCount > 0:
statMsg = nodeB_prefix + 'NB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
@@ -960,6 +984,14 @@ class RANManagement():
statMsg = nodeB_prefix + 'NB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
htmleNBFailureMsg += statMsg + '\n'
+ if ulschAllocateCCEerror > 0:
+ statMsg = nodeB_prefix + 'NB showed ' + str(ulschAllocateCCEerror) + ' "eNB_dlsch_ulsch_scheduler(); ERROR ALLOCATING CCEs" message(s)'
+ logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+ htmleNBFailureMsg += statMsg + '\n'
+ if uplinkSegmentsAborted > 0:
+ statMsg = nodeB_prefix + 'NB showed ' + str(uplinkSegmentsAborted) + ' "uplink segment error 0/2, aborted * segments" message(s)'
+ logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+ htmleNBFailureMsg += statMsg + '\n'
if dropNotEnoughRBs > 0:
statMsg = 'eNB showed ' + str(dropNotEnoughRBs) + ' "dropping, not enough RBs" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
@@ -1030,30 +1062,23 @@ class RANManagement():
rruMsg = 'Slave RRU DID NOT receive the RRU_frame_resynch command from RAU'
logging.debug('\u001B[1;37;41m ' + rruMsg + ' \u001B[0m')
htmleNBFailureMsg += rruMsg + '\n'
- self.prematureExit(True)
- return CONST.ENB_PROCESS_SLAVE_RRU_NOT_SYNCED
+ self.prematureExit = True
+ global_status = CONST.ENB_PROCESS_SLAVE_RRU_NOT_SYNCED
if foundSegFault:
logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with a Segmentation Fault! \u001B[0m')
- if self.htmlObj is not None:
- self.htmlObj.SetHmleNBFailureMsg(htmleNBFailureMsg)
- return CONST.ENB_PROCESS_SEG_FAULT
+ global_status = CONST.ENB_PROCESS_SEG_FAULT
if foundAssertion:
logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with an assertion! \u001B[0m')
htmleNBFailureMsg += msgAssertion
- if self.htmlObj is not None:
- self.htmlObj.SetHmleNBFailureMsg(htmleNBFailureMsg)
- return CONST.ENB_PROCESS_ASSERTION
+ global_status = CONST.ENB_PROCESS_ASSERTION
if foundRealTimeIssue:
logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB faced real time issues! \u001B[0m')
htmleNBFailureMsg += nodeB_prefix + 'NB faced real time issues!\n'
- #return CONST.ENB_PROCESS_REALTIME_ISSUE
if rlcDiscardBuffer > 0:
rlcMsg = nodeB_prefix + 'NB RLC discarded ' + str(rlcDiscardBuffer) + ' buffer(s)'
logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m')
htmleNBFailureMsg += rlcMsg + '\n'
- if self.htmlObj is not None:
- self.htmlObj.SetHmleNBFailureMsg(htmleNBFailureMsg)
- return CONST.ENB_PROCESS_REALTIME_ISSUE
+ global_status = CONST.ENB_PROCESS_REALTIME_ISSUE
if self.htmlObj is not None:
self.htmlObj.SetHmleNBFailureMsg(htmleNBFailureMsg)
- return 0
+ return global_status
diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh
index 0a75ff25b7..44d200c3b6 100755
--- a/ci-scripts/reportBuildLocally.sh
+++ b/ci-scripts/reportBuildLocally.sh
@@ -53,7 +53,7 @@ function details_table {
echo " Message | " >> $3
echo "
" >> $3
- LIST_MESSAGES=`egrep "error:|warning:" $2 | egrep -v "jobserver unavailable|Clock skew detected.|flexran.proto"`
+ LIST_MESSAGES=`egrep "error:|warning:" $2 | egrep -v "jobserver unavailable|Clock skew detected.|flexran.proto|disabling jobserver mode"`
COMPLETE_MESSAGE="start"
for MESSAGE in $LIST_MESSAGES
do
@@ -146,7 +146,7 @@ function summary_table_row {
else
echo " $NB_ERRORS" >> ./build_results.html
fi
- NB_WARNINGS=`egrep "warning:" $2 | egrep -v "jobserver unavailable|Clock skew detected.|flexran.proto" | egrep -c "warning:"`
+ NB_WARNINGS=`egrep "warning:" $2 | egrep -v "jobserver unavailable|Clock skew detected.|flexran.proto|disabling jobserver mode" | egrep -c "warning:"`
if [ $NB_WARNINGS -eq 0 ]
then
echo " | $NB_WARNINGS" >> ./build_results.html
diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh
index b74fe93a1f..897f9285e9 100755
--- a/ci-scripts/reportTestLocally.sh
+++ b/ci-scripts/reportTestLocally.sh
@@ -724,8 +724,8 @@ function report_test {
echo " | " >> ./test_simulator_results.html
echo " " >> ./test_simulator_results.html
fi
- #PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping*.log 2> /dev/null`
- #analyzePingFiles
+ PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_ping*.log 2> /dev/null`
+ analyzePingFiles
IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_iperf_dl*client*txt 2> /dev/null`
analyzeIperfFiles
diff --git a/ci-scripts/rrc-files/rbconfig.raw b/ci-scripts/rrc-files/rbconfig.raw
deleted file mode 100644
index b03f18d121..0000000000
Binary files a/ci-scripts/rrc-files/rbconfig.raw and /dev/null differ
diff --git a/ci-scripts/rrc-files/reconfig.raw b/ci-scripts/rrc-files/reconfig.raw
deleted file mode 100644
index 97b41d9b6b..0000000000
Binary files a/ci-scripts/rrc-files/reconfig.raw and /dev/null differ
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 64af11c8ba..0db2264c76 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -89,6 +89,9 @@ function start_basic_sim_enb {
fi
done
ENB_SYNC=0
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1
rm $1
if [ $i -lt 50 ]
then
@@ -151,6 +154,9 @@ function start_basic_sim_ue {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1
rm $1
if [ $i -lt 50 ]
then
@@ -523,9 +529,9 @@ function install_epc_on_vm {
echo "############################################################"
echo "[ -f 01proxy ] && sudo cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS
echo "touch /home/ubuntu/.hushlogin" >> $LOC_EPC_VM_CMDS
- echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $LOC_EPC_VM_CMDS
+ echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev iperf\"" >> $LOC_EPC_VM_CMDS
echo "sudo apt-get update > zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
- echo "sudo apt-get --yes install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf >> zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
+ echo "sudo apt-get --yes install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev iperf >> zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
# Installing HSS
echo "echo \"cd /opt\"" >> $LOC_EPC_VM_CMDS
@@ -588,8 +594,6 @@ function start_epc {
echo "echo \"cd /opt/hss_sim0609\"" > $LOC_EPC_VM_CMDS
echo "cd /opt/hss_sim0609" >> $LOC_EPC_VM_CMDS
echo "sudo rm -f hss.log" >> $LOC_EPC_VM_CMDS
- #echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $LOC_EPC_VM_CMDS
- #echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $LOC_EPC_VM_CMDS
echo "echo \"screen -dm -S simulated_hss ./starthss_real\"" >> $LOC_EPC_VM_CMDS
echo "sudo su -c \"screen -dm -S simulated_hss ./starthss_real\"" >> $LOC_EPC_VM_CMDS
@@ -656,8 +660,6 @@ function terminate_epc {
echo "cd /opt/ltebox/tools" >> $1
echo "echo \"sudo ./stop_ltebox\"" >> $1
echo "sudo ./stop_ltebox" >> $1
- echo "echo \"sudo daemon --name=simulated_hss --stop\"" >> $1
- echo "sudo daemon --name=simulated_hss --stop" >> $1
echo "echo \"sudo killall --signal SIGKILL hss_sim\"" >> $1
echo "sudo killall --signal SIGKILL hss_sim" >> $1
ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1
@@ -764,6 +766,9 @@ function start_l2_sim_enb {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_VM_IP_ADDR < $1
rm $1
ENB_SYNC=1
if [ $i -lt 50 ]
@@ -872,6 +877,9 @@ function start_l2_sim_ue {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1
rm $1
UE_SYNC=1
if [ $i -lt 50 ]
@@ -985,6 +993,9 @@ function start_rf_sim_enb {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_VM_IP_ADDR < $1
rm $1
if [ $i -lt 50 ]
then
@@ -1114,6 +1125,9 @@ function start_rf_sim_ue {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1
rm $1
if [ $i -lt 50 ]
then
@@ -1158,6 +1172,10 @@ function start_rf_sim_gnb {
local LOC_CONF_FILE=$5
# 1 is with S1 and 0 without S1 aka noS1
local LOC_S1_CONFIGURATION=$6
+
+ if [ -e rbconfig.raw ]; then rm -f rbconfig.raw; fi
+ if [ -e reconfig.raw ]; then rm -f reconfig.raw; fi
+
echo "cd /home/ubuntu/tmp" > $1
echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1
echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1
@@ -1171,6 +1189,7 @@ function start_rf_sim_gnb {
echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1
echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
+ echo "sudo rm -f r*config.raw" >> $1
if [ $LOC_S1_CONFIGURATION -eq 0 ]
then
echo "echo \"RFSIMULATOR=server ./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim --phy-test\" > ./my-nr-softmodem-run.sh " >> $1
@@ -1231,6 +1250,13 @@ function start_rf_sim_gnb {
fi
fi
sleep 10
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1
+ rm $1
+ # Copy the RAW files from the gNB run for the NR-UE
+ scp -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/ran_build/build/rbconfig.raw .
+ scp -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/ran_build/build/reconfig.raw .
}
function start_rf_sim_nr_ue {
@@ -1241,14 +1267,21 @@ function start_rf_sim_nr_ue {
local LOC_FREQUENCY=$6
# 1 is with S1 and 0 without S1 aka noS1
local LOC_S1_CONFIGURATION=$7
+
+ # Copy the RAW files from the gNB run
+ scp -o StrictHostKeyChecking=no rbconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp
+ scp -o StrictHostKeyChecking=no reconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp
+
echo "echo \"sudo apt-get --yes --quiet install daemon \"" > $1
echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1
echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1
echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
+ echo "sudo cp /home/ubuntu/tmp/r*config.raw /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
+ echo "sudo chmod 666 /home/ubuntu/tmp/cmake_targets/ran_build/build/r*config.raw" >> $1
echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
if [ $LOC_S1_CONFIGURATION -eq 0 ]
then
- echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/ci-scripts/rrc-files --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1
+ echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/ --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1
fi
echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1
echo "cat ./my-nr-softmodem-run.sh" >> $1
@@ -1295,6 +1328,9 @@ function start_rf_sim_nr_ue {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1
rm $1
if [ $i -lt 50 ]
then
@@ -2028,7 +2064,7 @@ function run_test_on_vm {
NR_STATUS=0
######### start of loop
- while [ $try_cnt -lt 5 ]
+ while [ $try_cnt -lt 1 ]
do
SYNC_STATUS=0
PING_STATUS=0
@@ -2050,6 +2086,8 @@ function run_test_on_vm {
echo "Problem w/ gNB and NR-UE not syncing"
terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
+ scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC
+ scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC
SYNC_STATUS=-1
try_cnt=$[$try_cnt+1]
continue
@@ -2089,6 +2127,8 @@ function run_test_on_vm {
echo "DL test not OK"
terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
+ scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC
+ scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC
try_cnt=$[$try_cnt+1]
continue
fi
diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml
index 4dbfe00821..aac71198f1 100644
--- a/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml
+++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml
@@ -25,23 +25,10 @@
EPC-Start
log-in
- 010101 090101
050101 060101 070101
-
- Build_eNB
- Build eNB (USRP)
- -w USRP -c --eNB
-
-
-
- Build_OAI_UE
- Build OAI UE
- -w USRP --UE
-
-
Initialize_HSS
Initialize HSS
diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml
index 41e746bc85..73d1216199 100644
--- a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml
@@ -24,6 +24,7 @@
test-05-tm1-rrc-no-flex
Test-05MHz-TM1-RRC-Inactivity
tasks
+ 2
030201
040101
diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
index f3e80c576a..c51093c178 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
@@ -52,7 +52,7 @@
Initialize_OAI_UE
Initialize NR UE USRP
- --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path ci-scripts/rrc-files
+ --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path .
NR
diff --git a/ci-scripts/xml_files/gnb_usrp_build.xml b/ci-scripts/xml_files/gnb_usrp_build.xml
index bba92930c5..97d6ef06f6 100644
--- a/ci-scripts/xml_files/gnb_usrp_build.xml
+++ b/ci-scripts/xml_files/gnb_usrp_build.xml
@@ -24,6 +24,7 @@
gnb-build-tab
Build-gNB
wrench
+ 4
010101
diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml
index e1644f3931..8276294e9a 100644
--- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml
+++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml
@@ -24,6 +24,7 @@
test-10
Test-10MHz
tasks
+ 2
030201
040101
diff --git a/ci-scripts/xml_files/multi_rru_band38_build.xml b/ci-scripts/xml_files/multi_rru_band38_build.xml
index 614ef394f3..ba45eab10a 100644
--- a/ci-scripts/xml_files/multi_rru_band38_build.xml
+++ b/ci-scripts/xml_files/multi_rru_band38_build.xml
@@ -33,7 +33,7 @@
Build_eNB
Build RCC
- -w USRP -c --eNB
+ -w USRP -c --eNB --ninja
0
0
True
@@ -42,7 +42,7 @@
WaitEndBuild_eNB
Wait for end of Build RCC
- -w USRP -c --eNB
+ -w USRP -c --eNB --ninja
0
0
@@ -50,7 +50,7 @@
Build_eNB
Build Master RRU
- -w USRP -c --eNB
+ -w USRP -c --eNB --ninja
1
1
True
@@ -59,7 +59,7 @@
WaitEndBuild_eNB
Wait for end of Build Master RRU
- -w USRP -c --eNB
+ -w USRP -c --eNB --ninja
1
1
@@ -67,7 +67,7 @@
Build_eNB
Build Slave RRU
- -w USRP -c --eNB
+ -w USRP -c --eNB --ninja
2
2
True
@@ -76,7 +76,7 @@
WaitEndBuild_eNB
Wait for end of Build Slave RRU
- -w USRP -c --eNB
+ -w USRP -c --eNB --ninja
2
2
diff --git a/ci-scripts/xml_files/multi_rru_band38_test_10mhz_tm1.xml b/ci-scripts/xml_files/multi_rru_band38_test_10mhz_tm1.xml
index 7658f8a0e5..cca14c0696 100644
--- a/ci-scripts/xml_files/multi_rru_band38_test_10mhz_tm1.xml
+++ b/ci-scripts/xml_files/multi_rru_band38_test_10mhz_tm1.xml
@@ -24,7 +24,7 @@
test-multi-rru-10
Test-Multi-RRU-10MHz
tasks
- 4
+ 2
030211 030212 030213
030111 030112 030113
diff --git a/ci-scripts/xml_files/nr_ue_usrp_build.xml b/ci-scripts/xml_files/nr_ue_usrp_build.xml
index 7d8d97d2c5..c3c842b85a 100644
--- a/ci-scripts/xml_files/nr_ue_usrp_build.xml
+++ b/ci-scripts/xml_files/nr_ue_usrp_build.xml
@@ -24,6 +24,7 @@
nr-ue-build-tab
Build-NR-UE
wrench
+ 2
010102
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index dcd063ff5c..0b60172747 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -20,34 +20,9 @@
# */
# Author: laurent THOMAS, Lionel GAUTHIER
-###################### FOR CUDA#############################
-# author NCTU OpinConnect Terng-Yin Hsu,WEI-YING,LIN:
-# Add for PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
-# email tyhsu@cs.nctu.edu.tw
-###################### FOR CUDA#############################
+
cmake_minimum_required (VERSION 3.0)
-
-
-##############################################
-# Base CUDA setting
-##############################################
-find_package(CUDA)
-message ("cuda include ${CUDA_INCLUDE_DIRS}")
-message ("cuda library ${CUDA_LIBRARY_DIRS}")
-
-add_definitions("-L/usr/local/cuda/lib64")
-
-SET(CUDA_NVCC_FLAGS
- "${CUDA_NVCC_FLAGS};-arch=sm_75;")
-
-# Disable warnings for CUDA
-SET(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-lpthread;-w;-O3;--default-stream;per-thread;-I/usr/local/cuda/inc;-L/usr/local/cuda/lib -lcutil;-rdc=true;-lcudadevrt")
-SET(CUDA_VERBOSE_BUILD ON)
-SET(CUDA_HOST_COMPILER "/usr/bin/g++")
-
-SET(CUDA_SEPARABLE_COMPILATION ON)
-
#########################################################
# Base directories, compatible with legacy OAI building #
#########################################################
@@ -64,6 +39,33 @@ set (OPENAIR_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
project (OpenAirInterface)
+
+
+##############################################
+# Base CUDA setting
+##############################################
+find_package(CUDA)
+if (CUDA_FOUND)
+ message ("cuda include ${CUDA_INCLUDE_DIRS}")
+ message ("cuda library ${CUDA_LIBRARY_DIRS}")
+
+ add_definitions("-L/usr/local/cuda/lib64")
+
+ SET(CUDA_NVCC_FLAGS
+ "${CUDA_NVCC_FLAGS};-arch=sm_60;")
+
+ # Disable warnings for CUDA
+ SET(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-lpthread;-w;-O3;--default-stream;per-thread;-I/usr/local/cuda/inc;-L/usr/local/cuda/lib -lcutil;-rdc=true;-lcudadevrt")
+ SET(CUDA_VERBOSE_BUILD ON)
+ SET(CUDA_HOST_COMPILER "/usr/bin/g++")
+
+ SET(CUDA_SEPARABLE_COMPILATION ON)
+
+else (CUDA_FOUND)
+ message ("No CUDA tool installed")
+endif ()
+
+
###########################################
# macros to define options as there is numerous options in oai
################################################
@@ -194,13 +196,30 @@ endif()
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -pipe -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC")
# add autotools definitions that were maybe used!
-# set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
-set(CMAKE_C_FLAGS
- "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP "
-)
-set(CMAKE_CXX_FLAGS
- "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 "
-)
+if (CUDA_FOUND)
+ set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
+ set(CUDA_CMAKE_C_FLAGS
+ "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D CUDA_FLAG"
+ )
+ set(CUDA_CMAKE_CXX_FLAGS
+ "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 -D CUDA_FLAG"
+ )
+
+ set(CMAKE_C_FLAGS
+ "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER} -D CUDA_FLAG"
+ )
+ set(CMAKE_CXX_FLAGS
+ "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 -D${MKVER} -D CUDA_FLAG"
+ )
+else (CUDA_FOUND)
+ set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
+ set(CMAKE_C_FLAGS
+ "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER}"
+ )
+ set(CMAKE_CXX_FLAGS
+ "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 -D${MKVER}"
+ )
+endif ()
add_definitions("-DASN_DISABLE_OER_SUPPORT")
@@ -1655,7 +1674,7 @@ add_library(PHY_MEX ${PHY_MEX_UE} ${CONFIG_LIB})
#Layer 2 library
#####################
set(MAC_DIR ${OPENAIR2_DIR}/LAYER2/MAC)
-set(NR_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB)
+set(NR_GNB_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB)
set(NR_UE_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_UE)
set(PHY_INTERFACE_DIR ${OPENAIR2_DIR}/PHY_INTERFACE)
set(NR_PHY_INTERFACE_DIR ${OPENAIR2_DIR}/NR_PHY_INTERFACE)
@@ -1811,20 +1830,22 @@ set (MAC_SRC
${MAC_DIR}/eNB_scheduler_fairRR.c
${MAC_DIR}/eNB_scheduler_phytest.c
${MAC_DIR}/pre_processor.c
+ ${MAC_DIR}/slicing/slicing.c
${MAC_DIR}/config.c
${MAC_DIR}/config_ue.c
)
set (MAC_NR_SRC
${NR_PHY_INTERFACE_DIR}/NR_IF_Module.c
- ${NR_MAC_DIR}/main.c
- ${NR_MAC_DIR}/config.c
- ${NR_MAC_DIR}/gNB_scheduler.c
- ${NR_MAC_DIR}/gNB_scheduler_bch.c
- ${NR_MAC_DIR}/gNB_scheduler_dlsch.c
- ${NR_MAC_DIR}/gNB_scheduler_ulsch.c
- ${NR_MAC_DIR}/gNB_scheduler_primitives.c
- ${NR_MAC_DIR}/gNB_scheduler_phytest.c
+ ${NR_GNB_MAC_DIR}/main.c
+ ${NR_GNB_MAC_DIR}/config.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_bch.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_dlsch.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_ulsch.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_primitives.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_phytest.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_RA.c
)
@@ -1836,7 +1857,6 @@ set (MAC_SRC_UE
${MAC_DIR}/l1_helpers.c
${MAC_DIR}/rar_tools_ue.c
${MAC_DIR}/config_ue.c
-
)
set (MAC_NR_SRC_UE
@@ -1846,6 +1866,9 @@ set (MAC_NR_SRC_UE
${NR_UE_MAC_DIR}/main_ue_nr.c
${NR_UE_MAC_DIR}/nr_ue_procedures.c
${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
+ ${NR_UE_MAC_DIR}/nr_l1_helpers.c
+ ${NR_UE_MAC_DIR}/nr_ra_procedures.c
+ ${NR_UE_MAC_DIR}/rar_tools_nrUE.c
)
set (ENB_APP_SRC
@@ -1909,7 +1932,7 @@ add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c)
include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE")
-include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE")
+include_directories("${OPENAIR2_DIR}/LAYER2")
include_directories("${OPENAIR1_DIR}/SCHED_NR_UE")
#include_directories("${NFAPI_USER_DIR}"")
@@ -1937,6 +1960,19 @@ set (GTPV1U_SRC
add_library(GTPV1U ${GTPV1U_SRC})
add_dependencies(GTPV1U rrc_flag)
+#NR case
+set (NR_GTPV1U_SRC
+ ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c
+ ${RRC_DIR}/rrc_eNB_GTPV1U.c
+ ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c
+ ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c
+ ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c
+ ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1u.c
+ ${GTPV1U_DIR}/gtpv1u_teid_pool.c
+)
+add_library(NR_GTPV1U ${NR_GTPV1U_SRC})
+add_dependencies(NR_GTPV1U rrc_flag)
+
set (MME_APP_SRC
${OPENAIR3_DIR}/MME_APP/mme_app.c
${OPENAIR3_DIR}/MME_APP/mme_config.c
@@ -2264,26 +2300,28 @@ add_library(LFDS7
${lfds7_queue} ${lfds7_ring} ${lfds7_qbss} ${lfds7_stack} ${lfds7_freelist} ${lfds7_btree} ${lfds7_hash} ${lfds7_ordered_list} ${lfds7_unordered_list} ${lfds7_misc}
)
-# Simulation library
-##########################
-set (SIMUSRC
-${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c
-${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c
-${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
-${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_channel.c
-${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_tv_channel.c
-${OPENAIR1_DIR}/SIMULATION/TOOLS/abstraction.c
-${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c
-${OPENAIR1_DIR}/SIMULATION/RF/rf.c
-${OPENAIR1_DIR}/SIMULATION/RF/dac.c
-${OPENAIR1_DIR}/SIMULATION/RF/adc.c
-${OPENAIR_DIR}/targets/ARCH/rfsimulator/apply_channelmod.c
-#${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
-)
+add_library(SIMU_COMMON
+ ${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c
+ ${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c
+ )
# Simulation library
##########################
-add_library( SIMU SHARED ${SIMUSRC} )
+set (SIMUSRC
+ ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
+ ${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_channel.c
+ ${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_tv_channel.c
+ ${OPENAIR1_DIR}/SIMULATION/TOOLS/abstraction.c
+ ${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c
+ ${OPENAIR1_DIR}/SIMULATION/RF/rf.c
+ ${OPENAIR1_DIR}/SIMULATION/RF/dac.c
+ ${OPENAIR1_DIR}/SIMULATION/RF/adc.c
+ #${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
+ )
+
+# Simulation library
+##########################
+add_library(SIMU SHARED ${SIMUSRC} )
add_library(SIMU_ETH
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
@@ -2441,9 +2479,11 @@ target_link_libraries(gnbscope ${XFORMS_LIBRARIES})
add_library(rfsimulator MODULE
- ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c
+ ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c
+ ${OPENAIR_TARGETS}/ARCH/rfsimulator/apply_channelmod.c
+ ${OPENAIR_TARGETS}/ARCH/rfsimulator/new_channel_sim.c
)
-target_link_libraries(rfsimulator SIMU ${ATLAS_LIBRARIES})
+target_link_libraries(rfsimulator SIMU_COMMON ${ATLAS_LIBRARIES})
add_library(oai_iqplayer MODULE
${OPENAIR_TARGETS}/ARCH/iqplayer/iqplayer_lib.c
@@ -2466,7 +2506,7 @@ endif (${T_TRACER})
add_custom_command (
OUTPUT ${OPENAIR_DIR}/common/utils/T/T_IDs.h
COMMAND make clean
- COMMAND make
+ COMMAND make -j2
COMMAND make check_vcd
WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T
DEPENDS ${OPENAIR_DIR}/common/utils/T/T_messages.txt
@@ -2589,7 +2629,7 @@ add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer)
target_link_libraries (ocp-enb
-Wl,--start-group
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
- PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
+ PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB})
@@ -2659,7 +2699,7 @@ target_link_libraries (lte-uesoftmodem
-Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB
GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
- PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
+ PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
@@ -2685,6 +2725,7 @@ add_executable(nr-softmodem
${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
+ ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
@@ -2698,7 +2739,7 @@ add_executable(nr-softmodem
target_link_libraries (nr-softmodem
-Wl,--start-group
- UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA
+ UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB}
@@ -2742,9 +2783,9 @@ add_executable(nr-uesoftmodem
target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
+ PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
+ NFAPI_USER_LIB S1AP_LIB S1AP_ENB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
- PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS L2_UE NR_L2_UE MAC_NR_COMMON S1AP_LIB S1AP_ENB
- NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)
target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES})
@@ -2754,29 +2795,6 @@ target_link_libraries (nr-uesoftmodem ${T_LIB})
add_dependencies( nr-uesoftmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
-# USIM process
-#################
-#add_executable(usim
-# ${OPENAIR3_DIR}/NAS/TOOLS/usim_data.c
-# ${OPENAIR3_DIR}/NAS/USER/API/USIM/usim_api.c
-# ${OPENAIR3_DIR}/NAS/USER/API/USIM/aka_functions.c
-# ${OPENAIR3_DIR}/NAS/COMMON/UTIL/memory.c
-# ${OPENAIR3_DIR}/NAS/COMMON/UTIL/nas_log.c
-# ${OPENAIR3_DIR}/NAS/COMMON/UTIL/OctetString.c
-# ${OPENAIR3_DIR}/NAS/COMMON/UTIL/TLVEncoder.c
-# )
-#target_link_libraries (usim ${NAS_LIB} UTIL ${ITTI_LIB} LFDS pthread rt nettle crypto m)
-
-# ???
-#####################
-#add_executable(nvram
-# ${OPENAIR3_DIR}/NAS/TOOLS/ue_data.c
-# ${OPENAIR3_DIR}/NAS/COMMON/UTIL/memory.c
-# ${OPENAIR3_DIR}/NAS/COMMON/UTIL/nas_log.c
-# )
-#target_link_libraries (nvram LIB_NAS_UE UTIL ${ITTI_LIB} LFDS pthread rt nettle crypto m)
-
-
###################################"
# Addexecutables for tests
####################################
@@ -2793,7 +2811,7 @@ add_executable(dlsim_tm4
${T_SOURCE}
)
target_link_libraries (dlsim_tm4
- -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY LFDS ${ITTI_LIB} -Wl,--end-group
+ -Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY LFDS ${ITTI_LIB} -Wl,--end-group
pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${T_LIB}
)
@@ -2806,7 +2824,7 @@ add_executable(polartest
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(polartest
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE CONFIG_LIB -Wl,--end-group
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE CONFIG_LIB -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} dl
)
@@ -2821,35 +2839,51 @@ add_executable(smallblocktest
target_link_libraries(smallblocktest
- -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} dl
)
-<<<<<<< HEAD
+
+# temp_C_flag = CMAKE_C_FLAGS
+#set(CMAKE_C_FLAGS " ")
+set (TEMP_C_FLAG ${CMAKE_C_FLAGS})
+set (CMAKE_C_FLAGS ${CUDA_CMAKE_C_FLAGS})
+
+set (TEMP_CXX_FLAG ${CMAKE_CXX_FLAGS})
+set (CMAKE_CXX_FLAGS ${CUDA_CMAKE_CXX_FLAGS})
+if (CUDA_FOUND)
###################################################
# For CUDA library
###################################################
-CUDA_ADD_LIBRARY(LDPC_CU
- ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
- )
-CUDA_ADD_CUFFT_TO_TARGET(LDPC_CU)
-cuda_add_executable(ldpctest
-=======
-add_executable(ldpctest
- ${PHY_NR_CODINGIF}
->>>>>>> origin/develop
- ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
- ${T_SOURCE}
- ${SHLIB_LOADER_SOURCES}
- )
-<<<<<<< HEAD
+
+ CUDA_ADD_LIBRARY(LDPC_CU
+ ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
+ )
+ CUDA_ADD_CUFFT_TO_TARGET(LDPC_CU)
+ cuda_add_executable(ldpctest
+ ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
+ ${T_SOURCE}
+ ${SHLIB_LOADER_SOURCES}
+ )
+ target_link_libraries(ldpctest -ldl
+ -Wl,--start-group
+ LDPC_CU UTIL SIMU PHY_NR CONFIG_LIB
+ -Wl,--end-group
+ m pthread ${ATLAS_LIBRARIES} dl
+ )
+
+else (CUDA_FOUND)
+ add_executable(ldpctest
+ ${PHY_NR_CODINGIF}
+ ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
+ ${T_SOURCE}
+ ${SHLIB_LOADER_SOURCES}
+ )
+
+endif ()
+set (CMAKE_C_FLAGS ${TEMP_C_FLAG})
+set (CMAKE_CXX_FLAGS ${TEMP_CXX_FLAG})
-target_link_libraries(ldpctest -ldl
- -Wl,--start-group
- LDPC_CU UTIL SIMU PHY_NR CONFIG_LIB
- -Wl,--end-group
- m pthread ${ATLAS_LIBRARIES} dl
- )
# add_executable(ldpctest
# ${PHY_NR_CODINGIF}
@@ -2857,36 +2891,36 @@ target_link_libraries(ldpctest -ldl
# ${T_SOURCE}
# ${SHLIB_LOADER_SOURCES}
# )
-=======
->>>>>>> origin/develop
add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
target_link_libraries(ldpctest
- -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} dl
)
add_executable(nr_dlschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c
${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
${UTIL_SRC}
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_dlschsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
add_executable(nr_pbchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c
${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
${UTIL_SRC}
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_pbchsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
@@ -2901,7 +2935,7 @@ add_executable(nr_pucchsim
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_pucchsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
@@ -2915,7 +2949,7 @@ add_executable(nr_dlsim
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_dlsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR)
@@ -2929,17 +2963,18 @@ add_executable(nr_prachsim
${T_SOURCE}
${SHLIB_LOADER_SOURCES})
target_link_libraries(nr_prachsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl)
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB MAC_UE_NR SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl)
add_executable(nr_ulschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
${UTIL_SRC}
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_ulschsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
@@ -2953,7 +2988,7 @@ add_executable(nr_ulsim
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_ulsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR)
@@ -2972,7 +3007,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
${NFAPI_USER_DIR}/nfapi.c
)
target_link_libraries (${myExe}
- -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group
+ -Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group
pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl
)
@@ -3052,8 +3087,8 @@ if (${T_TRACER})
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR
- CN_UTILS GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB
- ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT)
+ CN_UTILS GTPV1U NR_GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB
+ ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts)
if (TARGET ${i})
add_dependencies(${i} generate_T)
endif()
@@ -3096,7 +3131,7 @@ function(make_driver name dir)
endforeach()
CONFIGURE_FILE(${OPENAIR_CMAKE}/tools/Kbuild.cmake ${OPENAIR_BIN_DIR}/${name}/Kbuild)
add_custom_command(OUTPUT ${name}.ko
- COMMAND make -C ${module_build_path} M=${OPENAIR_BIN_DIR}/${name}
+ COMMAND make -j2 -C ${module_build_path} M=${OPENAIR_BIN_DIR}/${name}
WORKING_DIRECTORY ${OPENAIR_BIN_DIR}/${name}
COMMENT "building ${module}.ko"
VERBATIM
diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt
index 10c14fd59a..19a333c626 100644
--- a/cmake_targets/autotests/README.txt
+++ b/cmake_targets/autotests/README.txt
@@ -142,10 +142,14 @@ Obj.# Case# Test# Description
(Test 11: 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%))
(TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)),
(TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)),
-01 51 11 nr_ulsim Test cases. (Test1: MCS 9),
- (Test2: MCS 16),
- (Test3: MCS 28)
-
+01 51 11 nr_ulsim Test cases. (Test1: MCS 9 106 PRBs),
+ (Test2: MCS 16 50 PRBs),
+ (Test3: MCS 28 50 PRBs),
+ (Test4: MCS 9 217 PRBs),
+ (Test5: MCS 9 273 PRBs)
+01 51 12 nr_prachsim Test cases.(Test1: 106 PRBs),
+ (Test2: 217 PRBs),
+ (Test3: 273 PRBs)
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 882670727b..786002e982 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1036,7 +1036,9 @@
execution
polartest Test cases. (Test1: PBCH polar test),
- (Test2: DCI polar test)
+ (Test2: DCI polar test),
+ (Test3: UCI polar test,6-bit CRC),
+ (Test4: UCI polar test,11-bit CRC)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1044,8 +1046,10 @@
$OPENAIR_DIR/targets/bin/polartest.Rel15
-q -s-10 -f0
- -q -s-10 -f0 -m1
- polartest.test1 polartest.test2
+ -q -s-10 -f0 -m1
+ -q -s-2 -f2 -m2 -k12
+ -q -s-2 -f2 -m2 -k20
+ polartest.test1 polartest.test2 polartest.test3 polartest.test4
BLER= 0.000000
segmentation fault|assertion|exiting|fatal
3
@@ -1067,9 +1071,9 @@
$OPENAIR_DIR/targets/bin/nr_pbchsim.Rel15
-s0 -S1 -n1000 -R106
-s0 -S1 -n10 -I -R106
- -s0 -S1 -n1000 -R217
+ -s0 -S1 -n1000 -R217
-s0 -S1 -n10 -I -R217
- -s0 -S1 -n1000 -R273
+ -s0 -S1 -n1000 -R273
-s0 -S1 -n10 -I -R273
nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6
PBCH test OK
@@ -1087,8 +1091,11 @@
(Test6: 217 PRB 100 PDSCH-PRBs),
(Test7: 217 PRB 80 PDSCH-Offset),
(Test8: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset),
- (Test9: 106 PRBs 50 PDSCH-PRBs MCS Index 27)
- (Test10: 106 PRBs 50 PDSCH-PRBs MCS Index 16)
+ (Test9: 106 PRBs 50 PDSCH-PRBs MCS Index 27),
+ (Test10: 106 PRBs 50 PDSCH-PRBs MCS Index 16),
+ (Test11: HARQ test 25% TP (4 rounds),
+ (Test12: HARQ test 33% TP (3 rounds),
+ (Test13: HARQ test 50% TP (2 rounds)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1104,8 +1111,11 @@
-n100 -R217 -a80 -s5
-n100 -R217 -a110 -s5 -b100
-n100 -e27 -s30
- -n100 -e16 -s10
- nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10
+ -n100 -e16 -s10
+ -n100 -s1 -t25
+ -n100 -s1 -t33
+ -n100 -s1 -t50
+ nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13
PDSCH test OK
segmentation fault|assertion|exiting|fatal
3
@@ -1179,15 +1189,20 @@
nr_pucchsim Test cases. (Test1: Format 0 1-bit ACK miss 106 PRB),
(Test2: Format 0 2-bit ACK miss 106 PRB),
(Test3: Format 0 2-bit ACK miss, 1-bit SR 106 PRB),
- (Test4: Format 2 3-bit 106 PRB),
- (Test5: Format 2 4-bit 106 PRB),
- (Test6: Format 2 5-bit 106 PRB),
- (Test7: Format 2 6-bit 106 PRB),
- (Test8: Format 2 7-bit 106 PRB),
- (Test9: Format 2 8-bit 106 PRB),
- (Test10: Format 2 9-bit 106 PRB),
- (Test11: Format 2 10-bit 106 PRB),
- (Test12: Format 2 11-bit 106 PRB)
+ (Test4: Format 2 3-bit 2/106 PRB),
+ (Test5: Format 2 4-bit 2/106 PRB),
+ (Test6: Format 2 5-bit 2/106 PRB),
+ (Test7: Format 2 6-bit 2/106 PRB),
+ (Test8: Format 2 7-bit 2/106 PRB),
+ (Test9: Format 2 8-bit 2/106 PRB),
+ (Test10: Format 2 9-bit 2/106 PRB),
+ (Test11: Format 2 10-bit 2/106 PRB),
+ (Test12: Format 2 11-bit 2/106 PRB),
+ (Test13: Format 2 12-bit 8/106 PRB),
+ (Test14: Format 2 19-bit 8/106 PRB),
+ (Test15: Format 2 32-bit 8/106 PRB),
+ (Test16: Format 2 32-bit 16/106 PRB),
+ (Test17: Format 2 64-bit 16/106 PRB)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1206,8 +1221,12 @@
-R 106 -i 1 -P 2 -b 9 -s5 -n1000
-R 106 -i 1 -P 2 -b 10 -s6 -n1000
-R 106 -i 1 -P 2 -b 11 -s6 -n1000
-
- nr_pucchsim.test1 nr_pucchsim.test2 nr_pucchsim.test3 nr_pucchsim.test4 nr_pucchsim.test5 nr_pucchsim.test6 nr_pucchsim.test7 nr_pucchsim.test8 nr_pucchsim.test9 nr_pucchsim.test10 nr_pucchsim.test11 nr_pucchsim.test12
+ -R 106 -i 1 -P 2 -q8 -b 12 -s-3 -n1000
+ -R 106 -i 1 -P 2 -q8 -b 19 -s-3 -n1000
+ -R 106 -i 1 -P 2 -q8 -b 32 -s-3 -n1000
+ -R 106 -i 1 -P 2 -q16 -b 32 -s-3 -n1000
+ -R 106 -i 1 -P 2 -q16 -b 64 -s-3 -n1000
+ nr_pucchsim.test1 nr_pucchsim.test2 nr_pucchsim.test3 nr_pucchsim.test4 nr_pucchsim.test5 nr_pucchsim.test6 nr_pucchsim.test7 nr_pucchsim.test8 nr_pucchsim.test9 nr_pucchsim.test10 nr_pucchsim.test11 nr_pucchsim.test12 nr_pucchsim.test13 nr_pucchsim.test14 nr_pucchsim.test15 nr_pucchsim.test16 nr_pucchsim.test17
PUCCH test OK
segmentation fault|assertion|exiting|fatal
3
@@ -1275,6 +1294,28 @@
3
+
+ execution
+ nr_prachsim Test cases. (Test1: 106 PRBs - Prach format A2),
+ (Test2: 217 PRBs - Prach format A2),
+ (Test3: 273 PRBs - Prach format A2),
+ (Test4: 106 PRBs - Prach format 0)
+
+ $OPENAIR_DIR/cmake_targets/build_oai
+ --phy_simulators -c
+ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash
+
+ $OPENAIR_DIR/targets/bin/nr_prachsim.Rel15
+ -a -s -30 -n 100 -p 63 -R 106
+ -a -s -30 -n 100 -p 63 -R 217
+ -a -s -30 -n 100 -p 63 -R 273
+ -a -s -30 -n 100 -p 63 -R 106 -c 4
+ nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4
+ PRACH test OK
+ segmentation fault|assertion|exiting|fatal
+ 3
+
+
lte-softmodem
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 9a5d5f370c..a7adc33db3 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -406,7 +406,7 @@ function main() {
shift 1;;
-k | --skip-shared-libraries)
SKIP_SHARED_LIB_FLAG="True"
- echo_info "Skipping build of shared libraries, rfsimulator, basicsimulator and transport protocol libraries"
+ echo_info "Skipping build of shared libraries, rfsimulator and transport protocol libraries"
shift;;
--ninja)
CMAKE_CMD="$CMAKE_CMD -GNinja"
@@ -701,7 +701,8 @@ function main() {
if [ "$SIMUS_PHY" = "1" ] ; then
echo_info "Compiling physical unitary tests simulators"
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
- simlist="dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim"
+ # simlist="dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim"
+ simlist="ldpctest"
for f in $simlist ; do
compilations \
phy_simulators $f \
@@ -896,7 +897,7 @@ function main() {
$build_dir rfsimulator \
librfsimulator.so $dbin/librfsimulator.so.$REL
- echo_info "Compiling basicsimulator"
+ echo_info "Compiling tcp_bridge_oai"
compilations \
$build_dir tcp_bridge_oai \
libtcp_bridge_oai.so $dbin/libtcp_bridge_oai.so.$REL
@@ -958,6 +959,7 @@ function main() {
wait
else
echo_info "10. Bypassing the Tests ..."
+ echo_success "BUILD SHOULD BE SUCCESSFUL"
fi
}
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 20bc5dc2b9..b8f0125b10 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -150,7 +150,9 @@ clean_all_files() {
set_openair_env
dir=$OPENAIR_DIR/cmake_targets
rm -rf $dir/log $OPENAIR_DIR/targets/bin/*
- rm -rf $dir/ran_build $dir/lte-simulators/build
+ rm -rf $dir/ran_build $dir/ran_build_noLOG
+ rm -rf $dir/lte-simulators/build
+ rm -rf $dir/phy_simulators/build $dir/nas_sim_tools/build
rm -rf $dir/oaisim_build_oai/build $dir/oaisim_build_oai/CMakeLists.txt
rm -rf $dir/autotests/bin $dir/autotests/log $dir/autotests/*/build
}
@@ -167,17 +169,29 @@ check_warnings() {
#we look for 'warning:' in the compilation log file
#this is how gcc starts a warning
#this is not perfect, we may get false positive
- warning_count=`grep "warning:" "$1"|wc -l`
+ warning_count=`grep "warning:" "$1" | egrep -v "jobserver unavailable|disabling jobserver mode" | wc -l`
if [ $warning_count -gt 0 ]; then
echo_error "WARNING: $warning_count warnings. See $1"
fi
}
+#check_errors:
+# print error message if the compilation had errors
+#argument:
+# $1: log file
+check_errors() {
+ #we look for 'warning:' in the compilation log file
+ error_count=`grep "error:" "$1" | wc -l`
+ if [ $error_count -gt 0 ]; then
+ echo_error "ERROR: $error_count error. See $1"
+ fi
+}
+
compilations() {
cd $OPENAIR_DIR/cmake_targets/$1/build
+ echo_info "Log file for compilation is being written to: $dlog/$2.$REL.txt"
set +e
{
- rm -f $3
if [ "$BUILD_COVERITY_SCAN" == "1" ]; then
COV_SCAN_PREFIX="cov-build --dir cov-int"
else
@@ -192,15 +206,22 @@ compilations() {
$COV_SCAN_PREFIX make -j`nproc` $2
fi
fi
-
+ ret=$?
} > $dlog/$2.$REL.txt 2>&1
set -e
- echo_info "Log file for compilation has been written to: $dlog/$2.$REL.txt"
+ if [[ $ret -ne 0 ]]; then
+ check_warnings "$dlog/$2.$REL.txt"
+ check_errors "$dlog/$2.$REL.txt"
+ echo_error "$2 compilation failed"
+ exit 1
+ fi
if [ -s $3 ] ; then
cp $3 $4
echo_success "$2 compiled"
check_warnings "$dlog/$2.$REL.txt"
else
+ check_warnings "$dlog/$2.$REL.txt"
+ check_errors "$dlog/$2.$REL.txt"
echo_error "$2 compilation failed"
exit 1
fi
diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c
index 2d861f2dc3..2e9fd614c5 100644
--- a/common/config/libconfig/config_libconfig.c
+++ b/common/config/libconfig/config_libconfig.c
@@ -179,8 +179,8 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) {
*(cfgoptions[i].u64ptr) = (uint64_t)llu;
printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].u64ptr)) );
} else {
- *(cfgoptions[i].iptr) = llu;
- printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].i64ptr)) );
+ *(cfgoptions[i].i64ptr) = llu;
+ printf_params("[LIBCONFIG] %s: %lld\n", cfgpath,(long long)(*(cfgoptions[i].i64ptr)) );
}
} else {
defval=config_setdefault_int64(&(cfgoptions[i]),prefix);
diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c
index 79db7f1c0e..90857d7cd9 100644
--- a/common/utils/LOG/vcd_signal_dumper.c
+++ b/common/utils/LOG/vcd_signal_dumper.c
@@ -518,7 +518,29 @@ const char* eurecomFunctionsNames[] = {
"wakeup_txfh",
"gNB_thread_rxtx0",
"gNB_thread_rxtx1",
- "ru_thread_tx_wait"
+ "ru_thread_tx_wait",
+ "gNB_ulsch_decoding",
+ "gNB_pdsch_codeword_scrambling",
+ "gNB_dlsch_encoding",
+ "gNB_pdsch_modulation",
+ "gNB_pdcch_tx",
+ "phy_procedures_gNB_tx",
+ "phy_procedures_gNB_common_tx",
+ "phy_procedures_gNB_uespec_rx",
+ "nr_rx_pusch",
+ "nr_ulsch_procedures_rx",
+ "macxface_gNB_dlsch_ulsch_scheduler",
+
+ /*NR ue-softmodem signal*/
+ "nr_ue_ulsch_encoding",
+ "nr_segmentation",
+ "ldpc_encoder_optim",
+ "nr_rate_matching_ldpc",
+ "nr_interleaving_ldpc",
+ "pss_synchro_nr",
+ "pss_search_time_nr",
+ "nr_initial_ue_sync",
+ "beam_switching_gpio"
};
struct vcd_module_s vcd_modules[] = {
diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h
index 88655977bb..601465c628 100644
--- a/common/utils/LOG/vcd_signal_dumper.h
+++ b/common/utils/LOG/vcd_signal_dumper.h
@@ -511,6 +511,29 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0,
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1,
VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_CODEWORD_SCRAMBLING,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,
+
+/* NR ue-softmodem signal*/
+ VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SYNCHRO_NR,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO,
+
VCD_SIGNAL_DUMPER_FUNCTIONS_END
} vcd_signal_dump_functions;
diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h
index 2221dbbcac..7b5304b1cb 100644
--- a/common/utils/T/T_defs.h
+++ b/common/utils/T/T_defs.h
@@ -73,7 +73,7 @@ typedef struct {
} T_cache_t;
/* number of VCD functions (to be kept up to date! see in T_messages.txt) */
-#define VCD_NUM_FUNCTIONS (249)
+#define VCD_NUM_FUNCTIONS (269)
/* number of VCD variables (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_VARIABLES (187)
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index 3838518834..d036b40560 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -3393,3 +3393,106 @@ ID = VCD_FUNCTION_RU_TX_WAIT
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = ru_thread_tx_wait
+ID = VCD_FUNCTION_PHY_gNB_ULSCH_DECODING
+ DESC = VCD function PHY_gNB_ULSCH_DECODING
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = gNB_ulsch_decoding
+ID = VCD_FUNCTION_gNB_PDSCH_CODEWORD_SCRAMBLING
+ DESC = VCD function gNB_PDSCH_CODEWORD_SCRAMBLING
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = gNB_pdsch_codeword_scrambling
+ID = VCD_FUNCTION_gNB_DLSCH_ENCODING
+ DESC = VCD function gNB_DLSCH_ENCODING
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = gNB_dlsch_encoding
+ID = VCD_FUNCTION_gNB_PDSCH_MODULATION
+ DESC = VCD function gNB_PDSCH_MODULATION
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = gNB_pdsch_modulation
+ID = VCD_FUNCTION_PHY_gNB_PDCCH_TX
+ DESC = VCD function PHY_gNB_PDCCH_TX
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = gNB_pdcch_tx
+ID = VCD_FUNCTION_PHY_PROCEDURES_gNB_TX
+ DESC = VCD function PHY_PROCEDURES_gNB_TX
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = phy_procedures_gNB_tx
+ID = VCD_FUNCTION_PHY_PROCEDURES_gNB_COMMON_TX
+ DESC = VCD function PHY_PROCEDURES_gNB_COMMON_TX
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = phy_procedures_gNB_common_tx
+ID = VCD_FUNCTION_PHY_PROCEDURES_gNB_UESPEC_RX
+ DESC = VCD function PHY_PROCEDURES_gNB_UESPEC_RX
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = phy_procedures_gNB_uespec_rx
+ID = VCD_FUNCTION_NR_RX_PUSCH
+ DESC = VCD function NR_RX_PUSCH
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = nr_rx_pusch
+ID = VCD_FUNCTION_NR_ULSCH_PROCEDURES_RX
+ DESC = VCD function NR_ULSCH_PROCEDURES_RX
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = nr_ulsch_procedures_rx
+ID = VCD_FUNCTION_gNB_DLSCH_ULSCH_SCHEDULER
+ DESC = VCD function gNB_DLSCH_ULSCH_SCHEDULER
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = macxface_gNB_dlsch_ulsch_scheduler
+
+ #function for nrUE
+ID = VCD_FUNCTION_NR_UE_ULSCH_ENCODING
+ DESC = VCD function NR_UE_ULSCH_ENCODING
+ GROUP = ALL:VCD:UE:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = nr_ue_ulsch_encoding
+ID = VCD_FUNCTION_NR_SEGMENTATION
+ DESC = VCD function NR_SEGMENTATION
+ GROUP = ALL:VCD:UE:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = nr_segmentation
+ID = VCD_FUNCTION_LDPC_ENCODER_OPTIM
+ DESC = VCD function LDPC_ENCODER_OPTIM
+ GROUP = ALL:VCD:UE:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = ldpc_encoder_optim
+ID = VCD_FUNCTION_NR_RATE_MATCHING_LDPC
+ DESC = VCD function NR_RATE_MATCHING_LDPC
+ GROUP = ALL:VCD:UE:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = nr_rate_matching_ldpc
+ID = VCD_FUNCTION_NR_INTERLEAVING_LDPC
+ DESC = VCD function NR_INTERLEAVING_LDPC
+ GROUP = ALL:VCD:UE:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = nr_interleaving_ldpc
+ID = VCD_FUNCTION_PSS_SYNCHRO_NR
+ DESC = VCD function PSS_SYNCHRO_NR
+ GROUP = ALL:VCD:UE:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = pss_synchro_nr
+ID = VCD_FUNCTION_PSS_SEARCH_TIME_NR
+ DESC = VCD function PSS_SEARCH_TIME_NR
+ GROUP = ALL:VCD:UE:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = pss_search_time_nr
+ID = VCD_FUNCTION_NR_INITIAL_UE_SYNC
+ DESC = VCD function NR_INITIAL_UE_SYNC
+ GROUP = ALL:VCD:UE:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = nr_initial_ue_sync
+ID = VCD_FUNCTION_BEAM_SWITCHING_GPIO
+ DESC = VCD function BEAM_SWITCHING_GPIO
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = beam_switching_gpio
+
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index 8a236c49f9..5f07fc00aa 100644
--- a/common/utils/nr/nr_common.c
+++ b/common/utils/nr/nr_common.c
@@ -52,6 +52,7 @@ int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB) {
else return(N_RB-1-tmp2);
}
+/* TS 38.214 ch. 6.1.2.2.2 - Resource allocation type 1 for DL and UL */
int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize) {
AssertFatal(NPRB>0 && (NPRB + RBstart <= BWPsize),"Illegal NPRB/RBstart Configuration (%d,%d) for BWPsize %d\n",NPRB,RBstart,BWPsize);
@@ -62,14 +63,21 @@ int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize) {
int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart) {
return(PRBalloc_to_locationandbandwidth0(NPRB,RBstart,275));
}
+
/// Target code rate tables indexed by Imcs
+/* TS 38.214 table 5.1.3.1-1 - MCS index table 1 for PDSCH */
uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \
616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948};
- // Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
+
+/* TS 38.214 table 5.1.3.1-2 - MCS index table 2 for PDSCH */
+// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \
616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948};
+
+/* TS 38.214 table 5.1.3.1-3 - MCS index table 3 for PDSCH */
uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \
378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772};
+
uint16_t nr_tbs_table[93] = {24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, \
336, 352, 368, 384, 408, 432, 456, 480, 504, 528, 552, 576, 608, 640, 672, 704, 736, 768, 808, 848, 888, 928, 984, 1032, 1064, 1128, 1160, 1192, 1224, 1256, \
1288, 1320, 1352, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 2024, 2088, 2152, 2216, 2280, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2976, \
diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp
index 3d4d356dcf..22933fdd5b 100644
--- a/common/utils/ocp_itti/intertask_interface.cpp
+++ b/common/utils/ocp_itti/intertask_interface.cpp
@@ -91,8 +91,16 @@ task_list_t tasks[TASK_MAX];
return (EXIT_SUCCESS);
}
+ // in the two following functions, the +32 in malloc is there to deal with gcc memory alignment
+ // because a struct size can be larger than sum(sizeof(struct components))
+ // We should remove the itti principle of a huge union for all types of messages in paramter "msg_t ittiMsg"
+ // to use a more C classical pointer casting "void * ittiMsg", later casted in the right struct
+ // but we would have to change all legacy macros, as per this example
+ // #define S1AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_register_enb_req
+ // would become
+ // #define S1AP_REGISTER_ENB_REQ(mSGpTR) (s1ap_register_enb_req) mSGpTR)->ittiMsg
MessageDef *itti_alloc_new_message_sized(task_id_t origin_task_id, MessagesIds message_id, MessageHeaderSize size) {
- MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, sizeof(MessageHeader) + size);
+ MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, sizeof(MessageHeader) +32 + size);
temp->ittiMsgHeader.messageId = message_id;
temp->ittiMsgHeader.originTaskId = origin_task_id;
temp->ittiMsgHeader.ittiMsgSize = size;
@@ -100,7 +108,7 @@ task_list_t tasks[TASK_MAX];
}
MessageDef *itti_alloc_new_message(task_id_t origin_task_id, MessagesIds message_id) {
- int size=sizeof(MessageHeader) + messages_info[message_id].size;
+ int size=sizeof(MessageHeader) + 32 + messages_info[message_id].size;
MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, size);
temp->ittiMsgHeader.messageId = message_id;
temp->ittiMsgHeader.originTaskId = origin_task_id;
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 0cd25ee231..026c8270d7 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -256,6 +256,7 @@ typedef struct IttiMsgText_s {
//#include
#include
+#include
void *rrc_enb_process_itti_msg(void *);
#include
#include
@@ -414,7 +415,7 @@ static const message_info_t messages_info[] = {
#undef MESSAGE_DEF
};
-typedef struct __attribute__ ((__packed__)) MessageDef_s {
+typedef struct MessageDef_s {
MessageHeader ittiMsgHeader; /**< Message header */
msg_t ittiMsg;
} MessageDef;
diff --git a/doc/BUILD.md b/doc/BUILD.md
index 9ada32e532..97f9047596 100644
--- a/doc/BUILD.md
+++ b/doc/BUILD.md
@@ -16,7 +16,6 @@ This page is valid on tags starting from **`2019.w09`**.
# Soft Modem Build Script
-oai EPC is developed in a distinct project with it's own [documentation](https://github.com/OPENAIRINTERFACE/openair-cn/wiki) , it is not described here.
OAI softmodem sources, which aim to implement 3GPP compliant UEs, eNodeB and gNodeB can be downloaded from the Eurecom [gitlab repository](./GET_SOURCES.md).
diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md
index f71b9acb33..23d32effbb 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -1,6 +1,8 @@
**Table of Contents**
-1. [OpenAirInterface eNB Feature Set](#openairinterface-enb-feature-set)
+1. [Functional Split Architecture](#functional-split-architecture)
+2. [OpenAirInterface Block Diagram](#openairinterface-block-diagram)
+2. [OpenAirInterface 4G-LTE eNB Feature Set](#openairinterface-4g-lte-enb-feature-set)
1. [eNB PHY Layer](#enb-phy-layer)
2. [eNB MAC Layer](#enb-mac-layer)
3. [eNB RLC Layer](#enb-rlc-layer)
@@ -9,29 +11,38 @@
6. [eNB X2AP](#enb-x2ap)
7. [eNB/MCE M2AP](#enbmce-m2ap)
8. [MCE/MME M3AP](#mcemme-m3ap)
- 9. [eNB Advanced Features](#enb-advanced-features)
-2. [OpenAirInterface Functional Split](#openairinterface-functional-split)
-3. [OpenAirInterface UE Feature Set](#openairinterface-ue-feature-set)
+3. [OpenAirInterface 4G-LTE UE Feature Set](#openairinterface-4g-lte-ue-feature-set)
1. [LTE UE PHY Layer](#lte-ue-phy-layer)
2. [LTE UE MAC Layer](#lte-ue-mac-layer)
3. [LTE UE RLC Layer](#lte-ue-rlc-layer)
4. [LTE UE PDCP Layer](#lte-ue-pdcp-layer)
5. [LTE UE RRC Layer](#lte-ue-rrc-layer)
-4. [OpenAirInterface Functional Split](#openairinterface-functional-split)
-5. [OpenAirInterface 5G-NR Feature Set](#openairinterface-5g-nr-feature-set)
+4. [OpenAirInterface 5G-NR gNB Feature Set](#openairinterface-5g-nr-feature-set)
1. [General Parameters](#general-parameters)
- 2. [gNB Features](#gnb-features)
- 1. [gNB Physical Layer](#gnb-phy-layer)
- 2. [gNB Higher Layers](#gnb-higher-layers)
- 3. [NR UE Features](#nr-ue-features)
- 1. [NR UE Physical Layer](#nr-ue-phy-layer)
- 2. [NR UE Higher Layers](#nr-ue-higher-layers)
+ 2. [gNB Physical Layer](#gnb-phy-layer)
+ 3. [gNB Higher Layers](#gnb-higher-layers)
+5. [OpenAirInterface 5G-NR UE Feature Set](#openairinterface-5g-nr-ue-feature-set)
+ 1. [UE Physical Layer](#ue-phy-layer)
+ 2. [UE Higher Layers](#ue-higher-layers)
-# OpenAirInterface Block diagram #
+
+# Functional Split Architecture #
+
+- RCC: Radio-Cloud Center
+- RAU: Radio-Access Unit
+- RRU: Remote Radio-Unit
+- IF4.5 / IF5 : similar to IEEE P1914.1
+- FAPI (IF2) : specified by Small Cell Forum (open-nFAPI implementation)
+- IF1 : F1 in 3GPP Release 15
+
+
+
+
+# OpenAirInterface Block Diagram #

-# OpenAirInterface eNB Feature Set #
+# OpenAirInterface 4G LTE eNB Feature Set #
## eNB PHY Layer ##
@@ -82,7 +93,11 @@ TDD UL: 20 MHz, 100 PRBS/ MCS **XX** | 3.0 Mbit/s | TM1: 4.21 Mbits/s
The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support of BCH, DLSCH, RACH, and ULSCH channels.
- RRC interface for CCCH, DCCH, and DTCH
-- Proportional fair scheduler (round robin scheduler soon)
+- Proportional fair scheduler (round robin scheduler soon), with the following improvements:
+ - Up to 30 users tested in the L2 simulator, CCE allocation in the preprocessor ; the scheduler was also simplified and made more modular
+ - Adaptative UL-HARQ
+ - Remove out-of-sync UEs
+ - No use of the `first_rb` in the UL scheduler ; respects `vrb_map_UL` and `vrb_map` in the DL
- DCI generation
- HARQ Support
- RA procedures and RNTI management
@@ -123,7 +138,7 @@ The current PDCP layer is header compliant with **3GPP 36.323** Rel 10.1.0 and i
## eNB RRC Layer ##
-The RRC layer is based on **3GPP 36.331** v14.3.0 and implements the following functions:
+The RRC layer is based on **3GPP 36.331** v15.6 and implements the following functions:
- System Information broadcast (SIB 1, 2, 3, and 13)
* SIB1: Up to 6 PLMN IDs broadcast
@@ -150,6 +165,10 @@ The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following
- X2 timers (t_reloc_prep, tx2_reloc_overall)
- Handover Cancel
- X2-U interface implemented
+ - EN-DC is implemented
+ - X2AP : Handling of SgNB Addition Request / Addition Request Acknowledge / Reconfiguration Complete
+ - RRC : Handling of RRC Connection Reconfiguration with 5G cell info, configuration of 5G-NR measurements
+ - S1AP : Handling of E-RAB Modification Indication / Confirmation
## eNB/MCE M2AP ##
@@ -171,11 +190,8 @@ The M3AP layer is based on **3GPP 36.444** v14.0.1:
- M3 Session Start Request
- M3 Session Start Response
-## eNB Advanced Features ##
-**To be completed**
-
-# OpenAirInterface UE Feature Set #
+# OpenAirInterface 4G LTE UE Feature Set #
## LTE UE PHY Layer ##
@@ -230,17 +246,6 @@ The NAS layer is based on **3GPP 24.301** and implements the following functions
- EMM attach/detach, authentication, tracking area update, and more
- ESM default/dedicated bearer, PDN connectivity, and more
-# OpenAirInterface Functional Split #
-
-- RCC: Radio-Cloud Center
-- RAU: Radio-Access Unit
-- RRU: Remote Radio-Unit
-
-
-
-- IF4.5 / IF5 : similar to IEEE P1914.1
-- FAPI (IF2) : specified by Small Cell Forum (open-nFAPI implementation)
-- IF1 : F1 in 3GPP Release 15
# OpenAirInterface 5G-NR Feature Set #
@@ -258,49 +263,103 @@ The following features are valid for the gNB and the 5G-NR UE.
* Highly efficient 3GPP compliant polar encoder and decoder
* Encoder and decoder for short blocks
-## gNB Features ##
-### gNB PHY Layer ###
+## gNB PHY Layer ##
-* Generation of PSS/SSS/PBCH for multiple beams and
-* Generation of PDCCH for SIB1 (including generation of DCI, polar encoding, scrambling, modulation, RB mapping, etc)
+* 30KHz SCS for FR1 and 120 KHz SCS for FR2
+* Generation of NR-PSS/NR-SSS
+* NR-PBCH supports multiple SSBs and flexible periodicity
+* Generation of NR-PDCCH for SIB1 (including generation of DCI, polar encoding, scrambling, modulation, RB mapping, etc)
- common search space configured by MIB
- user-specific search space configured by RRC
- - DCI formats: 00, 10
-* Generation of PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
- - Single symbol DMRS, dmrs-TypeA-Position Pos2, DMRS configuration type 1
- - PDSCH mapping type A
+ - DCI formats: 00, 10 (01 and 11 **under integration**)
+* Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
+ - Single symbol DMRS, DMRS-TypeA-Position Pos2, DMRS configuration type 1
+ - PDSCH mapping type A
+* NR-CSI Generation of sequence at PHY (**under integration**)
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
* NR-PUCCH
- - Format 0 (ACK/NACK)
+ - Format 0 (2 bits, mainly for ACK/NACK)
+ - Format 2 (up to 64 bits, mainly for CSI feedback)
+* NR-PRACH
+ - Formats 0,1,2,3, A1-A3, B1-B3
+* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported)
+* Highly efficient 3GPP compliant polar encoder and decoder
+* Encoder and decoder for short block
-### gNB higher Layers ###
-
+## gNB Higher Layers ##
+
+**gNB RRC**
- NR RRC (38.331) Rel 15 messages using new asn1c
- LTE RRC (36.331) also updated to Rel 15
-- Generation of MIB
+- Generation of CellGroupConfig (for eNB) and MIB
- Application to read configuration file and program gNB RRC
-- RRC -> MAC configuration
-- MAC -> PHY configuration (using NR FAPI P5 interface)
-- FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
+- RRC can configure PDCP, RLC, MAC
-For more details see [this document](https://gitlab.eurecom.fr/oai/openairinterface5g/uploads/ba5368448d627743a28c770c29e8978e/OAI_Software_Architecture_for_Dual_Connectivity_in_E-UTRA_and_5G-NR_and_nFAPI_for_MAC-PHY_Interface.docx)
+**gNB X2AP**
+- X2 setup with eNB
+- Handling of SgNB Addition Request / Addition Request Acknowledge / Reconfiguration Complete
-## NR UE Features ##
+**gNB MAC**
+- MAC -> PHY configuration using NR FAPI P5 interface
+- MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
+- Scheduler for RA procedreat gNB
+- MAC downlink scheduler (fixed allocations)
+- MAC header generation (including timing advance)
+- ACK / NACK handling and HARQ procedures for downlink
+- **As of May 2020** only DL was validated with COTS phone ; UL in progress, validated with OAI UE in noS1 mode
-### NR UE PHY Layer ###
+# OpenAirInterface 5G-NR UE Feature Set #
-- initial synchronization
-- Time tracking based on PDCCH DMRS
-- Frequency offset estimation
-- PBCH RX
-- PDCCH RX
-- PDSCH RX
- - including first version of dual stream receiver for PDSCH
+**as of May 2020** only supporting "noS1" mode (DL):
+- Creates TUN interface to PDCP to inject and receive user-place traffic
+- Will only work with OAI gNB configured in the same mode
+
+## UE PHY Layer ##
+
+* Initial synchronization
+* Time tracking based on PBCH DMRS
+* Time tracking based on PBCH DMRS
+* Frequency offset estimation
+* PBCH RX
+* PDCCH RX
+* PDSCH RX, including a first version of dual stream receiver for PDSCH
+* 30KHz SCS for FR1 and 120 KHz SCS for FR2
+* Generation of NR-PSS/NR-SSS
+* NR-PBCH supports multiple SSBs and flexible periodicity
+* Generation of NR-PDCCH for SIB1 (including generation of DCI, polar encoding, scrambling, modulation, RB mapping, etc)
+ - common search space configured by MIB
+ - user-specific search space configured by RRC
+ - DCI formats: 00, 10 (01 and 11 **under integration**)
+* Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
+ - Single symbol DMRS, DMRS-TypeA-Position Pos2, DMRS configuration type 1
+ - PDSCH mapping type A
+* NR-CSI Generation of sequence at PHY (**under integration**)
+* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
+* NR-PUCCH
+ - Format 0 (2 bits, mainly for ACK/NACK)
+ - Format 2 (up to 64 bits, mainly for CSI feedback)
+* NR-PRACH
+ - Formats 0,1,2,3, A1-A3, B1-B3
+* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported)
+* Highly efficient 3GPP compliant polar encoder and decoder
+* Encoder and decoder for short block
+
+
+## UE Higher Layers ##
+
+**gNB MAC**
+- Initial sync and MIB detection
+- MAC -> PHY configuration of PHY via UE FAPI P5 interface
+- Basic MAC to control PHY via UE FAPI P7 interface
+- Random access procedure
+
+
+**RLC**
+
+**PDCP**
-### NR UE higher Layers ###
-For more details see [this document](https://gitlab.eurecom.fr/oai/openairinterface5g/uploads/f7386f3a64806fd6b2ac1fc3d0252fff/UE_FAPI-like_interface.docx)
[OAI wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index 0c66b58547..37eadd92f3 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -56,9 +56,56 @@ oai supports [number of deployment](FEATURE_SET.md) model, the following are tes
1. [Monolithic eNodeB](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/HowToConnectCOTSUEwithOAIeNBNew) where the whole signal processing is performed in a single process
2. if4p5 mode, where frequency domain samples are carried over ethernet, from the RRU which implement part of L1(FFT,IFFT,part of PRACH), to a RAU
+# 5G NR
+
+As of February 2020, all 5G NR development is part of the develop branch (the branch develop-nr is no longer maintained). This also means that all new development will be merged into there once it passes all the CI.
+
+## NSA setup with COTS UE
+
+This setup requires an EPC, an OAI eNB and gNB, and a COTS Phone. A dedicated page describe the setup can be found [here](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home/gNB-COTS-UE-testing).
+
+### Launch gNB
+
+```bash sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf```
+
+### Launch eNB
+
+```bash sudo ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf```
+## phy-test setup with OAI UE
+
+The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC. In this case both gNB and eNB need to be run with the --phy-test flag. At the gNB this flag does the following
+ - it reads the RRC configuration from the configuration file
+ - it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw
+ - the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload
+
+At the UE the --phy-test flag will
+ - read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them.
+
+
+### Launch gNB
+
+```bash sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test```
+
+### Launch UE in another window
+
+```bash sudo ./nr-uesoftmodem --phy-test [--rrc_config_path ../../../ci-scripts/rrc-files]```
+
+Some other useful paramters of the UE are
+
+ - --ue-fo-compensation: enables the frequency offset compenstation at the UE. This is useful when running over the air and/or without an external clock/time source
+ - --usrp-args: this is the equivalend paramter of sdr_addrs field in the gNB config file and can be used to identify the USRP and set some basic paramters (like the clock source)
+ - --clock-source: sets the clock-source (internal or external).
+ - --time-source: sets the time-source (internal or external).
+
+
+## noS1 setup with OAI UE
+
+Instead of randomly generated payload, in the phy-test mode we can also inject/receive user-plane traffic over a TUN interface. This is the so-called noS1 mode.
+
+This setup is described in the [rfsimulator page](../targets/ARCH/rfsimulator/README.md#5g-case). In theory this should also work with the real hardware target although this has yet to be tested.
diff --git a/executables/main-ocp.c b/executables/main-ocp.c
index d2ee9418dc..e4e42b4f23 100644
--- a/executables/main-ocp.c
+++ b/executables/main-ocp.c
@@ -80,6 +80,7 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
int split73;
char * split73_config;
int split73;
+int usrp_tx_thread = 0;
static void *ru_thread( void *param );
void kill_RU_proc(RU_t *ru) {
@@ -1152,6 +1153,7 @@ int restart_L1L2(module_id_t enb_id) {
}
int main ( int argc, char **argv ) {
+ //mtrace();
int i;
int CC_id = 0;
int node_type = ngran_eNB;
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index aa16c771ae..27b0ed08dd 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -47,7 +47,7 @@
#include "SCHED/sched_eNB.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
-#include "PHY/LTE_TRANSPORT/transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
@@ -61,7 +61,6 @@
#include "PHY/phy_extern.h"
-
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface.h"
@@ -162,14 +161,14 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
/*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
- gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
+ gNB->UL_INFO.rach_ind.number_of_pdus ||
gNB->UL_INFO.cqi_ind.number_of_cqis
) {
- LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
+ LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d rach_pdus:%0d.%d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
- NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
+ gNB->UL_INFO.rach_ind.sfn, gNB->UL_INFO.rach_ind.slot,gNB->UL_INFO.rach_ind.number_of_pdus,
gNB->UL_INFO.cqi_ind.number_of_cqis,
frame_rx, slot_rx,
frame_tx, slot_tx);
@@ -202,6 +201,13 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
// UE-specific RX processing for subframe n
// TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
+
+ // Do PRACH RU processing
+ int prach_id=find_nr_prach(gNB,frame_rx,slot_rx,0,SEARCH_EXIST);
+ if (prach_id>=0) {
+ L1_nr_prach_procedures(gNB,frame_rx,slot_rx,&gNB->prach_vars.list[prach_id].pdu);
+ gNB->prach_vars.list[prach_id].frame=-1;
+ }
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
}
@@ -957,12 +963,14 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
LOG_I(PHY,"Setting indication lists\n");
+
gNB->UL_INFO.rx_ind.pdu_list = gNB->rx_pdu_list;
gNB->UL_INFO.crc_ind.crc_list = gNB->crc_pdu_list;
/*gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list;
gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/
+
gNB->prach_energy_counter = 0;
}
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 3ea026f6e6..969ad21b8e 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -51,6 +51,7 @@
#include "PHY/defs_nr_common.h"
#include "PHY/phy_extern.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/INIT/phy_init.h"
#include "SCHED/sched_eNB.h"
#include "SCHED_NR/sched_nr.h"
@@ -117,6 +118,7 @@ uint16_t sl_ahead;
extern int emulate_rf;
extern int numerology;
+extern int usrp_tx_thread;
/*************************************************************/
/* Functions to attach and configure RRU */
@@ -289,7 +291,7 @@ void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
// southbound IF4p5 fronthaul
void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
{
- nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx);
@@ -500,7 +502,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
RU_proc_t *proc = &ru->proc;
uint16_t packet_type;
uint32_t symbol_number,symbol_mask,symbol_mask_full=0;
@@ -697,7 +699,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
void *txp[ru->nb_tx];
unsigned int txs;
int i,txsymb;
@@ -770,8 +772,8 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
siglen+sf_extension,
ru->nb_tx,
flags);
- LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %d\n",ru->idx,
- (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot);
+ LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %di, returned %d\n",ru->idx,
+ (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot, txs);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
//AssertFatal(txs == 0,"trx write function error %d\n", txs);
}
@@ -789,7 +791,7 @@ void *ru_thread_asynch_rxtx( void *param ) {
static int ru_thread_asynch_rxtx_status;
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
- nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
int slot=0, frame=0;
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
wait_sync("ru_thread_asynch_rxtx");
@@ -1034,10 +1036,10 @@ int wakeup_prach_ru(RU_t *ru) {
void fill_rf_config(RU_t *ru, char *rf_config_file) {
int i;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index
+ nfapi_nr_config_request_scf_t *config = &ru->config; //tmp index
openair0_config_t *cfg = &ru->openair0_cfg;
- int mu = gNB_config->ssb_config.scs_common.value;
- int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
+ int mu = config->ssb_config.scs_common.value;
+ int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
if (mu == NR_MU_0) { //or if LTE
if(N_RB == 100) {
@@ -1122,7 +1124,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu);
}
- if (gNB_config->cell_config.frame_duplex_type.value==TDD)
+ if (config->cell_config.frame_duplex_type.value==TDD)
cfg->duplex_mode = duplex_mode_TDD;
else //FDD
cfg->duplex_mode = duplex_mode_FDD;
@@ -1161,7 +1163,7 @@ int setup_RU_buffers(RU_t *ru) {
int card,ant;
//uint16_t N_TA_offset = 0;
NR_DL_FRAME_PARMS *frame_parms;
- //nfapi_nr_config_request_t *gNB_config = ru->gNB_list[0]->gNB_config; //tmp index
+ nfapi_nr_config_request_scf_t *config = &ru->config;
if (ru) {
frame_parms = ru->nr_frame_parms;
@@ -1170,12 +1172,54 @@ int setup_RU_buffers(RU_t *ru) {
printf("ru pointer is NULL\n");
return(-1);
}
+ int mu = config->ssb_config.scs_common.value;
+ int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
- /* if (frame_parms->frame_type == TDD) {
- if (frame_parms->N_RB_DL == 100) ru->N_TA_offset = 624;
- else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2;
- else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4;
- } */
+
+ if (config->cell_config.frame_duplex_type.value == TDD) {
+ int N_TA_offset = config->carrier_config.uplink_frequency.value < 6000000 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
+
+ double factor=1;
+
+ switch (mu) {
+ case 0: //15 kHz scs
+ AssertFatal(N_TA_offset == 400,"scs_common 15kHz only for FR1\n");
+ if (N_RB <= 25) factor = .25; // 7.68 Ms/s
+ else if (N_RB <=50) factor = .5; // 15.36 Ms/s
+ else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s
+ else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
+ else AssertFatal(1==0,"Too many PRBS for mu=0\n");
+ break;
+ case 1: //30 kHz sc
+ AssertFatal(N_TA_offset == 400,"scs_common 30kHz only for FR1\n");
+ if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
+ else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
+ break;
+ case 2: //60 kHz scs
+ AssertFatal(1==0,"scs_common should not be 60 kHz\n");
+ break;
+ case 3: //120 kHz scs
+ AssertFatal(N_TA_offset == 431,"scs_common 120kHz only for FR2\n");
+ break;
+ case 4: //240 kHz scs
+ AssertFatal(1==0,"scs_common should not be 60 kHz\n");
+ if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
+ else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
+ else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB);
+ break;
+
+ if (N_RB == 100) ru->N_TA_offset = 624;
+ else if (N_RB == 50) ru->N_TA_offset = 624/2;
+ else if (N_RB == 25) ru->N_TA_offset = 624/4;
+ }
+ if (frame_parms->threequarter_fs == 1) factor = factor*.75;
+ ru->N_TA_offset = (int)(N_TA_offset * factor);
+ LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d)\n",ru->idx,ru->N_TA_offset,factor,
+ config->carrier_config.uplink_frequency.value, N_RB);
+ }
+ else ru->N_TA_offset = 0;
+
+
if (ru->openair0_cfg.mmapped_dma == 1) {
// replace RX signal buffers with mmaped HW versions
for (i=0; inb_rx; i++) {
@@ -1388,7 +1432,7 @@ void *ru_thread( void *param ) {
int i = 0;
int aa;
- nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
// set default return value
ru_thread_status = 0;
@@ -1400,7 +1444,7 @@ void *ru_thread( void *param ) {
if(emulate_rf) {
fill_rf_config(ru,ru->rf_config_file);
- nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp);
+ nr_init_frame_parms(&ru->config, fp);
nr_dump_frame_parms(fp);
nr_phy_init_RU(ru);
@@ -1420,8 +1464,10 @@ void *ru_thread( void *param ) {
AssertFatal(ret==0,"Cannot connect to remote radio\n");
}
+ memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
+
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
- nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp);
+ nr_init_frame_parms(&ru->config, fp);
nr_dump_frame_parms(fp);
fill_rf_config(ru,ru->rf_config_file);
nr_phy_init_RU(ru);
@@ -1465,12 +1511,14 @@ void *ru_thread( void *param ) {
if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
// start trx write thread
- if (ru->start_write_thread){
- if(ru->start_write_thread(ru) != 0){
- LOG_E(HW,"Could not start tx write thread\n");
- }
- else{
- LOG_I(PHY,"tx write thread ready\n");
+ if(usrp_tx_thread == 1){
+ if (ru->start_write_thread){
+ if(ru->start_write_thread(ru) != 0){
+ LOG_E(HW,"Could not start tx write thread\n");
+ }
+ else{
+ LOG_I(PHY,"tx write thread ready\n");
+ }
}
}
}
@@ -1532,6 +1580,17 @@ void *ru_thread( void *param ) {
for (aa=0;aanb_rx;aa++)
memcpy((void*)RC.gNB[0]->common_vars.rxdataF[aa],
(void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
+
+ // Do PRACH RU processing
+ int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
+ if (prach_id>=0) {
+ rx_nr_prach_ru(ru,
+ ru->prach_list[prach_id].fmt,
+ ru->prach_list[prach_id].numRA,
+ ru->prach_list[prach_id].prachStartSymbol,
+ proc->frame_rx,proc->tti_rx);
+ free_nr_ru_prach_entry(ru,prach_id);
+ }
}
// At this point, all information for subframe has been received on FH interface
@@ -1903,7 +1962,7 @@ void configure_ru(int idx,
RU_t *ru = RC.ru[idx];
RRU_config_t *config = (RRU_config_t *)arg;
RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg;
- nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
int ret;
LOG_I(PHY, "Received capabilities from RRU %d\n",idx);
@@ -1926,15 +1985,15 @@ void configure_ru(int idx,
//config->tdd_config_S[0] = ru->nr_frame_parms->tdd_config_S;
config->att_tx[0] = ru->att_tx;
config->att_rx[0] = ru->att_rx;
- config->N_RB_DL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
- config->N_RB_UL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
+ config->N_RB_DL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value;
+ config->N_RB_UL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value;
config->threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs;
/* if (ru->if_south==REMOTE_IF4p5) {
config->prach_FreqOffset[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset;
config->prach_ConfigIndex[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n",
config->prach_FreqOffset[0],config->prach_ConfigIndex[0]);*/
- nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, ru->nr_frame_parms);
+ nr_init_frame_parms(&ru->config, ru->nr_frame_parms);
nr_phy_init_RU(ru);
}
@@ -1942,23 +2001,23 @@ void configure_rru(int idx,
void *arg) {
RRU_config_t *config = (RRU_config_t *)arg;
RU_t *ru = RC.ru[idx];
- nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
ru->nr_frame_parms->nr_band = config->band_list[0];
ru->nr_frame_parms->dl_CarrierFreq = config->tx_freq[0];
ru->nr_frame_parms->ul_CarrierFreq = config->rx_freq[0];
if (ru->nr_frame_parms->dl_CarrierFreq == ru->nr_frame_parms->ul_CarrierFreq) {
- gNB_config->cell_config.frame_duplex_type.value = TDD;
+ cfg->cell_config.frame_duplex_type.value = TDD;
//ru->nr_frame_parms->tdd_config = config->tdd_config[0];
//ru->nr_frame_parms->tdd_config_S = config->tdd_config_S[0];
} else
- gNB_config->cell_config.frame_duplex_type.value = FDD;
+ cfg->cell_config.frame_duplex_type.value = FDD;
ru->att_tx = config->att_tx[0];
ru->att_rx = config->att_rx[0];
- int mu = gNB_config->ssb_config.scs_common.value;
- gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0];
- gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0];
+ int mu = cfg->ssb_config.scs_common.value;
+ cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0];
+ cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0];
ru->nr_frame_parms->threequarter_fs = config->threequarter_fs[0];
//ru->nr_frame_parms->pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0];
@@ -1973,7 +2032,7 @@ void configure_rru(int idx,
}
fill_rf_config(ru,ru->rf_config_file);
- nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, ru->nr_frame_parms);
+ nr_init_frame_parms(&ru->config, ru->nr_frame_parms);
nr_phy_init_RU(ru);
}
diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h
index ccb3f28d98..c968fee7b6 100644
--- a/executables/nr-softmodem-common.h
+++ b/executables/nr-softmodem-common.h
@@ -57,6 +57,7 @@
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
+#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n"
#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n"
#define CONFIG_HLP_EXCCLK "tells hardware to use a clock reference (0:internal(default), 1:external, 2:gpsdo)\n"
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
@@ -89,6 +90,7 @@
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
+#define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n"
@@ -143,6 +145,10 @@ extern int sync_var;
extern int transmission_mode;
extern double cpuf;
+extern int emulate_rf;
+extern int numerology;
+extern int usrp_tx_thread;
+
extern volatile int start_eNB;
extern volatile int start_UE;
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index f473d0161b..bf77125975 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -178,10 +178,12 @@ extern void reset_opp_meas(void);
extern void print_opp_meas(void);
extern void init_eNB_afterRU(void);
+extern void *udp_eNB_task(void *args_p);
int transmission_mode=1;
int emulate_rf = 0;
int numerology = 0;
+int usrp_tx_thread = 0;
static char *parallel_config = NULL;
@@ -384,10 +386,10 @@ int create_gNB_tasks(uint32_t gnb_nb) {
if (gnb_nb > 0) {
/* Last task to create, others task must be ready before its start */
- if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
+ /*if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
LOG_E(GNB_APP, "Create task for gNB APP failed\n");
return -1;
- }
+ }*/
if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){
LOG_E(SCTP, "Create task for SCTP failed\n");
return -1;
@@ -402,35 +404,39 @@ int create_gNB_tasks(uint32_t gnb_nb) {
}
}
- /*
- if (EPC_MODE_ENABLED) {
- if (gnb_nb > 0) {
- if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
- LOG_E(SCTP, "Create task for SCTP failed\n");
- return -1;
- }
+ if (EPC_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) {
+ if (gnb_nb > 0) {
+ /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
+ LOG_E(SCTP, "Create task for SCTP failed\n");
+ return -1;
+ }
- if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
- LOG_E(S1AP, "Create task for S1AP failed\n");
- return -1;
- }
- if(!emulate_rf){
- if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
- LOG_E(UDP_, "Create task for UDP failed\n");
- return -1;
- }
- }
+ if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
+ LOG_E(S1AP, "Create task for S1AP failed\n");
+ return -1;
+ }*/
- if (itti_create_task (TASK_GTPV1_U, >pv1u_eNB_task, NULL) < 0) {
- LOG_E(GTPU, "Create task for GTPV1U failed\n");
- return -1;
- }
+
+ if(!emulate_rf){
+ if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
+ LOG_E(UDP_, "Create task for UDP failed\n");
+ return -1;
}
+ }
+ if (itti_create_task (TASK_GTPV1_U, >pv1u_gNB_task, NULL) < 0) {
+ LOG_E(GTPU, "Create task for GTPV1U failed\n");
+ return -1;
+ }
}
- */
+ }
+
if (gnb_nb > 0) {
+ if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
+ LOG_E(GNB_APP, "Create task for gNB APP failed\n");
+ return -1;
+ }
LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
@@ -819,6 +825,10 @@ int main( int argc, char **argv )
}
openair0_cfg[0].threequarter_fs = threequarter_fs;
+ EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test;
+
+ if (get_softmodem_params()->do_ra)
+ AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
#if T_TRACER
T_Config_Init();
@@ -954,7 +964,9 @@ if(!IS_SOFTMODEM_NOS1)
scopeParms_t p;
p.argc=&argc;
p.argv=argv;
- startScope(&p);
+ p.gNB=RC.gNB[0];
+ p.ru=RC.ru[0];
+ gNBinitScope(&p);
}
if (nfapi_mode != 1 && nfapi_mode != 2) {
diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h
index 27e3ba1e3e..d113ae45aa 100644
--- a/executables/nr-softmodem.h
+++ b/executables/nr-softmodem.h
@@ -34,6 +34,7 @@
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
+ {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
}
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index dbee6f1e6f..2f99027b75 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -21,7 +21,7 @@
#include "executables/thread-common.h"
#include "executables/nr-uesoftmodem.h"
-#include "LAYER2/NR_MAC_UE/mac.h"
+#include "NR_MAC_UE/mac.h"
//#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface_extern.h"
@@ -32,7 +32,7 @@
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_UE.h"
-#include "LAYER2/NR_MAC_UE/mac_proto.h"
+#include "NR_MAC_UE/mac_proto.h"
#include "RRC/NR_UE/rrc_proto.h"
//#ifndef NO_RAT_NR
@@ -142,15 +142,24 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
uint8_t abstraction_flag)
{
+ int nb_connected_gNB = 1, gNB_id;
+
memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS));
ue->Mod_id = UE_id;
ue->mac_enabled = 1;
+ // Setting UE mode to NOT_SYNCHED by default
+ for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){
+ ue->UE_mode[gNB_id] = NOT_SYNCHED;
+ ue->prach_resources[gNB_id] = (NR_PRACH_RESOURCES_t *)malloc16_clear(sizeof(NR_PRACH_RESOURCES_t));
+ }
+
// initialize all signal buffers
- init_nr_ue_signal(ue,1,abstraction_flag);
+ init_nr_ue_signal(ue, nb_connected_gNB, abstraction_flag);
+
// intialize transport
- init_nr_ue_transport(ue,abstraction_flag);
+ init_nr_ue_transport(ue, abstraction_flag);
}
/*!
@@ -358,82 +367,32 @@ static void UE_synch(void *arg) {
void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
- uint32_t rb_size, rb_start;
- uint16_t rnti, l_prime_mask, n_rb0, n_rb1, pdu_bit_map;
- uint8_t nr_of_symbols, start_symbol_index, mcs_index, mcs_table, nrOfLayers, harq_process_id, rv_index, dmrs_config_type;
- uint8_t ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, ptrs_time_density, ptrs_freq_density;
- nr_dcireq_t dcireq;
- nr_scheduled_response_t scheduled_response;
- // program PUSCH. this should actually be done by the MAC upon reception of an UL DCI
- if (proc->nr_tti_tx == 8 || UE->frame_parms.frame_type == FDD){
+ fapi_nr_config_request_t *cfg = &UE->nrUE_config;
+ int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_tti_tx);
+ uint8_t gNB_id = 0;
- dcireq.module_id = UE->Mod_id;
- dcireq.gNB_index = 0;
- dcireq.cc_id = 0;
- dcireq.frame = proc->frame_rx;
- dcireq.slot = proc->nr_tti_rx;
+ if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){
- scheduled_response.dl_config = NULL;
- scheduled_response.ul_config = &dcireq.ul_config_req;
- scheduled_response.tx_request = NULL;
- scheduled_response.module_id = UE->Mod_id;
- scheduled_response.CC_id = 0;
- scheduled_response.frame = proc->frame_rx;
- scheduled_response.slot = proc->nr_tti_rx;
- //--------------------------Temporary configuration-----------------------------//
- rnti = 0x1234;
- rb_size = 50;
- rb_start = 0;
- nr_of_symbols = 12;
- start_symbol_index = 2;
- nrOfLayers = 1;
- mcs_index = 9;
- mcs_table = 0;
- harq_process_id = 0;
- rv_index = 0;
- l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
- dmrs_config_type = 0;
- ptrs_mcs1 = 2;
- ptrs_mcs2 = 4;
- ptrs_mcs3 = 10;
- n_rb0 = 25;
- n_rb1 = 75;
- pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
- ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table);
- ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size);
- //------------------------------------------------------------------------------//
+ // trigger L2 to run ue_scheduler thru IF module
+ // [TODO] mapping right after NR initial sync
+ if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
+ nr_uplink_indication_t ul_indication;
+ memset((void*)&ul_indication, 0, sizeof(ul_indication));
- scheduled_response.ul_config->slot = 8;
- scheduled_response.ul_config->number_pdus = 1;
- scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
+ ul_indication.module_id = UE->Mod_id;
+ ul_indication.gNB_index = gNB_id;
+ ul_indication.cc_id = UE->CC_id;
+ ul_indication.frame_rx = proc->frame_rx;
+ ul_indication.slot_rx = proc->nr_tti_rx;
+ ul_indication.frame_tx = proc->frame_tx;
+ ul_indication.slot_tx = proc->nr_tti_tx;
- if (1 << ptrs_time_density >= nr_of_symbols) {
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
+ UE->if_inst->ul_indication(&ul_indication);
}
- nr_ue_scheduled_response(&scheduled_response);
-
if (UE->mode != loop_through_memory) {
- uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx];
+ uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_rx];
phy_procedures_nrUE_TX(UE,proc,0,thread_id);
}
}
@@ -441,41 +400,26 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
- nr_dcireq_t dcireq;
- nr_scheduled_response_t scheduled_response;
- uint8_t ssb_period = UE->nrUE_config.ssb_table.ssb_period;
+ fapi_nr_config_request_t *cfg = &UE->nrUE_config;
+ int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_tti_rx);
+ uint8_t gNB_id = 0;
- //program DCI for slot 1
- //TODO: all of this has to be moved to the MAC!!!
- if (proc->nr_tti_rx == NR_DOWNLINK_SLOT || UE->frame_parms.frame_type == FDD){
- dcireq.module_id = UE->Mod_id;
- dcireq.gNB_index = 0;
- dcireq.cc_id = 0;
- dcireq.frame = proc->frame_rx;
- dcireq.slot = proc->nr_tti_rx;
- nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
+ if (rx_slot_type == NR_DOWNLINK_SLOT || rx_slot_type == NR_MIXED_SLOT){
- // we should have received a DL DCI here, so configure DL accordingly
- scheduled_response.dl_config = &dcireq.dl_config_req;
- scheduled_response.ul_config = NULL;
- scheduled_response.tx_request = NULL;
- scheduled_response.module_id = UE->Mod_id;
- scheduled_response.CC_id = 0;
- if (!((proc->frame_rx)%(1<<(ssb_period-1)))) {
- if(proc->frame_rx > dcireq.dl_config_req.sfn)
- UE->frame_gap = proc->frame_rx - dcireq.dl_config_req.sfn;
- if(proc->frame_rx < dcireq.dl_config_req.sfn)
- UE->frame_gap = dcireq.dl_config_req.sfn - proc->frame_rx;
- proc->frame_rx = dcireq.dl_config_req.sfn;
+ if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
+ nr_downlink_indication_t dl_indication;
+ memset((void*)&dl_indication, 0, sizeof(dl_indication));
+
+ dl_indication.module_id = UE->Mod_id;
+ dl_indication.gNB_index = gNB_id;
+ dl_indication.cc_id = UE->CC_id;
+ dl_indication.frame = proc->frame_rx;
+ dl_indication.slot = proc->nr_tti_rx;
+
+ UE->if_inst->dl_indication(&dl_indication, NULL);
}
- scheduled_response.frame = proc->frame_rx;
- scheduled_response.slot = proc->nr_tti_rx;
-
- nr_ue_scheduled_response(&scheduled_response);
- }
// Process Rx data for one sub-frame
- if ( proc->nr_tti_rx >=0 && proc->nr_tti_rx <= 1 ) {
#ifdef UE_SLOT_PARALLELISATION
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
@@ -510,6 +454,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
}
}
*/
+
}
/*!
@@ -526,7 +471,7 @@ typedef struct processingData_s {
} processingData_t;
void UE_processing(void *arg) {
- processingData_t *rxtxD=(processingData_t *) arg;
+ processingData_t *rxtxD = (processingData_t *) arg;
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
@@ -556,9 +501,7 @@ void UE_processing(void *arg) {
}
processSlotRX(UE, proc);
-
processSlotTX(UE, proc);
-
}
void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
@@ -633,8 +576,9 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
}
int computeSamplesShift(PHY_VARS_NR_UE *UE) {
+
if (IS_SOFTMODEM_RFSIM) {
- LOG_E(PHY,"SET rx_offset %d \n",UE->rx_offset);
+ LOG_D(PHY,"SET rx_offset %d \n",UE->rx_offset);
//UE->rx_offset_diff=0;
return 0;
}
@@ -704,8 +648,11 @@ void *UE_thread(void *arg) {
if (res) {
syncRunning=false;
syncData_t *tmp=(syncData_t *)NotifiedFifoData(res);
- // shift the frame index with all the frames we trashed meanwhile we perform the synch search
- decoded_frame_rx=(tmp->proc.decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
+ if (UE->is_synchronized) {
+ decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
+ // shift the frame index with all the frames we trashed meanwhile we perform the synch search
+ decoded_frame_rx=(decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
+ }
delNotifiedFIFO_elt(res);
} else {
readFrame(UE, ×tamp, true);
@@ -750,6 +697,7 @@ void *UE_thread(void *arg) {
absolute_slot++;
+
// whatever means thread_idx
// Fix me: will be wrong when slot 1 is slow, as slot 2 finishes
// Slot 3 will overlap if RX_NB_TH is 2
@@ -762,13 +710,13 @@ void *UE_thread(void *arg) {
curMsg->UE=UE;
// update thread index for received subframe
curMsg->UE->current_thread_id[slot_nr] = thread_idx;
- curMsg->proc.CC_id = 0;
+ curMsg->proc.CC_id = UE->CC_id;
curMsg->proc.nr_tti_rx= slot_nr;
curMsg->proc.subframe_rx=slot_nr/(nb_slot_frame/10);
curMsg->proc.nr_tti_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
curMsg->proc.subframe_tx=curMsg->proc.nr_tti_rx;
- curMsg->proc.frame_rx = ((absolute_slot/nb_slot_frame)+UE->frame_gap) % MAX_FRAME_NUMBER;
- curMsg->proc.frame_tx = (((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame)+UE->frame_gap) % MAX_FRAME_NUMBER;
+ curMsg->proc.frame_rx = (absolute_slot/nb_slot_frame) % MAX_FRAME_NUMBER;
+ curMsg->proc.frame_tx = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg->proc.decoded_frame_rx=-1;
//LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB);
@@ -857,8 +805,9 @@ void *UE_thread(void *arg) {
usleep(200);
}
- if ( decoded_frame_rx != curMsg->proc.frame_rx &&
- ((decoded_frame_rx+1) % MAX_FRAME_NUMBER) != curMsg->proc.frame_rx )
+ if ( (decoded_frame_rx != curMsg->proc.frame_rx) &&
+ (((decoded_frame_rx+1) % MAX_FRAME_NUMBER) != curMsg->proc.frame_rx) &&
+ (((decoded_frame_rx+2) % MAX_FRAME_NUMBER) != curMsg->proc.frame_rx))
LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
decoded_frame_rx, curMsg->proc.frame_rx );
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 9b2b704833..6d3bbc9038 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -76,36 +76,11 @@ unsigned short config_frames[4] = {2,9,11,13};
#include
#include
-#include
-
-
-/* Callbacks, globals and object handlers */
-
-extern void reset_stats( FL_OBJECT *, long );
-//extern void initTpool(char *params, tpool_t *pool, bool performanceMeas);
-
-/* Forms and Objects */
-
-typedef struct {
- FL_FORM *stats_form;
- void *vdata;
- char *cdata;
- long ldata;
- FL_OBJECT *stats_text;
- FL_OBJECT *stats_button;
-} FD_stats_form;
-
-extern FD_stats_form *create_form_stats_form( void );
-
-#include "PHY/TOOLS/nr_phy_scope.h"
//#include "stats.h"
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
+#include "PHY/TOOLS/nr_phy_scope.h"
// at eNB 0, an UL scope for every UE
-FD_phy_scope_nrue *form_nrue[NUMBER_OF_UE_MAX];
//FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
-char title[255];
-static pthread_t forms_thread; //xforms
#include
#include "executables/softmodem-common.h"
@@ -198,6 +173,7 @@ uint64_t num_missed_slots=0; // counter for the number of missed slots
int transmission_mode=1;
int numerology = 0;
+int usrp_tx_thread = 0;
/* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */
//uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD;
@@ -274,7 +250,7 @@ void exit_function(const char *file, const char *function, const int line, const
}
-void reset_stats(FL_OBJECT *button, long arg) {
+void reset_stats(long arg) {
//int i,j,k;
/*PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
@@ -304,35 +280,6 @@ void reset_stats(FL_OBJECT *button, long arg) {
}*/
}
-static void *scope_thread(void *arg) {
- sleep(5);
-
- while (!oai_exit) {
- phy_scope_nrUE(form_nrue[0],
- PHY_vars_UE_g[0][0],
- 0,0,1);
- usleep(100*1000);
- }
-
- pthread_exit((void *)arg);
-}
-
-
-void init_scope(void) {
- int fl_argc=1;
-
- if (do_forms==1) {
- char *name="5G-UE-scope";
- fl_initialize (&fl_argc, &name, NULL, 0, 0);
- int UE_id = 0;
- form_nrue[UE_id] = create_phy_scope_nrue();
- sprintf (title, "NR DL SCOPE UE");
- fl_show_form (form_nrue[UE_id]->phy_scope_nrue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
- threadCreate(&forms_thread, scope_thread, NULL, "scope", -1, OAI_PRIORITY_RT_LOW);
- }
-
-}
-
void *l2l1_task(void *arg) {
MessageDef *message_p = NULL;
int result;
@@ -720,6 +667,9 @@ int main( int argc, char **argv ) {
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE **));
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs);
+ if (get_softmodem_params()->do_ra)
+ AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
+
for (int CC_id=0; CC_idofdm_symbol_size);
frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx;
@@ -746,11 +696,6 @@ int main( int argc, char **argv ) {
init_nr_ue_vars(UE[CC_id],frame_parms[CC_id],0,abstraction_flag);
- if (get_softmodem_params()->phy_test==1)
- UE[CC_id]->mac_enabled = 0;
- else
- UE[CC_id]->mac_enabled = 1;
-
UE[CC_id]->mac_enabled = 1;
UE[CC_id]->if_inst = nr_ue_if_module_init(0);
UE[CC_id]->UE_scan = UE_scan;
@@ -763,15 +708,49 @@ int main( int argc, char **argv ) {
UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off;
UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
- if (frame_parms[CC_id]->frame_type==FDD) {
+ if (UE[CC_id]->frame_parms.frame_type == FDD) {
UE[CC_id]->N_TA_offset = 0;
} else {
- if (frame_parms[CC_id]->N_RB_DL == 100)
- UE[CC_id]->N_TA_offset = 624;
- else if (frame_parms[CC_id]->N_RB_DL == 50)
- UE[CC_id]->N_TA_offset = 624/2;
- else if (frame_parms[CC_id]->N_RB_DL == 25)
- UE[CC_id]->N_TA_offset = 624/4;
+ int N_RB = UE[CC_id]->frame_parms.N_RB_DL;
+ int N_TA_offset = UE[CC_id]->frame_parms.ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
+ double factor=1;
+ switch (UE[CC_id]->frame_parms.numerology_index) {
+ case 0: //15 kHz scs
+ AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n");
+ if (N_RB <= 25) factor = .25; // 7.68 Ms/s
+ else if (N_RB <=50) factor = .5; // 15.36 Ms/s
+ else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s
+ else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
+ else AssertFatal(1==0,"Too many PRBS for mu=0\n");
+ break;
+ case 1: //30 kHz sc
+ AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n");
+ if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
+ else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
+ break;
+ case 2: //60 kHz scs
+ AssertFatal(1==0,"scs_common should not be 60 kHz\n");
+ break;
+ case 3: //120 kHz scs
+ AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n");
+ break;
+ case 4: //240 kHz scs
+ AssertFatal(1==0,"scs_common should not be 60 kHz\n");
+ if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
+ else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
+ else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB);
+ break;
+
+ if (N_RB == 100)
+ UE[CC_id]->N_TA_offset = 624;
+ else if (N_RB == 50)
+ UE[CC_id]->N_TA_offset = 624/2;
+ else if (N_RB == 25)
+ UE[CC_id]->N_TA_offset = 624/4;
+ }
+ if (UE[CC_id]->frame_parms.threequarter_fs == 1) factor = factor*.75;
+ UE[CC_id]->N_TA_offset = (int)(N_TA_offset * factor);
+ LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", UE[CC_id]->Mod_id, UE[CC_id]->N_TA_offset, factor, UE[CC_id]->frame_parms.ul_CarrierFreq, N_RB);
}
}
@@ -782,7 +761,8 @@ int main( int argc, char **argv ) {
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
configure_linux();
mlockall(MCL_CURRENT | MCL_FUTURE);
- init_scope();
+ if (do_forms)
+ nrUEinitScope(PHY_vars_UE_g[0][0]);
number_of_cards = 1;
for(int CC_id=0; CC_id
#include "PHY/defs_nr_UE.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
-#include
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index 0ac7b6449e..449d2e0957 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -55,6 +55,7 @@ extern "C"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
+#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n"
#define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n"
#define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0"
#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n"
@@ -97,6 +98,7 @@ extern "C"
#define SPLIT73 softmodem_params.split73
#define TP_CONFIG softmodem_params.threadPoolConfig
#define PHY_TEST softmodem_params.phy_test
+#define DO_RA softmodem_params.do_ra
#define WAIT_FOR_SYNC softmodem_params.wait_for_sync
#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag
#define CHAIN_OFFSET softmodem_params.chain_offset
@@ -114,6 +116,7 @@ extern "C"
{"split73", CONFIG_HLP_SPLIT73, 0, strptr:(char **)&SPLIT73, defstrval:NULL, TYPE_STRING, sizeof(SPLIT73)},\
{"thread-pool", CONFIG_HLP_TPOOL, 0, strptr:(char **)&TP_CONFIG, defstrval:"n", TYPE_STRING, sizeof(TP_CONFIG)}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
+ {"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, iptr:&DO_RA, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
{"clock-source", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"time-source", CONFIG_HLP_TME, 0, uptr:&TIMING_SOURCE, defintval:0, TYPE_UINT, 0}, \
@@ -205,6 +208,7 @@ typedef struct {
char split73[1024];
char threadPoolConfig[1024];
int phy_test;
+ int do_ra;
uint8_t usim_test;
int emulate_rf;
int wait_for_sync; //eNodeB only
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
index cbcd26c3e3..e1d06335f5 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
@@ -18,6 +18,7 @@
#define FAPI_NR_RX_PDU_TYPE_SIB 0x02
#define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03
#define FAPI_NR_DCI_IND 0x04
+#define FAPI_NR_RX_PDU_TYPE_RAR 0x05
#define FAPI_NR_SIBS_MASK_SIB1 0x1
@@ -42,6 +43,7 @@
#define FAPI_NR_DL_CONFIG_TYPE_DCI 0x01
#define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02
+#define FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH 0x03
#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index 2c3809f5d4..246ab13e86 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -62,7 +62,7 @@ typedef struct {
uint8_t CoreSetType;
uint8_t precoder_granularity;
uint16_t pdcch_dmrs_scrambling_id;
-
+ uint16_t scrambling_rnti;
uint8_t tci_state_pdcch;
uint8_t tci_present_in_dci;
} fapi_nr_coreset_t;
@@ -158,22 +158,29 @@ typedef struct {
fapi_nr_tx_request_body_t *tx_request_body;
} fapi_nr_tx_request_t;
- typedef struct {
- uint8_t preamble_index;
- uint8_t prach_configuration_index;
- uint16_t preamble_length;
- uint8_t power_ramping_step;
- uint16_t preamble_received_target_power;
- uint8_t msg1_fdm;
- uint8_t msg1_frequency_start;
- uint8_t zero_correlation_zone_config;
- uint8_t subcarrier_spacing;
- uint8_t restrictedset_config;
- uint16_t root_sequence_index;
- uint16_t rsrp_threshold_ssb;
- uint16_t rsrp_threshold_sul;
- uint16_t prach_freq_offset;
- } fapi_nr_ul_config_prach_pdu;
+/// This struct replaces:
+/// PRACH-ConfigInfo from 38.331 RRC spec
+/// PRACH-ConfigSIB or PRACH-Config
+typedef struct {
+ /// PHY cell ID
+ uint16_t phys_cell_id;
+ /// Num PRACH occasions
+ uint8_t num_prach_ocas;
+ /// PRACH format
+ uint8_t prach_format;
+ /// Num RA
+ uint8_t num_ra;
+ uint8_t prach_start_symbol;
+ /// 38.211 (NCS 38.211 6.3.3.1).
+ uint16_t num_cs;
+ /// Parameter: prach-rootSequenceIndex, see TS 38.211 (6.3.3.2).
+ uint16_t root_seq_id;
+ /// Parameter: High-speed-flag, see TS 38.211 (6.3.3.1). 1 corresponds to Restricted set and 0 to Unrestricted set.
+ uint8_t restricted_set;
+ /// see TS 38.211 (6.3.3.2).
+ uint16_t freq_msg1;
+ // nfapi_nr_ul_beamforming_t beamforming;
+} fapi_nr_ul_config_prach_pdu;
typedef struct {
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index 54b592202d..e342ab0b67 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -86,7 +86,7 @@ typedef enum {
NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION= 0X86,
NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION= 0X87,
NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION= 0X88,
- NFAPI_NR_PHY_MSG_TYPE_PACH_INDICATION= 0X89
+ NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89
//RESERVED 0X8a ~ 0xff
} nfapi_nr_phy_msg_type_e;
@@ -623,22 +623,35 @@ typedef struct {
//table 3-37
-#define DCI_PAYLOAD_BTYE_LEN 12 //? TS38.212 sec 7.3.1
+#define DCI_PAYLOAD_BYTE_LEN 8 // 12 ? TS38.212 sec 7.3.1
+#define MAX_DCI_CORESET 8
-typedef struct
-{
- uint16_t rnti;//
- uint16_t scrambling_id;//
- uint16_t scrambling_rnti;/* */
- uint8_t cce_index;//
- uint8_t aggregation_level;//
- nfapi_nr_tx_precoding_and_beamforming_t* precoding_and_beamforming_list;
- //tx power info
- uint8_t beta_pdcch_1_0;/*PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of
-SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 */
- uint8_t power_control_offset_ss;//PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB
- uint16_t payload_size_bits;//The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0-> DCI_PAYLOAD_BTYE_LEN*8
- uint8_t payload[DCI_PAYLOAD_BTYE_LEN];//DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
+typedef struct {
+ // The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535.
+ uint16_t RNTI[MAX_DCI_CORESET];
+ // For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured,
+ // otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535
+ uint16_t ScramblingId[MAX_DCI_CORESET];
+ // For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI.
+ // Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535
+ uint16_t ScramblingRNTI[MAX_DCI_CORESET];
+ // CCE start Index used to send the DCI Value: 0->135
+ uint8_t CceIndex[MAX_DCI_CORESET];
+ // Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16
+ uint8_t AggregationLevel[MAX_DCI_CORESET];
+ // Precoding and Beamforming structure See Table 3-43
+ nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET];
+ // PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI.
+ // This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1]
+ // Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps
+ uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET];
+ // PDCCH power value used for all other PDCCH Formats.
+ // This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB
+ uint8_t powerControlOffsetSS[MAX_DCI_CORESET];
+ // The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8
+ uint16_t PayloadSizeBits[MAX_DCI_CORESET];
+ // DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
+ uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN];
} nfapi_nr_dl_dci_pdu_t;
@@ -653,9 +666,6 @@ typedef struct {
uint16_t *beamIdx[275];
} nr_beamforming_t;
-#define MAX_DCI_CORESET 8
-#define DCI_PAYLOAD_BYTE_LEN 8
-
typedef struct {
///Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP,Value: 1->275
uint16_t BWPSize;
@@ -685,26 +695,8 @@ typedef struct {
uint8_t precoderGranularity;
///Number of DCIs in this CORESET.Value: 0->MaxDciPerSlot
uint16_t numDlDci;
- ///The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535.
- uint16_t RNTI[MAX_DCI_CORESET];
- ///For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured, otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535
- uint16_t ScramblingId[MAX_DCI_CORESET];
- ///For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI. Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535
- uint16_t ScramblingRNTI[MAX_DCI_CORESET];
- ///CCE start Index used to send the DCI Value: 0->135
- uint8_t CceIndex[MAX_DCI_CORESET];
- ///Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16
- uint8_t AggregationLevel[MAX_DCI_CORESET];
- ///Precoding and Beamforming structure See Table 3-43
- nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET];
- ///PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps
- uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET];
- ///PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB
- uint8_t powerControlOffsetSS[MAX_DCI_CORESET];
-///The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BTYE_LEN*8
- uint16_t PayloadSizeBits[MAX_DCI_CORESET];
- ///DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
- uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN];
+ ///DL DCI PDU
+ nfapi_nr_dl_dci_pdu_t dci_pdu;
} nfapi_nr_dl_tti_pdcch_pdu_rel15_t;
typedef struct {
@@ -1037,10 +1029,12 @@ typedef struct
{
uint16_t phys_cell_id;
uint8_t num_prach_ocas;
+ // SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
+ // We added 9 = A1/B1 10 = A2/B2 11 A3/B3
uint8_t prach_format;
uint8_t num_ra;
uint8_t prach_start_symbol;
- uint16_t num_cs;//
+ uint16_t num_cs;
nfapi_nr_ul_beamforming_t beamforming;
} nfapi_nr_prach_pdu_t;
@@ -1126,6 +1120,7 @@ typedef struct
uint16_t ul_dmrs_symb_pos;
uint8_t dmrs_config_type;
uint16_t ul_dmrs_scrambling_id;
+ uint16_t pusch_identity;
uint8_t scid;
uint8_t num_dmrs_cdm_grps_no_data;
uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used
@@ -1498,7 +1493,7 @@ typedef struct
//for dci_pusch_pdu
typedef struct
{
- uint8_t pdu_bit_map;
+ uint8_t pduBitmap;
uint32_t handle;
uint16_t rnti;
uint8_t ul_cqi;
@@ -1513,7 +1508,7 @@ typedef struct
//for PUCCH PDU Format 0/1
typedef struct
{
- uint8_t pdu_bit_map;
+ uint8_t pduBitmap;
uint32_t handle;
uint16_t rnti;
uint8_t pucch_format;//PUCCH format Value: 0 -> 1 0: PUCCH Format0 1: PUCCH Format1
@@ -1529,7 +1524,7 @@ typedef struct
//PUCCH PDU Format 2/3/4
typedef struct
{
- uint8_t pdu_bit_map;
+ uint8_t pduBitmap;
uint32_t handle;
uint16_t rnti;
uint8_t pucch_format;//PUCCH format Value: 0 -> 2 0: PUCCH Format2 1: PUCCH Format3 2: PUCCH Format4
@@ -1566,7 +1561,7 @@ typedef struct
uint16_t sfn;
uint16_t slot;
uint16_t num_ucis;
- nfapi_nr_uci_t uci_list[NFAPI_MAX_NUM_UCI_INDICATION];
+ nfapi_nr_uci_t *uci_list;
} nfapi_nr_uci_indication_t;
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c
index 156a48ec05..61c6875bc6 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c
@@ -526,7 +526,7 @@ uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len,
return 0;
}
- if((end - out) >= sizeof(uint8_t) * len)
+ if((end - (*in)) >= sizeof(uint8_t) * len)
{
memcpy(out, (*in), len);
(*in)+=len;
diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
index b3c9f3117c..72d85b1b14 100644
--- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c
+++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
@@ -27,9 +27,7 @@
#include "SIMULATION/TOOLS/sim.h"
#include "PHY/CODING/nrLDPC_extern.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
-// extern "C" {
#include "openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h"
-// }
#define MAX_NUM_DLSCH_SEGMENTS 16
#define MAX_BLOCK_LENGTH 8448
@@ -105,7 +103,7 @@ int test_ldpc(short No_iteration,
time_stats_t *time_optim,
time_stats_t *time_decoder,
n_iter_stats_t *dec_iter,
- short run_cuda)
+ short run_cuda)
{
//clock initiate
//time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder;
@@ -398,23 +396,24 @@ int test_ldpc(short No_iteration,
decParams.numMaxIter=No_iteration;
decParams.outMode = nrLDPC_outMode_BIT;
//decParams.outMode =nrLDPC_outMode_LLRINT8;
-
-
+ set_compact_BG(Zc,BG);
+ init_LLR_DMA_for_CUDA(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], block_length);
for(j=0;j 1280, 2401 -> 2560
@@ -561,7 +561,7 @@ int main(int argc, char *argv[])
block_length = atoi(optarg);
break;
- case 'G':
+ case 'G':
run_cuda = atoi(optarg);
break;
diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c
index 806d8de28c..d9adf3e24f 100644
--- a/openair1/PHY/CODING/TESTBENCH/polartest.c
+++ b/openair1/PHY/CODING/TESTBENCH/polartest.c
@@ -12,7 +12,6 @@
#include "PHY/CODING/coding_defs.h"
#include "SIMULATION/TOOLS/sim.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
-//#include "PHY/NR_TRANSPORT/nr_transport.h"
//#include "common/utils/LOG/log.h"
//#define DEBUG_DCI_POLAR_PARAMS
@@ -27,7 +26,7 @@ int main(int argc, char *argv[])
{
//Default simulation values (Aim for iterations = 1000000.)
int decoder_int16=0;
- int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
+ int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, 2=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
double SNR, SNR_lin;
int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks).
@@ -42,6 +41,7 @@ int main(int argc, char *argv[])
switch (arguments) {
case 's':
SNRstart = atof(optarg);
+ SNRstop = SNRstart + 2;
break;
case 'd':
@@ -91,7 +91,7 @@ int main(int argc, char *argv[])
case 'k':
testLength=atoi(optarg);
- if (testLength < 12 || testLength > 60) {
+ if (testLength < 12 || testLength > 127) {
printf("Illegal packet bitlength %d \n",testLength);
exit(-1);
}
@@ -120,12 +120,13 @@ int main(int argc, char *argv[])
crcTableInit();
if (polarMessageType == 0) { //PBCH
- aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
+ aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
} else if (polarMessageType == 1) { //DCI
- coderLength = 108*aggregation_level;
- } else if (polarMessageType == -1) { //UCI
- printf("UCI testing not supported yet\n");
- exit(-1);
+ coderLength = 108*aggregation_level;
+ } else if (polarMessageType == 2) { //UCI
+ //pucch2 parameters, 1 symbol, aggregation_level = NPRB
+ AssertFatal(aggregation_level>2,"For UCI formats, aggregation (N_RB) should be > 2\n");
+ coderLength = 16*aggregation_level;
}
//Logging
diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h
index 9b111309cd..7f466c7097 100644
--- a/openair1/PHY/CODING/coding_defs.h
+++ b/openair1/PHY/CODING/coding_defs.h
@@ -382,12 +382,24 @@ unsigned int crc16 (unsigned char * inptr, int bitlen);
@param bitlen length of inputs in bits*/
unsigned int crc12 (unsigned char * inptr, int bitlen);
+/*!\fn uint32_t crc12(uint8_t *inPtr, int32_t bitlen)
+\brief This computes an 11-bit crc based on 3GPP NR specifications.
+@param inPtr Pointer to input byte stream
+@param bitlen length of inputs in bits*/
+unsigned int crc11 (unsigned char * inptr, int bitlen);
+
/*!\fn uint32_t crc8(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 8-bit crc based on 3GPP UMTS specifications.
@param inPtr Pointer to input byte stream
@param bitlen length of inputs in bits*/
unsigned int crc8 (unsigned char * inptr, int bitlen);
+/*!\fn uint32_t crc8(uint8_t *inPtr, int32_t bitlen)
+\brief This computes a 6-bit crc based on 3GPP NR specifications.
+@param inPtr Pointer to input byte stream
+@param bitlen length of inputs in bits*/
+unsigned int crc6 (unsigned char * inptr, int bitlen);
+
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type);
/*!\fn void phy_viterbi_dot11_sse2(int8_t *y, uint8_t *decoded_bytes, uint16_t n,int offset,int traceback)
@@ -463,6 +475,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb_oh,
+ uint8_t tb_scaling,
uint8_t Nl);
uint32_t nr_compute_tbslbrm(uint16_t table,
diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c
index ee5c302adb..555f314429 100644
--- a/openair1/PHY/CODING/crc_byte.c
+++ b/openair1/PHY/CODING/crc_byte.c
@@ -90,7 +90,9 @@ static unsigned int crc24bTable[256];
static unsigned int crc24cTable[256];
static unsigned short crc16Table[256];
static unsigned short crc12Table[256];
+static unsigned short crc11Table[256];
static unsigned char crc8Table[256];
+static unsigned char crc6Table[256];
void crcTableInit (void)
{
@@ -102,7 +104,9 @@ void crcTableInit (void)
crc24cTable[c] = crcbit (&c, 1, poly24c);
crc16Table[c] = (unsigned short) (crcbit (&c, 1, poly16) >> 16);
crc12Table[c] = (unsigned short) (crcbit (&c, 1, poly12) >> 16);
+ crc11Table[c] = (unsigned short) (crcbit (&c, 1, poly11) >> 16);
crc8Table[c] = (unsigned char) (crcbit (&c, 1, poly8) >> 24);
+ crc6Table[c] = (unsigned char) (crcbit (&c, 1, poly6) >> 24);
} while (++c);
}
@@ -207,6 +211,24 @@ crc12 (unsigned char * inptr, int bitlen)
return crc;
}
+unsigned int
+crc11 (unsigned char * inptr, int bitlen)
+{
+ int octetlen, resbit;
+ unsigned int crc = 0;
+ octetlen = bitlen / 8; /* Change in octets */
+ resbit = (bitlen % 8);
+
+ while (octetlen-- > 0) {
+ crc = (crc << 8) ^ (crc11Table[(*inptr++) ^ (crc >> 24)] << 16);
+ }
+
+ if (resbit > 0)
+ crc = (crc << resbit) ^ (crc11Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16);
+
+ return crc;
+}
+
unsigned int
crc8 (unsigned char * inptr, int bitlen)
{
@@ -225,6 +247,24 @@ crc8 (unsigned char * inptr, int bitlen)
return crc;
}
+unsigned int
+crc6 (unsigned char * inptr, int bitlen)
+{
+ int octetlen, resbit;
+ unsigned int crc = 0;
+ octetlen = bitlen / 8; /* Change in octets */
+ resbit = (bitlen % 8);
+
+ while (octetlen-- > 0) {
+ crc = crc6Table[(*inptr++) ^ (crc >> 24)] << 24;
+ }
+
+ if (resbit > 0)
+ crc = (crc << resbit) ^ (crc8Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 24);
+
+ return crc;
+}
+
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
{
uint32_t crc=0,oldcrc=0;
@@ -284,6 +324,7 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
AssertFatal(1,"Invalid crc_type \n");
}
+
if (crc == oldcrc)
return(1);
else
diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
index 68ca2f450f..931d500338 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
+++ b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
@@ -12,8 +12,8 @@
#include
#include
#include
-#include "PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_types.h"
-#include "PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_defs.h"
+#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
+#include "PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h"
#include "bgs/BG1_I0"
#include "bgs/BG1_I1"
@@ -32,7 +32,7 @@
#include "bgs/BG2_I6"
#include "bgs/BG2_I7"
-#define MAX_ITERATION 5
+#define MAX_ITERATION 2
#define MC 1
#define cudaCheck(ans) { cudaAssert((ans), __FILE__, __LINE__); }
@@ -49,13 +49,21 @@ typedef struct{
char y;
short value;
} h_element;
+#include "bgs/BG1_compact_in_C.h"
+__device__ char dev_const_llr[68*384];
+__device__ char dev_dt [46*68*384];
+__device__ char dev_llr[68*384];
+__device__ unsigned char dev_tmp[68*384];
h_element h_compact1 [46*19] = {};
h_element h_compact2 [68*30] = {};
-__device__ __constant__ h_element dev_h_compact1[46*19]; // used in kernel 1
-__device__ __constant__ h_element dev_h_compact2[68*30]; // used in kernel 2
+__device__ h_element dev_h_compact1[46*19]; // used in kernel 1
+__device__ h_element dev_h_compact2[68*30]; // used in kernel 2
+
+// __device__ __constant__ h_element dev_h_compact1[46*19]; // used in kernel 1
+// __device__ __constant__ h_element dev_h_compact2[68*30]; // used in kernel 2
// row and col element count
__device__ __constant__ char h_ele_row_bg1_count[46] = {
@@ -92,9 +100,93 @@ __global__ void warmup()
// warm up gpu for time measurement
}
+extern "C"
+void warmup_for_GPU(){
+
+ warmup<<<20,1024 >>>();
+
+}
+
+extern "C"
+void set_compact_BG(int Zc,short BG){
+
+ int row,col;
+ if(BG == 1){
+ row = 46;
+ col = 68;
+ }
+ else{
+ row = 42;
+ col = 52;
+ }
+ int compact_row = 30;
+ int compact_col = 19;
+ if(BG==2){compact_row = 10, compact_col = 23;}
+ int memorySize_h_compact1 = row * compact_col * sizeof(h_element);
+ int memorySize_h_compact2 = compact_row * col * sizeof(h_element);
+ int lift_index = 0;
+ short lift_set[][9] = {
+ {2,4,8,16,32,64,128,256},
+ {3,6,12,24,48,96,192,384},
+ {5,10,20,40,80,160,320},
+ {7,14,28,56,112,224},
+ {9,18,36,72,144,288},
+ {11,22,44,88,176,352},
+ {13,26,52,104,208},
+ {15,30,60,120,240},
+ {0}
+ };
+
+ for(int i = 0; lift_set[i][0] != 0; i++){
+ for(int j = 0; lift_set[i][j] != 0; j++){
+ if(Zc == lift_set[i][j]){
+ lift_index = i;
+ break;
+ }
+ }
+ }
+ printf("\nZc = %d BG = %d\n",Zc,BG);
+ switch(lift_index){
+ case 0:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I0, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I0, memorySize_h_compact2) );
+ break;
+ case 1:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I1, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I1, memorySize_h_compact2) );
+ break;
+ case 2:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I2, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I2, memorySize_h_compact2) );
+ break;
+ case 3:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I3, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I3, memorySize_h_compact2) );
+ break;
+ case 4:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I4, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I4, memorySize_h_compact2) );
+ break;
+ case 5:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I5, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I5, memorySize_h_compact2) );
+ break;
+ case 6:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I6, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I6, memorySize_h_compact2) );
+ break;
+ case 7:
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, host_h_compact1_I7, memorySize_h_compact1) );
+ cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, host_h_compact2_I7, memorySize_h_compact2) );
+ break;
+ }
+
+ // return 0;
+}
+
// Kernel 1
-__global__ void ldpc_cnp_kernel_1st_iter(char * dev_llr, char * dev_dt, int BG, int row, int col, int Zc)
+__global__ void ldpc_cnp_kernel_1st_iter(/*char * dev_llr,*/ int BG, int row, int col, int Zc)
{
// if(blockIdx.x == 0 && threadIdx.x == 1) printf("cnp %d\n", threadIdx.x);
int iMCW = blockIdx.y; // codeword id
@@ -153,7 +245,7 @@ __global__ void ldpc_cnp_kernel_1st_iter(char * dev_llr, char * dev_dt, int BG,
for(int i = 0; i < s; i++){
// v0: Best performance so far. 0.75f is the value of alpha.
sq = 1 - 2 * ((Q_sign >> i) & 0x01);
- R_temp = 0.8 * sign * sq * (i != idx_min ? rmin1 : rmin2);
+ R_temp = 0.75f * sign * sq * (i != idx_min ? rmin1 : rmin2);
// write results to global memory
h_element_t = dev_h_compact1[i*row+iBlkRow];
int addr_temp = offsetR + h_element_t.y * row * Zc;
@@ -163,7 +255,7 @@ __global__ void ldpc_cnp_kernel_1st_iter(char * dev_llr, char * dev_dt, int BG,
}
// Kernel_1
-__global__ void ldpc_cnp_kernel(char * dev_llr, char * dev_dt, int BG, int row, int col, int Zc)
+__global__ void ldpc_cnp_kernel(/*char * dev_llr, char * dev_dt,*/ int BG, int row, int col, int Zc)
{
// if(blockIdx.x == 0 && threadIdx.x == 1) printf("cnp\n");
int iMCW = blockIdx.y;
@@ -223,7 +315,7 @@ __global__ void ldpc_cnp_kernel(char * dev_llr, char * dev_dt, int BG, int row,
// The 2nd recursion
for(int i = 0; i < s; i ++){
sq = 1 - 2 * ((Q_sign >> i) & 0x01);
- R_temp = 0.8 * sign * sq * (i != idx_min ? rmin1 : rmin2);
+ R_temp = 0.75f * sign * sq * (i != idx_min ? rmin1 : rmin2);
// write results to global memory
@@ -236,7 +328,7 @@ __global__ void ldpc_cnp_kernel(char * dev_llr, char * dev_dt, int BG, int row,
// Kernel 2: VNP processing
__global__ void
-ldpc_vnp_kernel_normal(char * dev_llr, char * dev_dt, char * dev_const_llr, int BG, int row, int col, int Zc)
+ldpc_vnp_kernel_normal(/*char * dev_llr, char * dev_dt, char * dev_const_llr,*/ int BG, int row, int col, int Zc)
{
int iMCW = blockIdx.y;
int iBlkCol = blockIdx.x;
@@ -276,7 +368,7 @@ ldpc_vnp_kernel_normal(char * dev_llr, char * dev_dt, char * dev_const_llr, int
}
-__global__ void pack_decoded_bit(char *dev, unsigned char *host, int col, int Zc)
+__global__ void pack_decoded_bit(/*char *dev, unsigned char *host,*/ int col, int Zc)
{
__shared__ unsigned char tmp[128];
int iMCW = blockIdx.y;
@@ -284,15 +376,15 @@ __global__ void pack_decoded_bit(char *dev, unsigned char *host, int col, int Zc
int btid = threadIdx.x;
tmp[btid] = 0;
- if(dev[tid] < 0){
+ if(dev_llr[tid] < 0){
tmp[btid] = 1 << (7-(btid&7));
}
__syncthreads();
if(threadIdx.x < 16){
- host[iMCW * col*Zc + blockIdx.x*16+threadIdx.x] = 0;
+ dev_tmp[iMCW * col*Zc + blockIdx.x*16+threadIdx.x] = 0;
for(int i = 0; i < 8; i++){
- host[iMCW * col*Zc + blockIdx.x*16+threadIdx.x] += tmp[threadIdx.x*8+i];
+ dev_tmp[iMCW * col*Zc + blockIdx.x*16+threadIdx.x] += tmp[threadIdx.x*8+i];
}
}
}
@@ -369,18 +461,11 @@ void read_BG(int BG, int *h, int row, int col)
*/
}
-
extern "C"
-int32_t nrLDPC_decoder_LYC(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length, time_stats_t *time_decoder)
-{
- // alloc mem
- //unsigned char *decision = (unsigned char*)p_out;
-
- uint16_t Zc = p_decParams->Z;
- uint8_t BG = p_decParams->BG;
- uint8_t numMaxIter = p_decParams->numMaxIter;
- e_nrLDPC_outMode outMode = p_decParams->outMode;
+void init_LLR_DMA_for_CUDA(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length){
+ uint16_t Zc = p_decParams->Z;
+ uint8_t BG = p_decParams->BG;
uint8_t row,col;
if(BG == 1){
row = 46;
@@ -390,96 +475,41 @@ int32_t nrLDPC_decoder_LYC(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8
row = 42;
col = 52;
}
- int compact_row = 30, compact_col = 19, lift_index=0;;
- if(BG==2){compact_row = 10, compact_col = 23;}
+ unsigned char *hard_decision = (unsigned char*)p_out;
+ int memorySize_llr_cuda = col * Zc * sizeof(char) * MC;
+ cudaCheck( cudaMemcpyToSymbol(dev_const_llr, p_llr, memorySize_llr_cuda) );
+ cudaCheck( cudaMemcpyToSymbol(dev_llr, p_llr, memorySize_llr_cuda) );
+ cudaDeviceSynchronize();
- short lift_set[][9] = {
- {2,4,8,16,32,64,128,256},
- {3,6,12,24,48,96,192,384},
- {5,10,20,40,80,160,320},
- {7,14,28,56,112,224},
- {9,18,36,72,144,288},
- {11,22,44,88,176,352},
- {13,26,52,104,208},
- {15,30,60,120,240},
- {0}
- };
-
- for(int i = 0; lift_set[i][0] != 0; i++){
- for(int j = 0; lift_set[i][j] != 0; j++){
- if(Zc == lift_set[i][j]){
- lift_index = i;
- break;
- }
- }
+}
+
+extern "C"
+int32_t nrLDPC_decoder_LYC(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length, time_stats_t *time_decoder)
+{
+
+
+ uint16_t Zc = p_decParams->Z;
+ uint8_t BG = p_decParams->BG;
+ uint8_t numMaxIter = p_decParams->numMaxIter;
+ e_nrLDPC_outMode outMode = p_decParams->outMode;
+ cudaError_t cudaStatus;
+ uint8_t row,col;
+ if(BG == 1){
+ row = 46;
+ col = 68;
}
-
- int *h = NULL;
- switch(lift_index){
- case 0:
- h = (BG == 1)? h_base_0:h_base_8;
- break;
- case 1:
- h = (BG == 1)? h_base_1:h_base_9;
- break;
- case 2:
- h = (BG == 1)? h_base_2:h_base_10;
- break;
- case 3:
- h = (BG == 1)? h_base_3:h_base_11;
- break;
- case 4:
- h = (BG == 1)? h_base_4:h_base_12;
- break;
- case 5:
- h = (BG == 1)? h_base_5:h_base_13;
- break;
- case 6:
- h = (BG == 1)? h_base_6:h_base_14;
- break;
- case 7:
- h = (BG == 1)? h_base_7:h_base_15;
- break;
+ else{
+ row = 42;
+ col = 52;
}
- /* pack BG in compact graph */
- read_BG(BG, h, row, col);
-
-
- int memorySize_h_compact1 = row * compact_col * sizeof(h_element);
- int memorySize_h_compact2 = compact_row * col * sizeof(h_element);
-// cpu
- int memorySize_hard_decision = col * Zc * sizeof(unsigned char) * MC;
-
-
// alloc memory
unsigned char *hard_decision = (unsigned char*)p_out;
-
// gpu
int memorySize_llr_cuda = col * Zc * sizeof(char) * MC;
- int memorySize_dt_cuda = row * Zc * col * sizeof(char) * MC;
-
-
-// alloc memory
- char *dev_llr;
- char *dev_dt;
- char *dev_const_llr;
- unsigned char *dev_tmp;
+ cudaCheck( cudaMemcpyToSymbol(dev_const_llr, p_llr, memorySize_llr_cuda) );
+ cudaCheck( cudaMemcpyToSymbol(dev_llr, p_llr, memorySize_llr_cuda) );
- cudaCheck( cudaMalloc((void **)&dev_tmp, memorySize_hard_decision) );
- cudaCheck( cudaMalloc((void **)&dev_llr, memorySize_llr_cuda) );
- cudaCheck( cudaMalloc((void **)&dev_const_llr, memorySize_llr_cuda) );
- cudaCheck( cudaMalloc((void **)&dev_dt, memorySize_dt_cuda) );
-
-// memcpy host to device
-
- cudaCheck( cudaMemcpyToSymbol(dev_h_compact1, h_compact1, memorySize_h_compact1) );
- cudaCheck( cudaMemcpyToSymbol(dev_h_compact2, h_compact2, memorySize_h_compact2) );
- cudaCheck( cudaMemcpy((void*)dev_const_llr, p_llr, memorySize_llr_cuda, cudaMemcpyHostToDevice) );
-start_meas(time_decoder);
- cudaCheck( cudaMemcpy((void*)dev_llr, p_llr, memorySize_llr_cuda, cudaMemcpyHostToDevice) );
-
-
// Define CUDA kernel dimension
int blockSizeX = Zc;
dim3 dimGridKernel1(row, MC, 1); // dim of the thread blocks
@@ -488,61 +518,35 @@ start_meas(time_decoder);
dim3 dimGridKernel2(col, MC, 1);
dim3 dimBlockKernel2(blockSizeX, 1, 1);
cudaDeviceSynchronize();
-
- cudaEvent_t start, end;
- float time;
- warmup<<>>();
- warmup<<>>();
-
-
- cudaEventCreate(&start);
- cudaEventCreate(&end);
- cudaEventRecord(start, 0);
-
-// cudaProfilerStart();
-
// lauch kernel
+
for(int ii = 0; ii < MAX_ITERATION; ii++){
// first kernel
if(ii == 0){
ldpc_cnp_kernel_1st_iter
<<>>
- (dev_llr, dev_dt, BG, row, col, Zc);
+ (/*dev_llr,*/ BG, row, col, Zc);
}else{
ldpc_cnp_kernel
<<>>
- (dev_llr, dev_dt, BG, row, col, Zc);
+ (/*dev_llr,*/ BG, row, col, Zc);
}
-
// second kernel
-
- ldpc_vnp_kernel_normal
- <<>>
- (dev_llr, dev_dt, dev_const_llr, BG, row, col, Zc);
-
+ ldpc_vnp_kernel_normal
+ <<>>
+ // (dev_llr, dev_const_llr,BG, row, col, Zc);
+ (BG, row, col, Zc);
}
+
int pack = (block_length/128)+1;
dim3 pack_block(pack, MC, 1);
- pack_decoded_bit<<>>(dev_llr, dev_tmp, col, Zc);
-
-
- cudaEventRecord(end, 0);
- cudaEventSynchronize(end);
- cudaEventElapsedTime(&time, start, end);
+ pack_decoded_bit<<>>(/*dev_llr,*/ /*dev_tmp,*/ col, Zc);
-
- //cudaCheck( cudaMemcpy((*)hard_decision, (const void*)dev_tmp, memorySize_hard_decision, cudaMemcpyDeviceToHost) );
- cudaCheck( cudaMemcpy((void*)hard_decision, (const void*)dev_tmp, (block_length/8)*sizeof(unsigned char), cudaMemcpyDeviceToHost) );
+ cudaCheck( cudaMemcpyFromSymbol((void*)hard_decision, (const void*)dev_tmp, (block_length/8)*sizeof(unsigned char)) );
cudaDeviceSynchronize();
-stop_meas(time_decoder);
- cudaCheck( cudaFree(dev_llr) );
- cudaCheck( cudaFree(dev_dt) );
- cudaCheck( cudaFree(dev_const_llr) );
- cudaCheck( cudaFree(dev_tmp) );
-
- //free(hard_decision);
+
return MAX_ITERATION;
}
diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h
index e74f42b3d3..c8868f0a85 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h
@@ -1,8 +1,6 @@
#ifndef __NR_LDPC_DECODER_LYC__H__
#define __NR_LDPC_DECODER_LYC__H__
-#include "nrLDPC_types.h"
-#include "nrLDPC_init_mem.h"
/*! \file PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h
* \brief LDPC cuda support BG1 all length
@@ -25,4 +23,10 @@
int32_t nrLDPC_decoder_LYC(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length, time_stats_t *time_decoder);
+void init_LLR_DMA_for_CUDA(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length);
+
+void warmup_for_GPU(void);
+
+void set_compact_BG(int Zc, short BG);
+
#endif
diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_defs.h
deleted file mode 100644
index 9c64c262b9..0000000000
--- a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_defs.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- * contact@openairinterface.org
- */
-
- /*! \file PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_defs.h
- * \brief LDPC cuda support BG1 all length
- * \author NCTU OpinConnect Terng-Yin Hsu,WEI-YING,LIN
- * \email tyhsu@cs.nctu.edu.tw
- * \date 13-05-2020
- * \version
- * \note
- * \warning
- */
-
-
-/*!\file nrLDPC_defs.h
- * \brief Defines all constants and buffers for the LDPC decoder
- * \author Sebastian Wagner (TCL Communications) Email:
- * \date 27-03-2018
- * \version 1.0
- * \note
- * \warning
-* */
-
-#ifndef __NR_LDPC_DEFS__H__
-#define __NR_LDPC_DEFS__H__
-
-// ==============================================================================
-// DEFINES
-
-/** Maximum lifting size */
-#define NR_LDPC_ZMAX 384
-
-/** Number of columns in BG1 */
-#define NR_LDPC_NCOL_BG1 68
-/** Number of rows in BG1 */
-#define NR_LDPC_NROW_BG1 46
-/** Number of edges/entries in BG1 */
-#define NR_LDPC_NUM_EDGE_BG1 316
-/** Number of check node (CN) groups in BG1
- A CN group is defined by its number of connected bit nodes. */
-#define NR_LDPC_NUM_CN_GROUPS_BG1 9
-/** First column in BG1 that is connected to only a single CN */
-#define NR_LDPC_START_COL_PARITY_BG1 26
-
-/** Number of columns in BG1 for rate 1/3 = 22/(68-2) */
-#define NR_LDPC_NCOL_BG1_R13 NR_LDPC_NCOL_BG1
-/** Number of columns in BG1 for rate 2/3 = 22/(35-2) */
-#define NR_LDPC_NCOL_BG1_R23 35
-/** Number of columns in BG1 for rate 8/9 ~ 22/(27-2) */
-#define NR_LDPC_NCOL_BG1_R89 27
-
-/** Number of bit node (BN) groups in BG1 for rate 1/3
- A BN group is defined by its number of connected CNs. */
-#define NR_LDPC_NUM_BN_GROUPS_BG1_R13 30
-/** Number of bit node (BN) groups in BG1 for rate 2/3 */
-#define NR_LDPC_NUM_BN_GROUPS_BG1_R23 8
-/** Number of bit node (BN) groups in BG1 for rate 8/9 */
-#define NR_LDPC_NUM_BN_GROUPS_BG1_R89 5
-
-/** Number of columns in BG2 */
-#define NR_LDPC_NCOL_BG2 52
-/** Number of rows in BG2 */
-#define NR_LDPC_NROW_BG2 42
-/** Number of edges/entries in BG2 */
-#define NR_LDPC_NUM_EDGE_BG2 197
-/** Number of check node (CN) groups in BG2
- A CN group is defined by its number of connected bit nodes. */
-#define NR_LDPC_NUM_CN_GROUPS_BG2 6
-/** First column in BG2 that is connected to only a single CN */
-#define NR_LDPC_START_COL_PARITY_BG2 14
-
-/** Number of columns in BG2 for rate 1/5 = 10/(52-2) */
-#define NR_LDPC_NCOL_BG2_R15 NR_LDPC_NCOL_BG2
-/** Number of columns in BG2 for rate 1/3 = 10/(32-2) */
-#define NR_LDPC_NCOL_BG2_R13 32
-/** Number of columns in BG2 for rate 2/3 = 10/(17-2) */
-#define NR_LDPC_NCOL_BG2_R23 17
-
-/** Number of bit node (BN) groups in BG2 for rate 1/5
- A BN group is defined by its number of connected CNs. */
-#define NR_LDPC_NUM_BN_GROUPS_BG2_R15 23
-/** Number of bit node (BN) groups in BG2 for rate 1/3 */
-#define NR_LDPC_NUM_BN_GROUPS_BG2_R13 10
-/** Number of bit node (BN) groups in BG2 for rate 2/3 */
-#define NR_LDPC_NUM_BN_GROUPS_BG2_R23 6
-
-/** Worst case size of the CN processing buffer */
-#define NR_LDPC_SIZE_CN_PROC_BUF NR_LDPC_NUM_EDGE_BG1*NR_LDPC_ZMAX
-/** Worst case size of the BN processing buffer */
-#define NR_LDPC_SIZE_BN_PROC_BUF NR_LDPC_NUM_EDGE_BG1*NR_LDPC_ZMAX
-
-/** Maximum number of possible input LLR = NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX */
-#define NR_LDPC_MAX_NUM_LLR 26112
-
-// ==============================================================================
-// GLOBAL CONSTANT VARIABLES
-
-/** Start addresses for the cnProcBuf for each CN group in BG1*/
-static const uint32_t lut_startAddrCnGroups_BG1[NR_LDPC_NUM_CN_GROUPS_BG1] = {0, 1152, 8832, 43392, 61824, 75264, 81408, 88320, 92160};
-/** Start addresses for the cnProcBuf for each CN group in BG2*/
-static const uint32_t lut_startAddrCnGroups_BG2[NR_LDPC_NUM_CN_GROUPS_BG2] = {0, 6912, 37632, 54912, 61824, 67968};
-
-/** Number of BNs of CN group for BG1.
- E.g. 10 means that there is a CN group where every CN is connected to 10 BNs */
-static const uint8_t lut_numBnInCnGroups_BG1_R13[NR_LDPC_NUM_CN_GROUPS_BG1] = {3, 4, 5, 6, 7, 8, 9, 10, 19};
-/** Number of rows/CNs in every CN group for rate = 1/3 BG1, e.g. 5 rows of CNs connected to 4 BNs */
-static const uint8_t lut_numCnInCnGroups_BG1_R13[NR_LDPC_NUM_CN_GROUPS_BG1] = {1, 5, 18, 8, 5, 2, 2, 1, 4};
-/** Number of rows/CNs in every CN group for rate = 2/3 BG1, e.g. 3 rows of CNs connected to 7 BNs */
-static const uint8_t lut_numCnInCnGroups_BG1_R23[NR_LDPC_NUM_CN_GROUPS_BG1] = {1, 0, 0, 0, 3, 2, 2, 1, 4};
-/** Number of rows/CNs in every CN group for rate = 8/9 BG1, e.g. 4 rows of CNs connected to 19 BNs */
-static const uint8_t lut_numCnInCnGroups_BG1_R89[NR_LDPC_NUM_CN_GROUPS_BG1] = {1, 0, 0, 0, 0, 0, 0, 0, 4};
-
-/** Number of connected BNs for every column in BG1 rate = 1/3, e.g. in first column all BNs are connected to 30 CNs */
-static const uint8_t lut_numEdgesPerBn_BG1_R13[NR_LDPC_START_COL_PARITY_BG1] = {30, 28, 7, 11, 9, 4, 8, 12, 8, 7, 12, 10, 12, 11, 10, 7, 10, 10, 13, 7, 8, 11, 12, 5, 6, 6};
-/** Number of connected BNs for every column in BG1 rate = 2/3, e.g. in first column all BNs are connected to 12 CNs */
-static const uint8_t lut_numEdgesPerBn_BG1_R23[NR_LDPC_START_COL_PARITY_BG1] = {12, 11, 4, 5, 5, 3, 4, 5, 5, 3, 6, 6, 6, 6, 5, 3, 6, 5, 6, 4, 5, 6, 6, 3, 3, 2};
-/** Number of connected BNs for every column in BG1 rate = 8/9, e.g. in first column all BNs are connected to 5 CNs */
-static const uint8_t lut_numEdgesPerBn_BG1_R89[NR_LDPC_START_COL_PARITY_BG1] = {5, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2};
-
-/** Number of BNs of CN group for BG2.
- E.g. 3 means that there is a CN group where every CN is connected to 3 BNs */
-static const uint8_t lut_numBnInCnGroups_BG2_R15[NR_LDPC_NUM_CN_GROUPS_BG2] = {3, 4, 5, 6, 8, 10};
-/** Number of rows/CNs in every CN group for rate = 1/5 BG2, e.g. 6 rows of CNs connected to 3 BNs */
-static const uint8_t lut_numCnInCnGroups_BG2_R15[NR_LDPC_NUM_CN_GROUPS_BG2] = {6, 20, 9, 3, 2, 2};
-/** Number of rows/CNs in every CN group for rate = 1/3 BG2, e.g. 8 rows of CNs connected to 4 BNs */
-static const uint8_t lut_numCnInCnGroups_BG2_R13[NR_LDPC_NUM_CN_GROUPS_BG2] = {0, 8, 7, 3, 2, 2};
-/** Number of rows/CNs in every CN group for rate = 2/3 BG2, e.g. 1 row of CNs connected to 4 BNs */
-static const uint8_t lut_numCnInCnGroups_BG2_R23[NR_LDPC_NUM_CN_GROUPS_BG2] = {0, 1, 0, 2, 2, 2};
-
-/** Number of connected BNs for every column in BG2 rate = 1/5, e.g. in first column all BNs are connected to 22 CNs */
-static const uint8_t lut_numEdgesPerBn_BG2_R15[NR_LDPC_START_COL_PARITY_BG2] = {22, 23, 10, 5, 5, 14, 7, 13, 6, 8, 9, 16, 9, 12};
-/** Number of connected BNs for every column in BG2 rate = 1/3, e.g. in first column all BNs are connected to 14 CNs */
-static const uint8_t lut_numEdgesPerBn_BG2_R13[NR_LDPC_START_COL_PARITY_BG2] = {14, 16, 2, 4, 4, 6, 6, 8, 6, 6, 6, 13, 5, 7};
-/** Number of connected BNs for every column in BG2 rate = 2/3, e.g. in first column all BNs are connected to 6 CNs */
-static const uint8_t lut_numEdgesPerBn_BG2_R23[NR_LDPC_START_COL_PARITY_BG2] = { 6, 5, 2, 3, 3, 4, 3, 4, 3, 4, 3, 5, 2, 2};
-
-// Number of groups for bit node processing
-/** Number of connected CNs for every column/BN in BG1 for rate = 1/3, Worst case is BG1 with up to 30 CNs connected to one BN
- E.g. 42 parity BNs connected to single CN */
- // BG1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
-static const uint8_t lut_numBnInBnGroups_BG1_R13[NR_LDPC_NUM_BN_GROUPS_BG1_R13] = {42, 0, 0, 1, 1, 2, 4, 3, 1, 4, 3, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1};
-/** Number of connected CNs for every column/BN in BG1 for rate = 2/3 */
-static const uint8_t lut_numBnInBnGroups_BG1_R23[NR_LDPC_NUM_BN_GROUPS_BG1_R13] = { 9, 1, 5, 3, 7, 8, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-/** Number of connected CNs for every column/BN in BG1 for rate = 8/9 */
-static const uint8_t lut_numBnInBnGroups_BG1_R89[NR_LDPC_NUM_BN_GROUPS_BG1_R13] = { 1, 3,21, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-/** Number of connected CNs for every column/BN in BG2 for rate = 1/5, Worst case is BG1 with up to 30 CNs connected to one BN
- E.g. 38 parity BNs connected to single CN */
- // BG2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
-static const uint8_t lut_numBnInBnGroups_BG2_R15[NR_LDPC_NUM_BN_GROUPS_BG1_R13] = {38, 0, 0, 0, 2, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0};
-/** Number of connected CNs for every column/BN in BG2 for rate = 1/3 */
-static const uint8_t lut_numBnInBnGroups_BG2_R13[NR_LDPC_NUM_BN_GROUPS_BG1_R13] = {18, 1, 0, 2, 1, 5, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-/** Number of connected CNs for every column/BN in BG2 for rate = 2/3 */
-static const uint8_t lut_numBnInBnGroups_BG2_R23[NR_LDPC_NUM_BN_GROUPS_BG1_R13] = { 3, 3, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-// Start addresses for the bnProcBuf for each BN group
-// BG1
-/** Start address for every BN group within the BN processing buffer for BG1 rate = 1/3 */
-static const uint32_t lut_startAddrBnGroups_BG1_R13[NR_LDPC_NUM_BN_GROUPS_BG1_R13] = {0, 16128, 17664, 19584, 24192, 34944, 44160, 47616, 62976, 75648, 94080, 99072, 109824};
-/** Start address for every BN group within the BN processing buffer for BG1 rate = 2/3 */
-static const uint32_t lut_startAddrBnGroups_BG1_R23[NR_LDPC_NUM_BN_GROUPS_BG1_R23] = {0, 3456, 4224, 9984, 14592, 28032, 46464, 50688};
-/** Start address for every BN group within the BN processing buffer for BG1 rate = 8/9 */
-static const uint32_t lut_startAddrBnGroups_BG1_R89[NR_LDPC_NUM_BN_GROUPS_BG1_R89] = {0, 384, 2688, 26880, 28416};
-
-/** Start address for every BN group within the LLR processing buffer for BG1 rate = 1/3 */
-static const uint16_t lut_startAddrBnGroupsLlr_BG1_R13[NR_LDPC_NUM_BN_GROUPS_BG1_R13] = {0, 16128, 16512, 16896, 17664, 19200, 20352, 20736, 22272, 23424, 24960, 25344, 25728};
-/** Start address for every BN group within the LLR processing buffer for BG1 rate = 2/3 */
-static const uint16_t lut_startAddrBnGroupsLlr_BG1_R23[NR_LDPC_NUM_BN_GROUPS_BG1_R23] = {0, 3456, 3840, 5760, 6912, 9600, 12672, 13056};
-/** Start address for every BN group within the LLR processing buffer for BG1 rate = 8/9 */
-static const uint16_t lut_startAddrBnGroupsLlr_BG1_R89[NR_LDPC_NUM_BN_GROUPS_BG1_R89] = {0, 384, 1536, 9600, 9984};
-
-// BG2
-/** Start address for every BN group within the BN processing buffer for BG2 rate = 1/5 */
-static const uint32_t lut_startAddrBnGroups_BG2_R15[NR_LDPC_NUM_BN_GROUPS_BG2_R15] = {0, 14592, 18432, 20736, 23424, 26496, 33408, 37248, 41856, 46848, 52224, 58368, 66816};
-/** Start address for every BN group within the BN processing buffer for BG2 rate = 1/3 */
-static const uint32_t lut_startAddrBnGroups_BG2_R13[NR_LDPC_NUM_BN_GROUPS_BG2_R13] = {0, 6912, 7680, 10752, 12672, 24192, 26880, 29952, 34944, 40320};
-/** Start address for every BN group within the BN processing buffer for BG2 rate = 2/3 */
-static const uint32_t lut_startAddrBnGroups_BG2_R23[NR_LDPC_NUM_BN_GROUPS_BG2_R23] = {0, 1152, 3456, 9216, 13824, 17664};
-
-/** Start address for every BN group within the LLR processing buffer for BG2 rate = 1/5 */
-static const uint16_t lut_startAddrBnGroupsLlr_BG2_R15[NR_LDPC_NUM_BN_GROUPS_BG2_R15] = {0, 14592, 15360, 15744, 16128, 16512, 17280, 17664, 18048, 18432, 18816, 19200, 19584};
-/** Start address for every BN group within the LLR processing buffer for BG2 rate = 1/3 */
-static const uint16_t lut_startAddrBnGroupsLlr_BG2_R13[NR_LDPC_NUM_BN_GROUPS_BG2_R13] = {0, 6912, 7296, 8064, 8448, 10368, 10752, 11136, 11520, 11904};
-/** Start address for every BN group within the LLR processing buffer for BG2 rate = 2/3 */
-static const uint16_t lut_startAddrBnGroupsLlr_BG2_R23[NR_LDPC_NUM_BN_GROUPS_BG2_R23] = {0, 1152, 2304, 4224, 5376, 6144};
-
-/** Vector of 32 '1' in int8 for application with AVX2 */
-static const int8_t ones256_epi8[32] __attribute__ ((aligned(32))) = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
-/** Vector of 32 '0' in int8 for application with AVX2 */
-static const int8_t zeros256_epi8[32] __attribute__ ((aligned(32))) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-/** Vector of 32 '127' in int8 for application with AVX2 */
-static const int8_t maxLLR256_epi8[32] __attribute__ ((aligned(32))) = {127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127};
-
-#endif
diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_init_mem.h b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_init_mem.h
deleted file mode 100644
index bdaa118e1f..0000000000
--- a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_init_mem.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- * contact@openairinterface.org
- */
-
-/*!\file nrLDPC_init_mem.h
- * \brief Defines the function to initialize the LDPC decoder and sets correct LUTs.
- * \author Sebastian Wagner (TCL Communications) Email:
- * \date 07-12-2018
- * \version 1.0
- * \note
- * \warning
- */
-
-#ifndef __NR_LDPC_INIT_MEM__H__
-#define __NR_LDPC_INIT_MEM__H__
-
-#include
-#include "nrLDPC_defs.h"
-#include "nrLDPC_types.h"
-
-#ifndef malloc32_clear
-/**
- \brief Allocates 32 byte aligned memory and initializes to zero
- \param size Input size in bytes
- \return Pointer to memory
-*/
-static inline void* malloc32_clear(size_t size)
-{
- void* ptr = (void*) memalign(32, size+32);
- memset(ptr, 0, size);
- return ptr;
-}
-#endif
-
-/**
- \brief Allocates and initializes the internal decoder processing buffers
- \param p_decParams Pointer to decoder parameters
- \param p_lut Pointer to decoder LUTs
- \return Number of LLR values
-*/
-static inline t_nrLDPC_procBuf* nrLDPC_init_mem(void)
-{
- t_nrLDPC_procBuf* p_procBuf = (t_nrLDPC_procBuf*) malloc32_clear(sizeof(t_nrLDPC_procBuf));
-
- if (p_procBuf)
- {
- p_procBuf->cnProcBuf = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t));
- p_procBuf->cnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t));
- p_procBuf->bnProcBuf = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t));
- p_procBuf->bnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t));
- p_procBuf->llrRes = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR *sizeof(int8_t));
- p_procBuf->llrProcBuf = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR *sizeof(int8_t));
- }
-
- return(p_procBuf);
-}
-
-static inline void nrLDPC_free_mem(t_nrLDPC_procBuf* p_procBuf)
-{
- free(p_procBuf->cnProcBuf);
- free(p_procBuf->cnProcBufRes);
- free(p_procBuf->bnProcBuf);
- free(p_procBuf->bnProcBufRes);
- free(p_procBuf->llrRes);
- free(p_procBuf->llrProcBuf);
-
- free(p_procBuf);
-}
-#endif
diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_types.h
deleted file mode 100644
index 34322a7780..0000000000
--- a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_types.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- * contact@openairinterface.org
- */
-
-/*!\file nrLDPC_types.h
- * \brief Defines all types for the LDPC decoder
- * \author Sebastian Wagner (TCL Communications) Email:
- * \date 27-03-2018
- * \version 1.0
- * \note
- * \warning
- */
-
-#ifndef __NR_LDPC_TYPES__H__
-#define __NR_LDPC_TYPES__H__
-
-#include "PHY/TOOLS/time_meas.h"
-#include "nrLDPC_defs.h"
-
-// ==============================================================================
-// TYPES
-
-/**
- Structure containing the pointers to the LUTs.
- */
-typedef struct nrLDPC_lut {
- const uint32_t* startAddrCnGroups; /**< Start addresses for CN groups in CN processing buffer */
- const uint8_t* numCnInCnGroups; /**< Number of CNs in every CN group */
- const uint8_t* numBnInBnGroups; /**< Number of CNs in every BN group */
- const uint32_t* startAddrBnGroups; /**< Start addresses for BN groups in BN processing buffer */
- const uint16_t* startAddrBnGroupsLlr; /**< Start addresses for BN groups in LLR processing buffer */
- const uint16_t** circShift[NR_LDPC_NUM_CN_GROUPS_BG1]; /**< LUT for circular shift values for all CN groups and Zs */
- const uint32_t** startAddrBnProcBuf[NR_LDPC_NUM_CN_GROUPS_BG1]; /**< LUT of start addresses of CN groups in BN proc buffer */
- const uint8_t** bnPosBnProcBuf[NR_LDPC_NUM_CN_GROUPS_BG1]; /**< LUT of BN positions in BG for CN groups */
- const uint16_t* llr2llrProcBufAddr; /**< LUT for transferring input LLRs to LLR processing buffer */
- const uint8_t* llr2llrProcBufBnPos; /**< LUT BN position in BG */
- const uint8_t** posBnInCnProcBuf[NR_LDPC_NUM_CN_GROUPS_BG1]; /**< LUT for llr2cnProcBuf */
-} t_nrLDPC_lut;
-
-/**
- Enum with possible LDPC output formats.
- */
-typedef enum nrLDPC_outMode {
- nrLDPC_outMode_BIT, /**< 32 bits per uint32_t output */
- nrLDPC_outMode_BITINT8, /**< 1 bit per int8_t output */
- nrLDPC_outMode_LLRINT8 /**< Single LLR value per int8_t output */
-} e_nrLDPC_outMode;
-
-/**
- Structure containing LDPC decoder parameters.
- */
-typedef struct nrLDPC_dec_params {
- uint8_t BG; /**< Base graph */
- uint16_t Z; /**< Lifting size */
- uint8_t R; /**< Decoding rate: Format 15,13,... for code rates 1/5, 1/3,... */
- uint8_t numMaxIter; /**< Maximum number of iterations */
- e_nrLDPC_outMode outMode; /**< Output format */
-} t_nrLDPC_dec_params;
-
-/**
- Structure containing LDPC decoder processing time statistics.
- */
-typedef struct nrLDPC_time_stats {
- time_stats_t llr2llrProcBuf; /**< Statistics for function llr2llrProcBuf */
- time_stats_t llr2CnProcBuf; /**< Statistics for function llr2CnProcBuf */
- time_stats_t cnProc; /**< Statistics for function cnProc */
- time_stats_t cnProcPc; /**< Statistics for function cnProcPc */
- time_stats_t bnProcPc; /**< Statistics for function bnProcPc */
- time_stats_t bnProc; /**< Statistics for function bnProc */
- time_stats_t cn2bnProcBuf; /**< Statistics for function cn2bnProcBuf */
- time_stats_t bn2cnProcBuf; /**< Statistics for function bn2cnProcBuf */
- time_stats_t llrRes2llrOut; /**< Statistics for function llrRes2llrOut */
- time_stats_t llr2bit; /**< Statistics for function llr2bit */
- time_stats_t total; /**< Statistics for total processing time */
-} t_nrLDPC_time_stats;
-
-/**
- Structure containing the processing buffers
- */
-typedef struct nrLDPC_procBuf {
- int8_t* cnProcBuf; /**< CN processing buffer */
- int8_t* cnProcBufRes; /**< Buffer for CN processing results */
- int8_t* bnProcBuf; /**< BN processing buffer */
- int8_t* bnProcBufRes; /**< Buffer for BN processing results */
- int8_t* llrRes; /**< Buffer for LLR results */
- int8_t* llrProcBuf; /**< LLR processing buffer */
-} t_nrLDPC_procBuf;
-
-#endif
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
index 53119a1c2b..18db8a01fb 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
@@ -569,7 +569,7 @@ int8_t polar_decoder_dci(double *input,
}
void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
- AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
+ AssertFatal(polarParams->K > 17, "K = %d < 18, is not allowed\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
int bit_i,ip,ipmod64;
int numbytes = polarParams->K>>3;
@@ -670,7 +670,9 @@ uint32_t polar_decoder_int16(int16_t *input,
A32_flip[1+offset]=((uint8_t *)&Aprime)[2];
A32_flip[2+offset]=((uint8_t *)&Aprime)[1];
A32_flip[3+offset]=((uint8_t *)&Aprime)[0];
- crc = (uint64_t)(crc24c(A32_flip,8*offset+len)>>8);
+ if (crclen == 24) crc = (uint64_t)((crc24c(A32_flip,8*offset+len)>>8)&0xffffff);
+ else if (crclen == 11) crc = (uint64_t)((crc11(A32_flip,8*offset+len)>>21)&0x7ff);
+ else if (crclen == 6) crc = (uint64_t)((crc6(A32_flip,8*offset+len)>>26)&0x3f);
} else if (len<=64) {
Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));;
uint8_t A64_flip[8+offset];
@@ -688,7 +690,9 @@ uint32_t polar_decoder_int16(int16_t *input,
A64_flip[5+offset]=((uint8_t *)&Aprime)[2];
A64_flip[6+offset]=((uint8_t *)&Aprime)[1];
A64_flip[7+offset]=((uint8_t *)&Aprime)[0];
- crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8);
+ if (crclen==24) crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8)&0xffffff;
+ else if (crclen==11) crc = (uint64_t)(crc11(A64_flip,8*offset+len)>>21)&0x7ff;
+ else if (crclen==6) crc = (uint64_t)(crc6(A64_flip,8*offset+len)>>26)&0x3f;
}
#if 0
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
index daa2346098..42d500ae86 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
@@ -197,8 +197,10 @@ decoder_node_t *add_nodes(int level, int first_leaf_index, t_nrPolar_params *pol
}
for (int i=0;iinformation_bit_pattern[i+first_leaf_index]>0)
- all_frozen_below=0;
+ if (polarParams->information_bit_pattern[i+first_leaf_index]>0) {
+ all_frozen_below=0;
+ break;
+ }
}
if (all_frozen_below==0)
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
index 6e01a05d0f..a44a08a701 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
@@ -146,7 +146,7 @@ void polar_encoder_dci(uint32_t *in,
uint16_t n_RNTI);
void polar_encoder_fast(uint64_t *A,
- uint32_t *out,
+ void *out,
int32_t crcmask,
uint8_t ones_flag,
t_nrPolar_params *polarParams);
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
index 8e4b45f744..27c062c217 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
@@ -295,8 +295,8 @@ static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,vo
void build_polar_tables(t_nrPolar_params *polarParams) {
// build table b -> c'
- AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
- AssertFatal(polarParams->K < 129, "K = %d > 64, is not supported yet\n",polarParams->K);
+ AssertFatal(polarParams->K > 17, "K = %d < 18, is not possible\n",polarParams->K);
+ AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
int bit_i,ip;
int numbytes = polarParams->K>>3;
int residue = polarParams->K&7;
@@ -327,7 +327,7 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
AssertFatal(polarParams->N==512 || polarParams->N==256 || polarParams->N==128,"N = %d, not done yet\n",polarParams->N);
// build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to 64 bit packed vectors.
// keep only rows of G which correspond to information/crc bits
- polarParams->G_N_tab = (uint64_t **)malloc(polarParams->K * sizeof(int64_t *));
+ polarParams->G_N_tab = (uint64_t **)malloc((polarParams->K + polarParams->n_pc) * sizeof(int64_t *));
int k=0;
for (int i=0; iN; i++) {
@@ -408,18 +408,18 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
}
void polar_encoder_fast(uint64_t *A,
- uint32_t *out,
+ void *out,
int32_t crcmask,
uint8_t ones_flag,
t_nrPolar_params *polarParams) {
- AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
+ // AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits);
uint64_t B[4]= {0,0,0,0},Cprime[4]= {0,0,0,0};
int bitlen = polarParams->payloadBits;
// append crc
AssertFatal(bitlen<129,"support for payloads <= 128 bits\n");
- AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
+ // AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
//int bitlen0=bitlen;
uint64_t tcrc=0;
uint8_t offset = 0;
@@ -444,7 +444,9 @@ void polar_encoder_fast(uint64_t *A,
A32_flip[1+offset]=((uint8_t *)&Aprime)[2];
A32_flip[2+offset]=((uint8_t *)&Aprime)[1];
A32_flip[3+offset]=((uint8_t *)&Aprime)[0];
- tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8)));
+ if (polarParams->crcParityBits == 24) tcrc = (uint64_t)(((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8)))&0xffffff);
+ else if (polarParams->crcParityBits == 11) tcrc = (uint64_t)(((crcmask^(crc11(A32_flip,bitlen)>>21)))&0x7ff);
+ else if (polarParams->crcParityBits == 6) tcrc = (uint64_t)(((crcmask^(crc6(A32_flip,bitlen)>>26)))&0x3f);
} else if (bitlen<=64) {
uint8_t A64_flip[8+offset];
if (ones_flag) {
@@ -461,7 +463,8 @@ void polar_encoder_fast(uint64_t *A,
A64_flip[5+offset]=((uint8_t *)&Aprime)[2];
A64_flip[6+offset]=((uint8_t *)&Aprime)[1];
A64_flip[7+offset]=((uint8_t *)&Aprime)[0];
- tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8)));
+ if (polarParams->crcParityBits == 24) tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8)))&0xffffff;
+ else if (polarParams->crcParityBits == 11) tcrc = (uint64_t)((crcmask^(crc11(A64_flip,bitlen)>>21)))&0x7ff;
}
else if (bitlen<=128) {
uint8_t A128_flip[16+offset];
@@ -479,7 +482,8 @@ void polar_encoder_fast(uint64_t *A,
A128_flip[10+offset]=((uint8_t*)&Aprime)[5]; A128_flip[11+offset]=((uint8_t*)&Aprime)[4];
A128_flip[12+offset]=((uint8_t*)&Aprime)[3]; A128_flip[13+offset]=((uint8_t*)&Aprime)[2];
A128_flip[14+offset]=((uint8_t*)&Aprime)[1]; A128_flip[15+offset]=((uint8_t*)&Aprime)[0];
- tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8)));
+ if (polarParams->crcParityBits == 24) tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8)))&0xffffff;
+ else if (polarParams->crcParityBits == 11) tcrc = (uint64_t)((crcmask^(crc11(A128_flip,bitlen)>>21)))&0x7ff;
}
int n;
@@ -522,6 +526,7 @@ void polar_encoder_fast(uint64_t *A,
#ifdef DEBUG_POLAR_ENCODER
+ printf("Polar encoder: (N,K) : (%d,%d)\n",polarParams->N,polarParams->K);
if (polarParams->K<65)
printf("A %llx B %llx Cprime %llx (payload bits %d,crc %x)\n",
(unsigned long long)(A[0]&(((uint64_t)1<>8);
}
-#endif
+ #endif
/* printf("Bbytes : %x.%x.%x.%x.%x.%x.%x.%x\n",Bbyte[0],Bbyte[1],Bbyte[2],Bbyte[3],Bbyte[4],Bbyte[5],Bbyte[6],Bbyte[7]);
printf("%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",polarParams->cprime_tab[0][Bbyte[0]] ,
polarParams->cprime_tab[1][Bbyte[1]] ,
@@ -671,5 +676,5 @@ void polar_encoder_fast(uint64_t *A,
}
}
memset((void*)out,0,polarParams->encoderLength>>3);
- polar_rate_matching(polarParams,(void *)D,(void *)out);
+ polar_rate_matching(polarParams,(void *)D, out);
}
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h
index 42051eb1b5..1ab664e5a2 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h
@@ -33,8 +33,8 @@
#ifndef __NR_POLAR_UCI_DEFS__H__
#define __NR_POLAR_UCI_DEFS__H__
-#define NR_POLAR_UCI_MESSAGE_TYPE -1 //int8_t
-#define NR_POLAR_UCI_CRC_ERROR_CORRECTION_BITS 3
+#define NR_POLAR_UCI_PUCCH_MESSAGE_TYPE 2 //int8_t
+#define NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS 3
#define NR_POLAR_PUCCH_PAYLOAD_BITS 32
#define NR_POLAR_PUCCH_E 32
diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c
index f6a06b3f7f..f6a700117d 100644
--- a/openair1/PHY/CODING/nr_polar_init.c
+++ b/openair1/PHY/CODING/nr_polar_init.c
@@ -43,11 +43,12 @@ static void nr_polar_init(t_nrPolar_params * *polarParams,
uint8_t aggregation_level,
int decoder_flag) {
t_nrPolar_params *currentPtr = *polarParams;
- uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level);
+ uint16_t aggregation_prime = (messageType >= 2) ? aggregation_level : nr_polar_aggregation_prime(aggregation_level);
//Parse the list. If the node is already created, return without initialization.
while (currentPtr != NULL) {
//printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength);
+ //LOG_D(PHY,"Looking for index %d\n",(messageType * messageLength * aggregation_prime));
if (currentPtr->idx == (messageType * messageLength * aggregation_prime)) return;
else currentPtr = currentPtr->nextPtr;
}
@@ -55,8 +56,9 @@ static void nr_polar_init(t_nrPolar_params * *polarParams,
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
//Else, initialize and add node to the end of the linked list.
t_nrPolar_params *newPolarInitNode = calloc(sizeof(t_nrPolar_params),1);
-
+
if (newPolarInitNode != NULL) {
+ // LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * messageLength * aggregation_prime),messageType,messageLength,aggregation_prime);
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
newPolarInitNode->nextPtr = NULL;
//printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level);
@@ -87,15 +89,44 @@ static void nr_polar_init(t_nrPolar_params * *polarParams,
newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
//printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level);
- } else if (messageType == -1) { //UCI
+ } else if (messageType == 2) { //UCI PUCCH2
+ AssertFatal(aggregation_level>2,"Aggregation level (%d) for PUCCH 2 encoding is NPRB and should be > 2\n",aggregation_level);
+ AssertFatal(messageLength>11,"Message length %d is too short for polar encoding of UCI\n",messageLength);
+ newPolarInitNode->n_max = NR_POLAR_PUCCH_N_MAX;
+ newPolarInitNode->i_il = NR_POLAR_PUCCH_I_IL;
+ newPolarInitNode->encoderLength = aggregation_level * 16;
+
+ newPolarInitNode->i_seg = 0;
+
+ if ((messageLength >= 360 && newPolarInitNode->encoderLength >= 1088)||
+ (messageLength >= 1013)) newPolarInitNode->i_seg = 1;
+
+ newPolarInitNode->crcParityBits = 11;
+ newPolarInitNode->n_pc = 0;
+ newPolarInitNode->n_pc_wm = 0;
+
+ if (messageLength < 20) {
+ newPolarInitNode->crcParityBits = 6;
+ newPolarInitNode->n_pc = 3;
+ if ((newPolarInitNode->encoderLength - messageLength - 6 + 3) < 193) newPolarInitNode->n_pc_wm = 1;
+ }
+
+
+
+ newPolarInitNode->i_bil = NR_POLAR_PUCCH_I_BIL;
+
+ newPolarInitNode->payloadBits = messageLength;
+ newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS;
+ //newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
+ //LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level);
} else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
}
newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode.
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K,
- newPolarInitNode->encoderLength,
- newPolarInitNode->n_max);
+ newPolarInitNode->encoderLength,
+ newPolarInitNode->n_max);
newPolarInitNode->n = log2(newPolarInitNode->N);
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
//polar_encoder vectors:
@@ -191,16 +222,19 @@ t_nrPolar_params *nr_polar_params (int8_t messageType,
nr_polar_init(polarList_ext != NULL ? polarList_ext : &polarList,
messageType,messageLength,aggregation_level,decoding_flag);
t_nrPolar_params *polarParams=polarList_ext != NULL ? *polarList_ext : polarList;
- const int tag=messageType * messageLength * nr_polar_aggregation_prime(aggregation_level);
+ const int tag=messageType * messageLength * (messageType>=2 ? aggregation_level : nr_polar_aggregation_prime(aggregation_level));
+
+
while (polarParams != NULL) {
+ // LOG_D(PHY,"nr_polar_params : tag %d (from nr_polar_init %d)\n",tag,polarParams->idx);
if (polarParams->idx == tag)
return polarParams;
polarParams = polarParams->nextPtr;
}
- AssertFatal(false,"Polar Init tables internal failure\n");
+ AssertFatal(false,"Polar Init tables internal failure, no polarParams found\n");
return NULL;
}
diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c
index 0cffc2d852..5294e79b9f 100644
--- a/openair1/PHY/CODING/nr_rate_matching.c
+++ b/openair1/PHY/CODING/nr_rate_matching.c
@@ -364,8 +364,8 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
if (ind < Foffset) { // case where we have some bits before the filler and the rest after
memcpy((void*)e,(void*)(w+ind),Foffset-ind);
- if (E + F <= Ncb) { // E+F doesn't contain all coded bits
- memcpy((void*)(e+Foffset-ind),(void*)(w+Foffset+F-ind),E-Foffset+ind);
+ if (E + F <= Ncb-ind) { // E+F doesn't contain all coded bits
+ memcpy((void*)(e+Foffset-ind),(void*)(w+Foffset+F),E-Foffset+ind);
k=E;
}
else {
@@ -375,11 +375,12 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
}
else {
if (E + F <= Ncb-ind) { //E+F doesn't contain all coded bits
- memcpy((void*)(e+Foffset-ind),(void*)(w+Foffset+F-ind),E-Foffset+ind);
+ memcpy((void*)(e),(void*)(w+ind),E);
k=E;
}
else {
-
+ memcpy((void*)(e),(void*)(w+ind),Ncb-ind);
+ k=Ncb-ind;
}
}
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 813d419429..9e095d5ab5 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -25,7 +25,8 @@
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
/*#include "RadioResourceConfigCommonSIB.h"
#include "RadioResourceConfigDedicated.h"
#include "TDD-Config.h"
@@ -39,7 +40,6 @@
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h"
-#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "nfapi_nr_interface.h"
/*
@@ -153,11 +153,11 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
}
}
-
nr_init_pdsch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
//PUSCH DMRS init
gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(2*sizeof(uint32_t ***));
+
uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs;
for(int nscid=0; nscid<2; nscid++) {
@@ -176,6 +176,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
}
uint32_t Nid_pusch[2] = {cfg->cell_config.phy_cell_id.value,cfg->cell_config.phy_cell_id.value};
+ LOG_D(PHY,"Initializing PUSCH DMRS Gold sequence with (%x,%x)\n",Nid_pusch[0],Nid_pusch[1]);
nr_gold_pusch(gNB, &Nid_pusch[0]);
/// Transport init necessary for NR synchro
@@ -232,6 +233,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
*/
prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
+ init_prach_list(gNB);
+
int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value;
printf("Before ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]);
@@ -405,7 +408,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
fp->nr_band = 78;
- fp->threequarter_fs= 0;
+// fp->threequarter_fs= 0;
gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band);
@@ -417,6 +420,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
uint8_t Mod_id = phy_config->Mod_id;
+ uint8_t short_sequence, num_sequences, rootSequenceIndex, fd_occasion;
NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms;
nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config;
@@ -480,6 +484,14 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
return;
}
+ fd_occasion = 0;
+ nfapi_nr_prach_config_t *prach_config = &gNB_config->prach_config;
+ short_sequence = prach_config->prach_sequence_length.value;
+ num_sequences = prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value;
+ rootSequenceIndex = prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value;
+
+ compute_nr_prach_seq(short_sequence, num_sequences, rootSequenceIndex, RC.gNB[Mod_id]->X_u);
+
RC.gNB[Mod_id]->configured = 1;
LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
@@ -492,6 +504,12 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
LOG_I(PHY, "Initialise nr transport\n");
uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
+ for (i=0; ipucch[i] = new_gNB_pucch();
+ AssertFatal(gNB->pucch[i]!=NULL,"Can't initialize pucch %d \n", i);
+ }
+
for (i=0; inb_log_antennas=0;
for (int n=0;ngNB_config;
+ cfg = &ru->config;
if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
}
+ // copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration (at least the parts that are needed by the RU, numerology and PRACH)
+
AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas);
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
// Time-domain signals
@@ -107,7 +110,8 @@ int nr_phy_init_RU(RU_t *ru) {
ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
for (i=0; inb_rx; i++) {
- ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
+ // largest size for PRACH FFT is 4x98304 (16*24576)
+ ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]);
}
@@ -144,6 +148,8 @@ int nr_phy_init_RU(RU_t *ru) {
ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP );
+ init_prach_ru_list(ru);
+
return(0);
}
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 5a60d15e2b..1729ac0d9e 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -77,19 +77,19 @@ void phy_config_sib2_ue(uint8_t Mod_id,int CC_id,
LOG_I(PHY,"[UE%d] Applying radioResourceConfigCommon from eNB%d\n",Mod_id,eNB_id);
- fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex;
+ ue->prach_vars[eNB_id]->prach_pdu.root_seq_id =radioResourceConfigCommon->prach_Config.rootSequenceIndex;
- fp->prach_config_common.prach_Config_enabled=1;
- fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
- fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.highSpeedFlag;
- fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig;
- fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset;
+ ue->prach_vars[eNB_id]->prach_Config_enabled=1;
+ //ue->prach_vars[eNB_id]->prach_pdu.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
+ ue->prach_vars[eNB_id]->prach_pdu.restricted_set =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.highSpeedFlag;
+ ue->prach_vars[eNB_id]->prach_pdu.num_cs =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig;
+ //ue->prach_vars[eNB_id]->prach_pdu.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset;
- compute_prach_seq(fp->prach_config_common.rootSequenceIndex,
- fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
- fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
- fp->prach_config_common.prach_ConfigInfo.highSpeedFlag,
- fp->frame_type,ue->X_u);
+ //compute_prach_seq(fp->prach_config_common.rootSequenceIndex,
+ // fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
+ // fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+ // fp->prach_config_common.prach_ConfigInfo.highSpeedFlag,
+ // fp->frame_type,ue->X_u);
@@ -226,12 +226,12 @@ void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_
LOG_I(PHY,"[UE%d] Handover triggered: Applying radioResourceConfigCommon from eNB %d\n",
Mod_id,eNB_id);
- fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex;
- fp->prach_config_common.prach_Config_enabled=1;
- fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex;
- fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag;
- fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig;
- fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset;
+ ue->prach_vars[eNB_id]->prach_pdu.root_seq_id =radioResourceConfigCommon->prach_Config.rootSequenceIndex;
+ ue->prach_vars[eNB_id]->prach_Config_enabled=1;
+ //ue->prach_vars[eNB_id]->prach_pdu.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex;
+ ue->prach_vars[eNB_id]->prach_pdu.restricted_set =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag;
+ ue->prach_vars[eNB_id]->prach_pdu.num_cs =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig;
+ //ue->prach_vars[eNB_id]->prach_pdu.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset;
// prach_fmt = get_prach_fmt(radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex,fp->frame_type);
// N_ZC = (prach_fmt <4)?839:139;
@@ -239,12 +239,12 @@ void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_
// prach_root_sequence_map4[fp->prach_config_common.rootSequenceIndex];
//compute_prach_seq(u,N_ZC, PHY_vars_UE_g[Mod_id]->X_u);
- compute_prach_seq(PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.rootSequenceIndex,
- PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
- PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
- PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,
- fp->frame_type,
- PHY_vars_UE_g[Mod_id][CC_id]->X_u);
+ //compute_prach_seq(PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.rootSequenceIndex,
+ // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
+ // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+ // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,
+ // fp->frame_type,
+ // PHY_vars_UE_g[Mod_id][CC_id]->X_u);
fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon->deltaPUCCH_Shift;
@@ -958,7 +958,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
// enable MIB/SIB decoding by default
ue->decode_MIB = 1;
ue->decode_SIB = 1;
- init_prach_tables(839);
+
+ init_nr_prach_tables(839);
+
return 0;
}
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
index aaa138fcd9..f85162e095 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
@@ -112,18 +112,12 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms,
}
-int lte_est_timing_advance_pusch(PHY_VARS_eNB *eNB,
- module_id_t UE_id)
+int lte_est_timing_advance_pusch(LTE_DL_FRAME_PARMS *frame_parms,
+ int32_t **ul_ch_estimates_time)
{
int temp, i, aa, max_pos=0, max_val=0;
short Re,Im;
- RU_t *ru;
- ru = RC.ru[UE_id];
- LTE_DL_FRAME_PARMS *frame_parms = (eNB==NULL) ? ru->frame_parms : &eNB->frame_parms;
- LTE_eNB_PUSCH *eNB_pusch_vars = (eNB!=NULL) ? eNB->pusch_vars[UE_id] : (LTE_eNB_PUSCH*)NULL;
- RU_CALIBRATION *calibration = &ru->calibration;
- int32_t **ul_ch_estimates_time = (eNB==NULL) ? calibration->drs_ch_estimates_time : eNB_pusch_vars->drs_ch_estimates_time;
uint8_t cyclic_shift = 0;
int sync_pos = (frame_parms->ofdm_symbol_size-cyclic_shift*frame_parms->ofdm_symbol_size/12)%(frame_parms->ofdm_symbol_size);
@@ -149,7 +143,7 @@ int lte_est_timing_advance_pusch(PHY_VARS_eNB *eNB,
max_pos = max_pos-frame_parms->ofdm_symbol_size;
//#ifdef DEBUG_PHY
- LOG_D(PHY,"frame %d: max_pos = %d, sync_pos=%d\n",eNB->proc.frame_rx,max_pos,sync_pos);
+ LOG_D(PHY,"max_pos = %d, sync_pos=%d\n",max_pos,sync_pos);
//#endif //DEBUG_PHY
return max_pos - sync_pos;
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h
index 01883224db..fc40280853 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h
+++ b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h
@@ -220,8 +220,12 @@ void phy_adjust_gain (PHY_VARS_UE *phy_vars_ue,
uint32_t rx_power_fil_dB,
unsigned char eNB_id);
-int lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB,
+int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
L1_rxtx_proc_t *proc,
+ LTE_eNB_ULSCH_t * ulsch,
+ int32_t **ul_ch_estimates,
+ int32_t **ul_ch_estimates_time,
+ int32_t **rxdataF_ext,
module_id_t UE_id,
uint8_t l,
uint8_t Ns);
@@ -258,7 +262,8 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms,
unsigned char number_of_cards,
short coef);
-int lte_est_timing_advance_pusch(PHY_VARS_eNB* phy_vars_eNB,module_id_t UE_id);
+int lte_est_timing_advance_pusch(LTE_DL_FRAME_PARMS *frame_parms,
+ int32_t **ul_ch_estimates_time);
void lte_eNB_I0_measurements(PHY_VARS_eNB *phy_vars_eNB,
int subframe,
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
index 7caaf07406..755111feb8 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
@@ -34,23 +34,17 @@ static int16_t ru_90c[2*128] = {32767, 0,32766, -402,32758, -804,32746, -1206,32
#define SCALE 0x3FFF
-int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB,
+int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
L1_rxtx_proc_t *proc,
+ LTE_eNB_ULSCH_t * ulsch,
+ int32_t **ul_ch_estimates,
+ int32_t **ul_ch_estimates_time,
+ int32_t **rxdataF_ext,
module_id_t UE_id,
unsigned char l,
unsigned char Ns) {
- RU_t *ru;
- ru = RC.ru[UE_id];
- LTE_DL_FRAME_PARMS *frame_parms = (eNB!=NULL) ? &eNB->frame_parms : ru->frame_parms;
- LTE_eNB_PUSCH *pusch_vars = (eNB!=NULL) ? eNB->pusch_vars[UE_id] : NULL;
- RU_CALIBRATION *calibration = &ru->calibration;
- int32_t **ul_ch_estimates = (eNB!=NULL) ? pusch_vars->drs_ch_estimates : calibration->drs_ch_estimates;
- AssertFatal(ul_ch_estimates != NULL, "ul_ch_estimates is null (eNB %p, pusch %p, pusch->drs_ch_estimates %p, pusch->drs_ch_estimates[0] %p ul_ch_estimates %p UE_id %d)\n",eNB,pusch_vars,
- pusch_vars->drs_ch_estimates,pusch_vars->drs_ch_estimates[0],ul_ch_estimates,UE_id);
- int32_t **ul_ch_estimates_time = (eNB!=NULL) ? pusch_vars->drs_ch_estimates_time : calibration->drs_ch_estimates_time;
+ AssertFatal(ul_ch_estimates != NULL, "ul_ch_estimates is null ");
AssertFatal(ul_ch_estimates_time != NULL, "ul_ch_estimates_time is null\n");
- int32_t **rxdataF_ext = (eNB!=NULL) ? pusch_vars->rxdataF_ext : calibration->rxdataF_ext;
-
int subframe = proc->subframe_rx;
uint8_t harq_pid;
@@ -83,16 +77,16 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB,
#endif
int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32)));
- if (eNB->ulsch[UE_id]->ue_type > 0) harq_pid = 0;
+ if (ulsch->ue_type > 0) harq_pid = 0;
else {
harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe);
}
- uint16_t N_rb_alloc = eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb;
+ uint16_t N_rb_alloc = ulsch->harq_processes[harq_pid]->nb_rb;
int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16)));
Msc_RS = N_rb_alloc*12;
cyclic_shift = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
- eNB->ulsch[UE_id]->harq_processes[harq_pid]->n_DMRS2 +
+ ulsch->harq_processes[harq_pid]->n_DMRS2 +
frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[(subframe<<1)+Ns]) % 12;
Msc_idx_ptr = (uint16_t *) bsearch(&Msc_RS, dftsizes, 34, sizeof(uint16_t), compareints);
@@ -276,7 +270,7 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB,
#if T_TRACER
if (aa == 0)
- T(T_ENB_PHY_UL_CHANNEL_ESTIMATE, T_INT(0), T_INT(eNB->ulsch[UE_id]->rnti),
+ T(T_ENB_PHY_UL_CHANNEL_ESTIMATE, T_INT(0), T_INT(ulsch->rnti),
T_INT(proc->frame_rx), T_INT(subframe),
T_INT(0), T_BUFFER(ul_ch_estimates_time[0], 512 * 4));
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index ce409de131..8de011acef 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -2006,11 +2006,6 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu
return;
}
- //AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n");
- if(ulsch->harq_processes[harq_pid]->nb_rb == 0) {
- LOG_E(PHY, "fill_ulsch UE_id %d nb_rb = 0\n", UE_id);
- }
-
ulsch->harq_processes[harq_pid]->frame = frame;
ulsch->harq_processes[harq_pid]->subframe = subframe;
ulsch->harq_processes[harq_pid]->handled = 0;
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index 15eb5206a1..14036ad43a 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -422,6 +422,6 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
else
r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
}
-
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0);
}
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
index f357e385f0..1b23fc99bf 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
@@ -1047,7 +1047,11 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
l%(frame_parms->symbols_per_tti/2),
l/(frame_parms->symbols_per_tti/2),
frame_parms);
- lte_ul_channel_estimation(eNB,proc,
+ lte_ul_channel_estimation(&eNB->frame_parms,proc,
+ eNB->ulsch[UE_id],
+ eNB->pusch_vars[UE_id]->drs_ch_estimates,
+ eNB->pusch_vars[UE_id]->drs_ch_estimates_time,
+ eNB->pusch_vars[UE_id]->rxdataF_ext,
UE_id,
l%(frame_parms->symbols_per_tti/2),
l/(frame_parms->symbols_per_tti/2));
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
index 2fd84f563c..556a9f2d23 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
@@ -821,15 +821,14 @@ int rx_pdsch(PHY_VARS_UE *ue,
pllr_symbol_cw0 += llr_offset_symbol;
pllr_symbol_cw1 += llr_offset_symbol;
- /*
- LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n",
+ LOG_D(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p energy: %d\n",
frame, subframe,symbol,
nb_rb,dlsch0_harq->Qm,
pdsch_vars[eNB_id]->llr_length[symbol],
pdsch_vars[eNB_id]->llr_offset[symbol],
(int16_t*)pdsch_vars[eNB_id]->llr[0],
- pllr_symbol_cw0);
- */
+ pllr_symbol_cw0,
+ signal_energy(pdsch_vars[eNB_id]->rxdataF_comp0[0], 7*2*frame_parms->N_RB_DL*12));
switch (dlsch0_harq->Qm) {
case 2 :
if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c
index b27b692e66..dbfe93adee 100644
--- a/openair1/PHY/MODULATION/nr_modulation.c
+++ b/openair1/PHY/MODULATION/nr_modulation.c
@@ -34,6 +34,8 @@ void nr_modulation(uint32_t *in,
offset = (mod_order==2)? NR_MOD_TABLE_QPSK_OFFSET : (mod_order==4)? NR_MOD_TABLE_QAM16_OFFSET : \
(mod_order==6)? NR_MOD_TABLE_QAM64_OFFSET: (mod_order==8)? NR_MOD_TABLE_QAM256_OFFSET : 0;
+ LOG_D(PHY,"nr_modulation: length %d, mod_order %d\n",length,mod_order);
+
for (int i=0; iframe_parms;
NR_UE_COMMON *common_vars = &ue->common_vars;
@@ -339,7 +339,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
#endif
- dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+ dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
@@ -363,7 +363,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
dft(dftsize,(int16_t *)tmp_dft_in,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
- dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+ dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
}
#if UE_TIMING_TRACE
@@ -395,12 +395,13 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
int sample_offset,
int no_prefix)
{
- uint32_t slot_offset;
- uint32_t rxdata_offset;
+ int32_t slot_offset, rxdata_offset;
unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
+ int tmp_dft_in[8192] __attribute__ ((aligned (32)));
+
dft_size_idx_t dftsize;
switch (frame_parms->ofdm_symbol_size) {
@@ -443,14 +444,29 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
-
if(symbol == 0)
rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET;
else
rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET;
- dft(dftsize,(int16_t *)&rxdata[rxdata_offset],
- (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
+ if(sample_offset>rxdata_offset) {
+ memcpy((void *)tmp_dft_in,
+ (void *) &rxdata[frame_parms->samples_per_frame-sample_offset+rxdata_offset],
+ (sample_offset-rxdata_offset)*sizeof(int));
+
+ memcpy((void *)&tmp_dft_in[sample_offset-rxdata_offset],
+ (void *) &rxdata[0],
+ (frame_parms->ofdm_symbol_size-sample_offset+rxdata_offset)*sizeof(int));
+
+ dft(dftsize,(int16_t *)&tmp_dft_in,
+ (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
+ }
+ else
+ dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset],
+ (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
+
+ // clear DC carrier from OFDM symbols
+ rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0;
return(0);
}
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index f94a82c111..3f7c7817f7 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -28,7 +28,7 @@
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
//#define DEBUG_CH
-
+//#define DEBUG_PUSCH
int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
unsigned char Ns,
@@ -116,7 +116,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//------------------generate DMRS------------------//
- nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->dmrs_config_type);
+ if (pusch_pdu->transform_precoding==1) // if transform precoding is disabled
+ nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
+ else
+ nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type);
//------------------------------------------------//
@@ -129,8 +132,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size));
#ifdef DEBUG_PUSCH
+ printf("symbol_offset %d, nushift %d\n",symbol_offset,nushift);
printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL);
- printf("k %d, first_carrier %d\n",k,gNB->frame_parms.first_carrier_offset);
+ printf("bwp_start_subcarrier %d, k %d, first_carrier %d\n",bwp_start_subcarrier,k,gNB->frame_parms.first_carrier_offset);
printf("rxF addr %p p %d\n", rxF,p);
printf("ul_ch addr %p nushift %d\n",ul_ch,nushift);
#endif
@@ -145,7 +149,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#ifdef DEBUG_PUSCH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
- printf("data 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[2],rxF[3],&rxF[2],ch[0],ch[1],pil[0],pil[1]);
+ printf("data 0 : rxF - > (%d,%d)\n",rxF[2],rxF[3]);
#endif
multadd_real_vector_complex_scalar(fl,
@@ -163,6 +167,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#ifdef DEBUG_PUSCH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+ printf("data 1 : rxF - > (%d,%d)\n",rxF[2],rxF[3]);
#endif
multadd_real_vector_complex_scalar(fml,
ch,
@@ -178,6 +183,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#ifdef DEBUG_PUSCH
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+ printf("data 2 : rxF - > (%d,%d)\n",rxF[2],rxF[3]);
#endif
multadd_real_vector_complex_scalar(fmm,
ch,
@@ -198,7 +204,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+ printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+ printf("data %u : rxF - > (%d,%d)\n",pilot_cnt,rxF[2],rxF[3]);
#endif
multadd_real_vector_complex_scalar(fml,
ch,
@@ -214,6 +221,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#ifdef DEBUG_PUSCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+ printf("data %u : rxF - > (%d,%d)\n",pilot_cnt+1,rxF[2],rxF[3]);
#endif
multadd_real_vector_complex_scalar(fmm,
ch,
@@ -235,6 +243,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+ printf("data %u : rxF - > (%d,%d)\n",pilot_cnt,rxF[2],rxF[3]);
#endif
multadd_real_vector_complex_scalar(fm,
ch,
@@ -253,6 +262,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#ifdef DEBUG_PUSCH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
printf("pilot %u: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
+ printf("data %u : rxF - > (%d,%d)\n",pilot_cnt+1,rxF[2],rxF[3]);
#endif
multadd_real_vector_complex_scalar(fmr,
ch,
@@ -268,6 +278,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
printf("pilot %u: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+ printf("data %u : rxF - > (%d,%d)\n",pilot_cnt+2,rxF[2],rxF[3]);
#endif
multadd_real_vector_complex_scalar(fr,
ch,
@@ -275,70 +286,69 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
8);
- // check if PRB crosses DC and improve estimates around DC
- if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) {
- ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
- uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
- uint16_t idxPil = idxDC/2;
- re_offset = k;
- pil = (int16_t *)&pilot[0];
- pil += (idxPil-2);
- ul_ch += (idxDC-4);
- ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10);
- re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size;
- rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
- ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
- ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
-
- // for proper allignment of SIMD vectors
- if((gNB->frame_parms.N_RB_UL&1)==0) {
+ // check if PRB crosses DC and improve estimates around DC
+ if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) {
+ ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
+ uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
+ uint16_t idxPil = idxDC/2;
+ re_offset = k;
+ pil = (int16_t *)&pilot[0];
+ pil += (idxPil-2);
+ ul_ch += (idxDC-4);
+ ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10);
+ re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size;
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
- multadd_real_vector_complex_scalar(fdcl,
- ch,
- ul_ch-4,
- 8);
+ // for proper allignment of SIMD vectors
+ if((gNB->frame_parms.N_RB_UL&1)==0) {
+
+ multadd_real_vector_complex_scalar(fdcl,
+ ch,
+ ul_ch-4,
+ 8);
- pil += 4;
- re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
- rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
- ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
- ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+ pil += 4;
+ re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
- multadd_real_vector_complex_scalar(fdcr,
- ch,
- ul_ch-4,
- 8);
- } else {
+ multadd_real_vector_complex_scalar(fdcr,
+ ch,
+ ul_ch-4,
+ 8);
+ }
+ else {
+ multadd_real_vector_complex_scalar(fdclh,
+ ch,
+ ul_ch,
+ 8);
- multadd_real_vector_complex_scalar(fdclh,
- ch,
- ul_ch,
- 8);
+ pil += 4;
+ re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
- pil += 4;
- re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
- rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
- ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
- ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
-
- multadd_real_vector_complex_scalar(fdcrh,
- ch,
- ul_ch,
- 8);
+ multadd_real_vector_complex_scalar(fdcrh,
+ ch,
+ ul_ch,
+ 8);
+ }
}
-
- }
#ifdef DEBUG_PDSCH
- ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
- for(uint16_t idxP=0; idxPframe_parms.ofdm_symbol_size) {
+ switch (gNB->frame_parms.ofdm_symbol_size) {
case 128:
idft(IDFT_128,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
(int16_t*) ul_ch_estimates_time[aarx],
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c
index 8718fc8610..7042c152fd 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c
@@ -33,7 +33,32 @@
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
#include "PHY/NR_REFSIG/dmrs_nr.h"
-/***********************************************************************/
+
+
+uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k,
+ uint16_t start_sc,
+ uint8_t numDmrsCdmGrpsNoData,
+ uint8_t dmrs_type) {
+ uint8_t delta;
+ uint16_t diff;
+ if (k>start_sc)
+ diff = k-start_sc;
+ else
+ diff = start_sc-k;
+ for (int i = 0; i 2)
- LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", dmrs_type);
+ LOG_E(PHY,"PUSCH DMRS config type %d not valid\n", dmrs_type+1);
if ((p>=1000) && (p<((dmrs_type==pusch_dmrs_type1) ? 1008 : 1012))) {
if (gNB->frame_parms.Ncp == NORMAL) {
-
- for (int i=0; i>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
- ((int16_t*)output)[i<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
- ((int16_t*)output)[(i<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
+ ((int16_t*)output)[k<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
+ ((int16_t*)output)[(k<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
#ifdef DEBUG_PUSCH
- printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb);
- printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]);
- printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1),
- (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]);
+ printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb);
+ printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]);
+ printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1),
+ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[k<<1], ((int16_t*)output)[(k<<1)+1]);
#endif
+
}
} else {
LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n");
@@ -102,7 +105,6 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
}
-
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
unsigned int Ns,
unsigned int *nr_gold_pdsch,
diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c
index 472d03e649..4b007f1292 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold.c
@@ -88,6 +88,7 @@ void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
uint16_t N_n_scid[NR_MAX_NB_CODEWORDS]={Nid, Nid}; // Not correct, appropriate scrambling IDs have to be updated to support DCI 1_1
uint8_t n_scid=0; // again works only for 1_0
for (uint8_t slot=0; slotslots_per_frame; slot++) {
+
for (uint8_t symb=0; symbsymbols_per_slot; symb++) {
reset = 1;
x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index d18f6405d7..1bf2ef4fb2 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -48,6 +48,7 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb,
+ uint32_t re_offset,
uint8_t dmrs_type);
void init_scrambling_luts(void);
diff --git a/openair1/PHY/NR_REFSIG/scrambling_luts.c b/openair1/PHY/NR_REFSIG/scrambling_luts.c
index 9d957de0f7..790d3f7719 100644
--- a/openair1/PHY/NR_REFSIG/scrambling_luts.c
+++ b/openair1/PHY/NR_REFSIG/scrambling_luts.c
@@ -27,6 +27,7 @@
#include "PHY/impl_defs_nr.h"
#include "PHY/sse_intrin.h"
+#include
__m64 byte2m64_re[256];
__m64 byte2m64_im[256];
@@ -42,7 +43,7 @@ void init_byte2m64(void) {
byte2m64_im[s] = _mm_insert_pi16(byte2m64_im[s],(1-2*((s>>5)&1)),2);
byte2m64_re[s] = _mm_insert_pi16(byte2m64_re[s],(1-2*((s>>6)&1)),3);
byte2m64_im[s] = _mm_insert_pi16(byte2m64_im[s],(1-2*((s>>7)&1)),3);
- printf("init_scrambling_luts: s %x (%d) ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+ LOG_T(PHY,"init_scrambling_luts: s %x (%d) ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
((uint16_t*)&s)[0],
(1-2*(s&1)),
((int16_t*)&byte2m64_re[s])[0],((int16_t*)&byte2m64_im[s])[0],
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index d62687bd9c..a29211b55b 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -131,12 +131,13 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
void nr_pdcch_scrambling(uint32_t *in,
uint32_t size,
uint32_t Nid,
- uint32_t n_RNTI,
+ uint32_t scrambling_RNTI,
uint32_t *out) {
uint8_t reset;
uint32_t x1, x2, s=0;
reset = 1;
- x2 = (n_RNTI<<16) + Nid;
+ x2 = (scrambling_RNTI<<16) + Nid;
+ LOG_D(PHY,"PDCCH Scrambling x2 %x : scrambling_RNTI %x \n", x2, scrambling_RNTI);
for (int i=0; iCceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED,
"Interleaved CCE REG MAPPING not supported\n");
uint32_t dmrs_length = (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED)?
- (n_rb*6) : (pdcch_pdu_rel15->AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE)
- uint32_t encoded_length = pdcch_pdu_rel15->AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE)
+ (n_rb*6) : (pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE)
+ uint32_t encoded_length = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE)
LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d)\n", dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType);
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
@@ -228,18 +229,20 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
/// DCI payload processing
// CRC attachment + Scrambling + Channel coding + Rate matching
uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
- uint16_t n_RNTI = pdcch_pdu_rel15->RNTI[d];
- uint16_t Nid = pdcch_pdu_rel15->ScramblingId[d];
-
+
+ uint16_t n_RNTI = pdcch_pdu_rel15->dci_pdu.RNTI[d];
+ uint16_t Nid = pdcch_pdu_rel15->dci_pdu.ScramblingId[d];
+ uint16_t scrambling_RNTI = pdcch_pdu_rel15->dci_pdu.ScramblingRNTI[d];
+
t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE,
- pdcch_pdu_rel15->PayloadSizeBits[d],
- pdcch_pdu_rel15->AggregationLevel[d],
+ pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d],
+ pdcch_pdu_rel15->dci_pdu.AggregationLevel[d],
0,NULL);
- polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->Payload[d], encoder_output, n_RNTI,1,currentPtr);
+ polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d], (void*)encoder_output, n_RNTI,1,currentPtr);
#ifdef DEBUG_CHANNEL_CODING
- printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->PayloadSizeBits[d],pdcch_pdu_rel15->AggregationLevel[d]);
+ printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d],pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]);
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
- ((uint64_t*)pdcch_pdu_rel15->Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->Payload[d])[1]);
+ ((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d])[1]);
printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5);
for (int i=0; i>5; i++)
@@ -249,7 +252,7 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
#endif
/// Scrambling
uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0};
- nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output);
+ nr_pdcch_scrambling(encoder_output, encoded_length, Nid, scrambling_RNTI, scrambled_output);
#ifdef DEBUG_CHANNEL_CODING
printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \
[6]->0x%08x \t [7]->0x%08x \t [8]->0x%08x \t [9]->0x%08x\t [10]->0x%08x\t [11]->0x%08x\n",
@@ -272,8 +275,8 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
cset_start_sc -= frame_parms.ofdm_symbol_size;
/*Reorder REG list for a freq first mapping*/
- uint8_t nb_regs = pdcch_pdu_rel15->AggregationLevel[d]*NR_NB_REG_PER_CCE;
- uint8_t reg_idx0 = pdcch_pdu_rel15->CceIndex[d]*NR_NB_REG_PER_CCE;
+ uint8_t reg_idx0 = pdcch_pdu_rel15->dci_pdu.CceIndex[d]*NR_NB_REG_PER_CCE;
+ uint8_t nb_regs = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*NR_NB_REG_PER_CCE;
/*Mapping the encoded DCI along with the DMRS */
for (int reg_idx=reg_idx0; reg_idx<(nb_regs+reg_idx0); reg_idx++) {
@@ -295,8 +298,8 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
for (int m=0; mCceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED) {
- ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (2*amp * mod_dmrs[l][dmrs_idx<<1]) >> 15;
- ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (2*amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
+ ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[l][dmrs_idx<<1]) >> 15;
+ ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS
printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
index c7b14571b7..02ecfc4404 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
@@ -140,7 +140,7 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) {
int C=-1;
for (int d=0;dnumDlDci;d++) {
- int L = pdcch_pdu_rel15->AggregationLevel[d];
+ int L = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d];
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1)
AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L);
@@ -151,10 +151,10 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) {
C = N_reg/(bsize*R);
}
- LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->CceIndex[d]);
+ LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->dci_pdu.CceIndex[d]);
for (uint8_t cce_idx=0; cce_idxcce_list[d][cce_idx];
- cce->cce_idx = pdcch_pdu_rel15->CceIndex[d] + cce_idx;
+ cce->cce_idx = pdcch_pdu_rel15->dci_pdu.CceIndex[d] + cce_idx;
LOG_D(PHY, "cce_idx %d\n", cce->cce_idx);
if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
@@ -210,17 +210,17 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
for (int i=0;inumDlDci;i++) {
- //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
+ //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i];
-
- int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->RNTI[i],gNB,SEARCH_EXIST_OR_FREE);
+ int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->dci_pdu.RNTI[i],gNB,SEARCH_EXIST_OR_FREE);
if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){
- LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->RNTI[i],dlsch_id);
+ LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->dci_pdu.RNTI[i],dlsch_id);
return;
}
dlsch = gNB->dlsch[dlsch_id][0];
- int harq_pid = 0;//extract_harq_pid(i,pdu_rel15);
+ int num_slots_tdd = (gNB->frame_parms.slots_per_frame)>>(7-gNB->gNB_config.tdd_table.tdd_period.value);
+ int harq_pid = slot % num_slots_tdd;
dlsch->slot_tx[slot] = 1;
dlsch->harq_ids[frame%2][slot] = harq_pid;
@@ -228,7 +228,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
"illegal harq_pid %d\n",harq_pid);
dlsch->harq_mask |= (1<rnti = pdcch_pdu_rel15->RNTI[i];
+ dlsch->rnti = pdcch_pdu_rel15->dci_pdu.RNTI[i];
nr_fill_cce_list(gNB,0);
/*
@@ -248,7 +248,7 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
for (int i=0;inumDlDci;i++) {
- //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
+ //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i];
// if there's no DL DCI then generate CCE list
if (gNB->pdcch_pdu) nr_fill_cce_list(gNB,0);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index 4518280f6b..23466132d6 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -34,6 +34,8 @@
#include "nr_dci.h"
#include "nr_sch_dmrs.h"
#include "PHY/MODULATION/nr_modulation.h"
+#include "PHY/NR_REFSIG/dmrs_nr.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
//#define DEBUG_DLSCH
//#define DEBUG_DLSCH_MAPPING
@@ -47,7 +49,7 @@ void nr_pdsch_codeword_scrambling(uint8_t *in,
uint8_t reset, b_idx;
uint32_t x1, x2, s=0;
-
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_CODEWORD_SCRAMBLING, 1);
reset = 1;
x2 = (n_RNTI<<15) + (q<<14) + Nid;
@@ -62,7 +64,7 @@ void nr_pdsch_codeword_scrambling(uint8_t *in,
*out ^= (((in[i])&1) ^ ((s>>b_idx)&1))<harq_ids[frame%2][slot];
NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
int16_t **tx_layers = (int16_t**)dlsch->txdataF;
int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
-
uint8_t dmrs_Type = rel15->dmrsConfigType;
- int nb_re_dmrs = (dmrs_Type== NFAPI_NR_DMRS_TYPE1) ? 6:4;
- uint16_t n_dmrs = ((rel15->rbSize+rel15->rbStart)*nb_re_dmrs)<<1;
- int16_t mod_dmrs[n_dmrs<<1];
-
- uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords;
+ int nb_re_dmrs;
+ uint16_t n_dmrs;
+ if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) {
+ nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData;
+ n_dmrs = ((rel15->rbSize+rel15->rbStart)*6)<<1;
+ }
+ else {
+ nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
+ n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1;
+ }
+ uint16_t nb_re;
+ nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords;
uint8_t Qm = rel15->qamModOrder[0];
uint32_t encoded_length = nb_re*Qm;
+ int16_t mod_dmrs[n_dmrs<<1];
/// CRC, coding, interleaving and rate matching
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
@@ -193,11 +202,13 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
/// Modulation
start_meas(dlsch_modulation_stats);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 1);
for (int q=0; qNrOfCodewords; q++)
nr_modulation(scrambled_output[q],
encoded_length,
Qm,
mod_symbs[q]);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 0);
stop_meas(dlsch_modulation_stats);
#ifdef DEBUG_DLSCH
printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re);
@@ -297,15 +308,16 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
}
else {
-
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
+ if( (l != dmrs_symbol) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
- printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
-m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
+ printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
+ m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif
- m++;
+ m++;
+ }
}
if (++k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
index f48905b68c..3a6851ee8f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
@@ -90,7 +90,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
-void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB);
+void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB);
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index f120864184..2f55bde321 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -36,7 +36,7 @@
#include "PHY/CODING/coding_defs.h"
#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/CODING/nrLDPC_extern.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
@@ -49,7 +49,7 @@
//#define DEBUG_DLSCH_FREE 1
-void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB)
+void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB)
{
int i;
int r;
@@ -130,7 +130,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB)
}
free16(dlsch,sizeof(NR_gNB_DLSCH_t));
- dlsch = NULL;
+ *dlschptr = NULL;
}
}
@@ -335,13 +335,19 @@ int nr_dlsch_encoding(unsigned char *a,
uint32_t E;
uint8_t Ilbrm = 1;
uint32_t Tbslbrm = 950984; //max tbs
- uint8_t nb_re_dmrs = rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1 ? 6:4;
+ uint8_t nb_re_dmrs;
+
+ if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1)
+ nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData;
+ else
+ nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
+
uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
uint16_t R=rel15->targetCodeRate[0];
float Coderate = 0.0;
uint8_t Nl = 4;
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
A = rel15->TBSize[0]<<3;
@@ -459,6 +465,9 @@ int nr_dlsch_encoding(unsigned char *a,
}
+ F = dlsch->harq_processes[harq_pid]->F;
+
+ Kr = dlsch->harq_processes[harq_pid]->K;
for (r=0; rharq_processes[harq_pid]->C; r++) {
if (F>0) {
@@ -530,7 +539,7 @@ int nr_dlsch_encoding(unsigned char *a,
r_offset += E;
}
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return 0;
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
index 2e6fc707bd..7702d770ee 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
@@ -274,25 +274,7 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
return first_free_index;
}
-int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
- uint16_t i;
- int16_t first_free_index=-1;
-
- AssertFatal(gNB!=NULL,"gNB is null\n");
- for (i=0; iulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i);
- AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i);
- LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index);
- if ((gNB->ulsch[i][0]->harq_mask >0) &&
- (gNB->ulsch[i][0]->rnti==rnti)) return i;
- else if ((gNB->ulsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
- }
- if (type == SEARCH_EXIST) return -1;
- if (first_free_index != -1)
- gNB->ulsch[first_free_index][0]->rnti = 0;
- return first_free_index;
-}
void nr_fill_dlsch(PHY_VARS_gNB *gNB,
int frame,
@@ -316,26 +298,3 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB,
}
-void nr_fill_ulsch(PHY_VARS_gNB *gNB,
- int frame,
- int slot,
- nfapi_nr_pusch_pdu_t *ulsch_pdu) {
-
-
- int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
- AssertFatal( (ulsch_id>=0) && (ulsch_idrnti,ulsch_id);
-
- NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id][0];
- int harq_pid = ulsch_pdu->pusch_data.harq_process_id;
- ulsch->rnti = ulsch_pdu->rnti;
- //ulsch->rnti_type;
- ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid;
-
- memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t));
-
- LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
-
-}
-
diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
index b6a4787193..bc33d93811 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
@@ -32,7 +32,7 @@
*/
#include "PHY/defs_gNB.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "PHY/sse_intrin.h"
@@ -297,7 +297,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
a_reversed |= (((uint64_t)pbch->pbch_a_prime>>i)&1)<<(31-i);
/// CRC, coding and rate matching
- polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0, 0,
+ polar_encoder_fast (&a_reversed, (void*)pbch->pbch_e, 0, 0,
nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL,0,NULL)
);
#ifdef DEBUG_PBCH_ENCODING
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c
index 5c4d048a77..2640a86240 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c
@@ -31,141 +31,247 @@
*/
#include "PHY/defs_gNB.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
-#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
-extern uint16_t NCS_unrestricted_delta_f_RA_125[16];
-extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15];
-extern uint16_t NCS_restricted_TypeB_delta_f_RA_125[13];
-extern uint16_t NCS_unrestricted_delta_f_RA_5[16];
-extern uint16_t NCS_restricted_TypeA_delta_f_RA_5[16];
-extern uint16_t NCS_restricted_TypeB_delta_f_RA_5[14];
-extern uint16_t NCS_unrestricted_delta_f_RA_15[16];
extern uint16_t prach_root_sequence_map_0_3[838];
extern uint16_t prach_root_sequence_map_abc[138];
-extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
-extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
-extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
+extern const char *prachfmt[9];
+
+void init_prach_list(PHY_VARS_gNB *gNB) {
+
+ AssertFatal(gNB!=NULL,"gNB is null\n");
+ for (int i=0; iprach_vars.list[i].frame=-1;
+}
+
+int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, int numRA, find_type_t type) {
+
+ uint16_t i;
+ int16_t first_free_index=-1;
+
+ AssertFatal(gNB!=NULL,"gNB is null\n");
+ for (i=0; i %d.%d numRA %d\n", frame,slot,numRA,i,
+ gNB->prach_vars.list[i].frame,gNB->prach_vars.list[i].slot,gNB->prach_vars.list[i].pdu.num_ra);
+ if ((gNB->prach_vars.list[i].frame == frame) &&
+ (gNB->prach_vars.list[i].slot == slot) &&
+ (gNB->prach_vars.list[i].pdu.num_ra == numRA)) return i;
+ else if ((gNB->prach_vars.list[i].frame == -1) && (first_free_index==-1)) first_free_index=i;
+ }
+ if (type == SEARCH_EXIST) return -1;
+
+ return first_free_index;
+}
+
+void nr_fill_prach(PHY_VARS_gNB *gNB,
+ int SFN,
+ int Slot,
+ nfapi_nr_prach_pdu_t *prach_pdu) {
+
+ int prach_id = find_nr_prach(gNB,SFN,Slot,prach_pdu->num_ra,SEARCH_EXIST_OR_FREE);
+ AssertFatal( (prach_id>=0) && (prach_idnum_ra,prach_id);
+
+ gNB->prach_vars.list[prach_id].frame=SFN;
+ gNB->prach_vars.list[prach_id].slot=Slot;
+ memcpy((void*)&gNB->prach_vars.list[prach_id].pdu,(void*)prach_pdu,sizeof(*prach_pdu));
+
+}
+
+void init_prach_ru_list(RU_t *ru) {
+
+ AssertFatal(ru!=NULL,"ruis null\n");
+ for (int i=0; iprach_list[i].frame=-1;
+ pthread_mutex_init(&ru->prach_list_mutex,NULL);
+}
+
+int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) {
+
+ uint16_t i;
+ int16_t first_free_index=-1;
+
+ AssertFatal(ru!=NULL,"ru is null\n");
+ pthread_mutex_lock(&ru->prach_list_mutex);
+ for (i=0; i %d.%d\n", frame,slot,i,
+ ru->prach_list[i].frame,ru->prach_list[i].slot);
+ if ((ru->prach_list[i].frame == frame) &&
+ (ru->prach_list[i].slot == slot)) {
+ pthread_mutex_unlock(&ru->prach_list_mutex);
+ return i;
+ }
+ else if ((ru->prach_list[i].frame == -1) && (first_free_index==-1)) first_free_index=i;
+ }
+ pthread_mutex_unlock(&ru->prach_list_mutex);
+ if (type == SEARCH_EXIST) return -1;
+
+ return first_free_index;
+}
+
+void nr_fill_prach_ru(RU_t *ru,
+ int SFN,
+ int Slot,
+ nfapi_nr_prach_pdu_t *prach_pdu) {
+
+ int prach_id = find_nr_prach_ru(ru,SFN,Slot,SEARCH_EXIST_OR_FREE);
+ AssertFatal( (prach_id>=0) && (prach_idprach_list_mutex);
+ ru->prach_list[prach_id].frame = SFN;
+ ru->prach_list[prach_id].slot = Slot;
+ ru->prach_list[prach_id].fmt = prach_pdu->prach_format;
+ ru->prach_list[prach_id].numRA = prach_pdu->num_ra;
+ ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol;
+ pthread_mutex_unlock(&ru->prach_list_mutex);
+
+}
+
+void free_nr_ru_prach_entry(RU_t *ru,
+ int prach_id) {
+
+ pthread_mutex_lock(&ru->prach_list_mutex);
+ ru->prach_list[prach_id].frame=-1;
+ pthread_mutex_unlock(&ru->prach_list_mutex);
+
+}
+
void rx_nr_prach_ru(RU_t *ru,
+ int prachFormat,
+ int numRA,
+ int prachStartSymbol,
int frame,
- int subframe) {
+ int slot) {
AssertFatal(ru!=NULL,"ru is null\n");
int16_t **rxsigF=NULL;
NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms;
- int16_t prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
+ int slot2=slot;
+
int16_t *prach[ru->nb_rx];
- uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,fp->frame_type,fp->freq_range);
+ int prach_sequence_length = ru->config.prach_config.prach_sequence_length.value;
+
+ int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
rxsigF = ru->prach_rxsigF;
AssertFatal(ru->if_south == LOCAL_RF,"we shouldn't call this if if_south != LOCAL_RF\n");
- for (int aa=0; aanb_rx; aa++)
- prach[aa] = (int16_t*)&ru->common.rxdata[aa][(subframe*fp->samples_per_subframe)-ru->N_TA_offset];
-
+ for (int aa=0; aanb_rx; aa++){
+ if (prach_sequence_length == 0) slot2=(slot/fp->slots_per_subframe)*fp->slots_per_subframe;
+ prach[aa] = (int16_t*)&ru->common.rxdata[aa][(slot2*fp->get_samples_per_slot(slot,fp))-ru->N_TA_offset];
+ }
+ int dftlen=0;
int mu = fp->numerology_index;
- int Ncp;
+ int Ncp = 0;
int16_t *prach2;
-
- switch (prach_fmt) {
- case 0:
- Ncp = 3168;
- break;
-
- case 1:
- Ncp = 21024;
- break;
-
- case 2:
- Ncp = 4688;
- break;
-
- case 3:
- Ncp = 3168;
- break;
-
- case 0xa1:
- Ncp = 288/(1<idx,frame,slot2,prachFormat,msg1_frequencystart);
+ AssertFatal(prachFormat<4,"Illegal prach format %d for length 839\n",prachFormat);
+ switch (prachFormat) {
+ case 0:
+ Ncp = 3168;
+ break;
+
+ case 1:
+ Ncp = 21024;
+ break;
+
+ case 2:
+ Ncp = 4688;
+ break;
+
+ case 3:
+ Ncp = 3168;
+ break;
+
+ }
}
+ else {
+ LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n",
+ ru->idx,frame,slot,prachfmt[prachFormat],msg1_frequencystart,prachStartSymbol);
+ switch (prachFormat) {
+ case 0: //A1
+ Ncp = 288/(1<N_RB_UL, ru->nb_rx, Ncp);
+ LOG_D(PHY,"rx_prach: Doing PRACH FFT for nb_rx:%d Ncp:%d\n",ru->nb_rx, Ncp);
}
AssertFatal(mu==1,"only 30 kHz SCS handled for now\n");
// Note: Assumes PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below
int kbar = 1;
int K = 24;
- if (prach_fmt == 3) {
+ if (prach_sequence_length == 0 && prachFormat == 3) {
K=4;
kbar=10;
}
- else if (prach_fmt > 3) {
+ else if (prach_sequence_length == 1) {
// Note: Assumes that PRACH SCS is same as PUSCH SCS
K=1;
kbar=2;
}
- int n_ra_prb = fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart;
+ int n_ra_prb = msg1_frequencystart;
int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
- int N_ZC = (prach_fmt<4)?839:139;
+ int N_ZC = (prach_sequence_length==0)?839:139;
if (k<0) k+=(fp->ofdm_symbol_size);
k*=K;
k+=kbar;
int reps=1;
- int dftlen=0;
for (int aa=0; aanb_rx; aa++) {
AssertFatal(prach[aa]!=NULL,"prach[%d] is null\n",aa);
-
// do DFT
if (fp->N_RB_UL <= 100)
AssertFatal(1==0,"N_RB_UL %d not support for NR PRACH yet\n",fp->N_RB_UL);
@@ -173,175 +279,232 @@ void rx_nr_prach_ru(RU_t *ru,
if (fp->threequarter_fs==0) {
//40 MHz @ 61.44 Ms/s
//50 MHz @ 61.44 Ms/s
- prach2 = prach[aa] + (Ncp<<2);
- if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2)
- dft(DFT_49152,prach2,rxsigF[aa],1);
- if (prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1);
- reps++;
- }
- if (prach_fmt == 2) {
- dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
- dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
- reps+=2;
- }
- if (prach_fmt == 3) {
- for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
- reps=4;
- }
- if (prach_fmt >3) {
- dft(DFT_2048,prach2,rxsigF[aa],1);
- if (prach_fmt != 0xc0) {
- dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
+ prach2 = prach[aa] + (Ncp<<2); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s
+ if (prach_sequence_length == 0) {
+ if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+ dftlen=49152;
+ dft(DFT_49152,prach2,rxsigF[aa],1);
+ }
+ if (prachFormat == 1 || prachFormat == 2) {
+ dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1);
reps++;
}
- }
- if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
- dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
- dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
- reps+=2;
- }
- if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
- dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
- dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
- reps+=2;
- }
- if (prach_fmt == 0xc2) {
- for (int i=6;i<11;i++) dft(DFT_2048,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
- reps+=6;
+ if (prachFormat == 2) {
+ dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
+ dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
+ reps+=2;
+ }
+ if (prachFormat == 3) {
+ dftlen=12288;
+ for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
+ reps=4;
+ }
+ }// 839 sequence
+ else {
+ if ((mu==0 &&
+ (prachStartSymbol == 0 || prachStartSymbol == 7)) ||
+ (mu==1 && prachStartSymbol == 0)) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+ if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==1) {
+ dftlen=2048;
+ dft(DFT_2048,prach2,rxsigF[aa],1);
+ if (prachFormat != 7) { // !=C0
+ dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
+ reps++;
+ }
+ if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
+ dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
+ dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
+ reps+=2;
+ }
+ if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
+ dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
+ dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
+ reps+=2;
+ }
+ if (prachFormat == 6) {
+ for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1);
+ reps+=6;
+ }
+ }
+ else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
}
- } else {
+ } else { // threequarter sampling
// 40 MHz @ 46.08 Ms/s
- prach2 = prach[aa] + (3*Ncp);
- AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n");
- if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_36864,prach2,rxsigF[aa],1);
- reps++;
- }
- if (prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1);
- reps++;
- }
- if (prach_fmt == 2) {
- dft(DFT_36864,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
- dft(DFT_36864,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
- reps+=2;
- }
- if (prach_fmt == 3) {
- for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
- reps=4;
- }
- if (prach_fmt >3) {
- dft(DFT_1536,prach2,rxsigF[aa],1);
- if (prach_fmt != 0xc0) {
- dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
+ prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q
+ if (prach_sequence_length == 0) {
+ AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n");
+ if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+ dftlen=36864;
+ dft(DFT_36864,prach2,rxsigF[aa],1);
reps++;
}
- }
- if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
- dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
- dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
- reps+=2;
- }
- if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
- dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
- dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
- reps+=2;
- }
- if (prach_fmt == 0xc2) {
- for (int i=6;i<11;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
- reps+=6;
- }
- }
- }
+ if (prachFormat == 1 || prachFormat == 2) {
+ dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1);
+ reps++;
+ }
+ if (prachFormat == 2) {
+ dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1);
+ dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1);
+ reps+=2;
+ }
+ if (prachFormat == 3) {
+ dftlen=9216;
+ for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
+ reps=4;
+ }
+ } else {
+ if ((mu==0 &&
+ (prachStartSymbol == 0 || prachStartSymbol == 7)) ||
+ (mu==1 && prachStartSymbol == 0)) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only)
+ if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==1) {
+ dftlen=1536;
+ dft(DFT_1536,prach2,rxsigF[aa],1);
+ if (prachFormat != 7) {
+ dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
+ reps++;
+ }
+
+ if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
+ dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
+ dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
+ reps+=2;
+ }
+ if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
+ dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
+ dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
+ reps+=2;
+ }
+ if (prachFormat == 6) {
+ for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
+ reps+=6;
+ }
+ }// mu==1
+ else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
+ } // short format
+ } // 3/4 sampling
+ } // <=50 MHz BW
else if (fp->N_RB_UL <= 273) {
if (fp->threequarter_fs==0) {
prach2 = prach[aa] + (Ncp<<3);
- dftlen=98304;
- //80,90,100 MHz @ 61.44 Ms/s
- if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2)
- dft(DFT_98304,prach2,rxsigF[aa],1);
- if (prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
- reps++;
- }
- if (prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
- dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1);
- reps+=2;
- }
- if (prach_fmt == 3) {
- dft(DFT_24576,prach2+(2*49152),rxsigF[aa]+(2*49152),1);
- reps=4;
- dftlen=24576;
- }
- if (prach_fmt >3) {
- dftlen=4096;
- dft(DFT_4096,prach2,rxsigF[aa],1);
- if (prach_fmt != 0xc0) {
- dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
+ //80,90,100 MHz @ 122.88 Ms/s
+
+ if (prach_sequence_length == 0) {
+ if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+ dftlen=98304;
+ dft(DFT_98304,prach2,rxsigF[aa],1);
+ }
+ if (prachFormat == 1 || prachFormat == 2) {
+ dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
reps++;
}
- }
- if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
- dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
- dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
- reps+=2;
- }
- if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
- dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
- dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
- reps+=2;
- }
- if (prach_fmt == 0xc2) {
- for (int i=6;i<11;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
- reps+=6;
+ if (prachFormat == 2) {
+ dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1);
+ dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1);
+ reps+=2;
+ }
+ if (prachFormat == 3) {
+ dftlen=24576;
+ for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1);
+ reps=4;
+ }
+ }
+ else {
+ if ((mu==0 &&
+ (prachStartSymbol == 0 || prachStartSymbol == 7)) ||
+ (mu==1 && prachStartSymbol == 0)) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+ if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==1) {
+ dftlen=4096;
+ dft(DFT_4096,prach2,rxsigF[aa],1);
+ if (prachFormat != 7) { //!=C0
+ dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
+ reps++;
+ }
+
+ if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
+ dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
+ dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
+ reps+=2;
+ }
+ if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
+ dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
+ dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
+ reps+=2;
+ }
+ if (prachFormat == 6) {
+ for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
+ reps+=6;
+ }
+ }
+ else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
}
} else {
AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n");
prach2 = prach[aa] + (6*Ncp);
- // 80 MHz @ 46.08 Ms/s
- dftlen=73728;
- if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_73728,prach2,rxsigF[aa],1);
- reps++;
- }
- if (prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1);
- reps++;
- }
- if (prach_fmt == 3) {
- dft(DFT_73728,prach2+(4*73728),rxsigF[aa]+(4*73728),1);
- reps=4;
- dftlen=18432;
- }
-
- if (prach_fmt >3) {
- dftlen=3072;
- dft(DFT_3072,prach2,rxsigF[aa],1);
- if (prach_fmt != 0xc0) {
- dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
+ // 80 MHz @ 92.16 Ms/s
+ if (prach_sequence_length == 0) {
+ if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+ dftlen=73728;
+ dft(DFT_73728,prach2,rxsigF[aa],1);
reps++;
}
- }
- if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
- dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
- dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
- reps+=2;
- }
- if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
- dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
- dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
- reps+=2;
- }
- if (prach_fmt == 0xc2) {
- for (int i=6;i<11;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
- reps+=6;
+ if (prachFormat == 1 || prachFormat == 2) {
+ dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1);
+ reps++;
+ }
+ if (prachFormat == 3) {
+ dftlen=18432;
+ for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1);
+ reps=4;
+ }
+ } else {
+ if ((mu==0 &&
+ (prachStartSymbol == 0 || prachStartSymbol == 7)) ||
+ (mu==1 && prachStartSymbol == 0)) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+ if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==1) {
+ dftlen=3072;
+ dft(DFT_3072,prach2,rxsigF[aa],1);
+ if (prachFormat != 7) { //!=C0
+ dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
+ reps++;
+ }
+
+ if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
+ dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
+ dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
+ reps+=2;
+ }
+ if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
+ dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
+ dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
+ reps+=2;
+ }
+ if (prachFormat == 6) {
+ for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
+ reps+=6;
+ }
+ }
+ else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
}
}
}
//Coherent combining of PRACH repetitions (assumes channel does not change, to be revisted for "long" PRACH)
+ LOG_D(PHY,"Doing PRACH combining of %d reptitions N_ZC %d\n",reps,N_ZC);
int16_t rxsigF_tmp[N_ZC<<1];
// if (k+N_ZC > dftlen) { // PRACH signal is split around DC
int16_t *rxsigF2=rxsigF[aa];
@@ -350,7 +513,7 @@ void rx_nr_prach_ru(RU_t *ru,
for (int j=0;jgNB_config.prach_config;
NR_DL_FRAME_PARMS *fp;
- lte_frame_type_t frame_type;
+
uint16_t rootSequenceIndex;
- uint8_t prach_ConfigIndex;
- uint8_t Ncs_config;
+ int numrootSequenceIndex;
uint8_t restricted_set;
uint8_t n_ra_prb;
int16_t *prachF=NULL;
@@ -404,59 +568,35 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32)));
int32_t *prach_ifft=(int32_t*)NULL;
- nr_frequency_range_e freq_range;
+ fp = &gNB->frame_parms;
- fp = &gNB->frame_parms;
- nb_rx = fp->nb_antennas_rx;
+ nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value;
- frame_type = fp->frame_type;
- freq_range = fp->freq_range;
- rootSequenceIndex = fp->prach_config_common.rootSequenceIndex;
- prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
- Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
- restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
-
+ rootSequenceIndex = cfg->num_prach_fd_occasions_list[0].prach_root_sequence_index.value;
+ numrootSequenceIndex = cfg->num_prach_fd_occasions_list[0].num_root_sequences.value;
+ NCS = prach_pdu->num_cs;//cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value;
+ int prach_sequence_length = cfg->prach_sequence_length.value;
- uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,frame_type,freq_range);
- uint16_t N_ZC = (prach_fmt <4)?839:139;
+ int msg1_frequencystart = cfg->num_prach_fd_occasions_list[0].k1.value;
+ // int num_unused_root_sequences = cfg->num_prach_fd_occasions_list[0].num_unused_root_sequences.value;
+ // cfg->num_prach_fd_occasions_list[0].unused_root_sequences_list
+
+ restricted_set = cfg->restricted_set_config.value;
+
+ uint8_t prach_fmt = prach_pdu->prach_format;
+ uint16_t N_ZC = (prach_sequence_length==0)?839:139;
+
+ LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d \n", rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC);
prach_ifft = gNB->prach_vars.prach_ifft;
prachF = gNB->prach_vars.prachF;
if (LOG_DEBUGFLAG(PRACH)){
- if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for subframe %d, msg1_frequencystart %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart,prach_ConfigIndex,rootSequenceIndex);
+ if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for subframe %d, msg1_frequencystart %d, rootSequenceIndex %d\n", subframe,msg1_frequencystart,rootSequenceIndex);
}
-
-
-
-
-
- int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME
- if (prach_fmt<3){
- if (restricted_set == 0) {
- NCS = NCS_unrestricted_delta_f_RA_125[Ncs_config];
- } else {
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[Ncs_config]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[Ncs_config]; // for TypeB, this is hardcoded. FIXME
- }
- }
- if (prach_fmt==3){
- if (restricted_set == 0) {
- NCS = NCS_unrestricted_delta_f_RA_5[Ncs_config];
- } else {
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[Ncs_config]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[Ncs_config]; // for TypeB, this is hardcoded. FIXME
- }
- }
- if (prach_fmt>3){
- NCS = NCS_unrestricted_delta_f_RA_15[Ncs_config];
- }
-
- AssertFatal(NCS!=99,"NCS has not been set\n");
-
start_meas(&gNB->rx_prach);
- prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
+ prach_root_sequence_map = (cfg->prach_sequence_length.value==0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
// PDP is oversampled, e.g. 1024 sample instead of 839
// Adapt the NCS (zero-correlation zones) with oversampling factor e.g. 1024/839
@@ -469,16 +609,19 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
*max_preamble_energy=0;
+ *max_preamble_delay=0;
+ *max_preamble=0;
+
for (preamble_index=0 ; preamble_index<64 ; preamble_index++) {
if (LOG_DEBUGFLAG(PRACH)){
int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],(N_ZC==839) ? 840: 140));
- if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d \n",frame,subframe,preamble_index);
+ if (en>60) LOG_D(PHY,"frame %d, subframe %d : Trying preamble %d \n",frame,subframe,preamble_index);
}
if (restricted_set == 0) {
// This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
-
+
if (preamble_offset != preamble_offset_old) {
preamble_offset_old = preamble_offset;
new_dft = 1;
@@ -508,13 +651,6 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
// current root depending on rootSequenceIndex
int index = (rootSequenceIndex + preamble_offset) % N_ZC;
- if (prach_fmt<4) {
- // prach_root_sequence_map points to prach_root_sequence_map0_3
- DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) );
- } else {
- // prach_root_sequence_map points to prach_root_sequence_map4
- DevAssert( index < sizeof(prach_root_sequence_map_abc) / sizeof(prach_root_sequence_map_abc[0]) );
- }
u = prach_root_sequence_map[index];
uint16_t n_group_ra = 0;
@@ -559,14 +695,21 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
// Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex
if (LOG_DEBUGFLAG(PRACH)) {
int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
- if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d, NCS %d, NCS_config %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n",
- frame,subframe,preamble_index,NCS,Ncs_config,N_ZC/NCS,preamble_offset,preamble_shift,en);
+ if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n",
+ frame,subframe,preamble_index,NCS,N_ZC/NCS,preamble_offset,preamble_shift,en);
}
+ LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset);
+
+
if (new_dft == 1) {
new_dft = 0;
Xu=(int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx];
+
+ LOG_D(PHY,"PRACH RX new dft preamble_offset-first_nonzero_root_idx %d\n",preamble_offset-first_nonzero_root_idx);
+
+
memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t));
@@ -590,32 +733,31 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
idft(IDFT_1024,prachF,prach_ifft_tmp,1);
// compute energy and accumulate over receive antennas
for (i=0;i<2048;i++)
- prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[i<<1] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>10;
+ prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10;
} else {
idft(IDFT_256,prachF,prach_ifft_tmp,1);
log2_ifft_size = 8;
// compute energy and accumulate over receive antennas and repetitions for BR
for (i=0;i<256;i++)
- prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[(i<<1)] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>10;
+ prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10;
}
- if (LOG_DUMPFLAG(PRACH)) {
+ if (LOG_DUMPFLAG(PRACH)) {
if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
if (aa==1) LOG_M("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1);
- }
+ }
}// antennas_rx
} // new dft
// check energy in nth time shift, for
preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<*max_preamble_energy) {
+ LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy);
*max_preamble_energy = levdB;
*max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate
*max_preamble = preamble_index;
@@ -623,9 +765,34 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
}
}// preamble_index
+
+ // The conversion from *max_preamble_delay from TA value is done here.
+ // It is normalized to the 30.72 Ms/s, considering the numerology, N_RB and the sampling rate
+ // See table 6.3.3.1 -1 and -2 in 38211.
+
+ // Format 0, 1, 2: 24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s
+ // By solving:
+ // max_preamble_delay * ( (24576*(fs/30.72M)) / 1024 ) / fs = TA * 16 * 64 / 2^mu * Tc
+
+ // Format 3: 6144 samples @ 30.72 Ms/s, 24576 samples @ 122.88 Ms/s
+ // By solving:
+ // max_preamble_delay * ( (6144*(fs/30.72M)) / 1024 ) / fs = TA * 16 * 64 / 2^mu * Tc
+
+ // Format >3: 2048/2^mu samples @ 30.72 Ms/s, 2048/2^mu * 4 samples @ 122.88 Ms/s
+ // By solving:
+ // max_preamble_delay * ( (2048/2^mu*(fs/30.72M)) / 256 ) / fs = TA * 16 * 64 / 2^mu * Tc
+ uint16_t *TA = max_preamble_delay;
+ int mu = fp->numerology_index;
+ if (cfg->prach_sequence_length.value==0) {
+ if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) *TA = *TA*3*(1<60) {
+ //int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
+ // if (en>60) {
int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
if (k<0) k+=fp->ofdm_symbol_size;
@@ -639,9 +806,9 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
LOG_M("Xu.m","xu",Xu,N_ZC,1,1);
LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1);
- }
+ // }
} /* LOG_DUMPFLAG(PRACH) */
- if (gNB) stop_meas(&gNB->rx_prach);
+ stop_meas(&gNB->rx_prach);
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.h b/openair1/PHY/NR_TRANSPORT/nr_prach.h
index 1e2b758035..d158e04c79 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach.h
@@ -37,18 +37,6 @@ uint16_t nr_du[838];
/*************************************
* The following tables defined for NR
**************************************/
-// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
-uint16_t NCS_unrestricted_delta_f_RA_125[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419};
-uint16_t NCS_restricted_TypeA_delta_f_RA_125[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case set Type A
-uint16_t NCS_restricted_TypeB_delta_f_RA_125[13] = {15,18,22,26,32,38,46,55,68,82,100,118,137}; // high-speed case set Type B
-
-// Table 6.3.3.1-6 (38.211) NCS for preamble formats with delta_f_RA = 5 KHz
-uint16_t NCS_unrestricted_delta_f_RA_5[16] = {0,13,26,33,38,41,49,55,64,76,93,119,139,209,279,419};
-uint16_t NCS_restricted_TypeA_delta_f_RA_5[16] = {36,57,72,81,89,94,103,112,121,132,137,152,173,195,216,237}; // high-speed case set Type A
-uint16_t NCS_restricted_TypeB_delta_f_RA_5[14] = {36,57,60,63,65,68,71,77,81,85,97,109,122,137}; // high-speed case set Type B
-
-// Table 6.3.3.1-7 (38.211) NCS for preamble formats with delta_f_RA = 15 * 2mu KHz where mu = {0,1,2,3}
-uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69};
//Table 6.3.3.1-3: Mapping from logical index i to sequence number u for preamble formats with L_RA = 839
uint16_t prach_root_sequence_map_0_3[838] = {
@@ -105,787 +93,3 @@ uint16_t prach_root_sequence_map_abc[138] = {
51, 88 , 52, 87 , 53, 86 , 54, 85 , 55, 84 , 56, 83 , 57, 82 , 58, 81 , 59, 80 , 60, 79 ,
61, 78 , 62, 77 , 63, 76 , 64, 75 , 65, 74 , 66, 73 , 67, 72 , 68, 71 , 69, 70
};
-
-// Table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
-// the column 5, (SFN_nbr is a bitmap where we set bit to '1' in the position of the subframe where the RACH can be sent.
-// E.g. in row 4, and column 5 we have set value 512 ('1000000000') which means RACH can be sent at subframe 9.
-// E.g. in row 20 and column 5 we have set value 66 ('0001000010') which means RACH can be sent at subframe 1 or 6
-int64_t table_6_3_3_2_2_prachConfig_Index [256][9] = {
-//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
-{0, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{0, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{0, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{0, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{0, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{0, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{0, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{0, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{0, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{0, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{0, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{0, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
-{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
-{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
-{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
-{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
-{0, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
-{0, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
-{0, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9
-{0, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8
-{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9
-{0, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{1, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{1, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{1, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{1, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{1, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{1, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{1, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{1, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{1, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{1, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{1, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{1, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{1, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{1, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
-{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
-{1, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
-{1, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
-{1, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
-{1, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
-{1, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
-{1, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3,6,9
-{2, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{2, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{2, -1, 4, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{2, -1, 2, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{2, -1, 2, 0, 32, 0, -1, -1, 0}, // (subframe number) 5
-{2, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{2, -1, 1, 0, 32, 0, -1, -1, 0}, // (subframe number) 5
-{3, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{3, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{3, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{3, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{3, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{3, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{3, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{3, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{3, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{3, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{3, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{3, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
-{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
-{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
-{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
-{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
-{3, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
-{3, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
-{3, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9
-{3, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8
-{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9
-{3, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xa1, -1, 16, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 16, 1, 16, 0, 2, 6, 2}, // (subframe number) 4
-{0xa1, -1, 8, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 8, 1, 16, 0, 2, 6, 2}, // (subframe number) 4
-{0xa1, -1, 4, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 4, 1, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 4, 0, 16, 0, 2, 6, 2}, // (subframe number) 4
-{0xa1, -1, 2, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 2, 0, 2, 0, 2, 6, 2}, // (subframe number) 1
-{0xa1, -1, 2, 0, 16, 0, 2, 6, 2}, // (subframe number) 4
-{0xa1, -1, 2, 0, 128, 0, 2, 6, 2}, // (subframe number) 7
-{0xa1, -1, 1, 0, 16, 0, 1, 6, 2}, // (subframe number) 4
-{0xa1, -1, 1, 0, 66, 0, 1, 6, 2}, // (subframe number) 1,6
-{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 1, 0, 2, 0, 2, 6, 2}, // (subframe number) 1
-{0xa1, -1, 1, 0, 128, 0, 2, 6, 2}, // (subframe number) 7
-{0xa1, -1, 1, 0, 132, 0, 2, 6, 2}, // (subframe number) 2,7
-{0xa1, -1, 1, 0, 146, 0, 2, 6, 2}, // (subframe number) 1,4,7
-{0xa1, -1, 1, 0, 341, 0, 2, 6, 2}, // (subframe number) 0,2,4,6,8
-{0xa1, -1, 1, 0, 1023, 0, 2, 6, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xa1, -1, 1, 0, 682, 0, 2, 6, 2}, // (subframe number) 1,3,5,7,9
-{0xa1, 0xb1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xa1, 0xb1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xa1, 0xb1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
-{0xa1, 0xb1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
-{0xa1, 0xb1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xa1, 0xb1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
-{0xa1, 0xb1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
-{0xa1, 0xb1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
-{0xa1, 0xb1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
-{0xa2, -1, 16, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
-{0xa2, -1, 16, 1, 16, 0, 2, 3, 4}, // (subframe number) 4
-{0xa2, -1, 8, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
-{0xa2, -1, 8, 1, 16, 0, 2, 3, 4}, // (subframe number) 4
-{0xa2, -1, 4, 0, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
-{0xa2, -1, 4, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
-{0xa2, -1, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
-{0xa2, -1, 2, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
-{0xa2, -1, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
-{0xa2, -1, 2, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
-{0xa2, -1, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4
-{0xa2, -1, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6
-{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9
-{0xa2, -1, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
-{0xa2, -1, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
-{0xa2, -1, 1, 0, 132, 0, 2, 3, 4}, // (subframe number) 2,7
-{0xa2, -1, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7
-{0xa2, -1, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8
-{0xa2, -1, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xa2, -1, 1, 0, 682, 0, 2, 3, 4}, // (subframe number) 1,3,5,7,9
-{0xa2, 0xb2, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
-{0xa2, 0xb2, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
-{0xa2, 0xb2, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4
-{0xa2, 0xb2, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6
-{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9
-{0xa2, 0xb2, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
-{0xa2, 0xb2, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
-{0xa2, 0xb2, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7
-{0xa2, 0xb2, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8
-{0xa2, 0xb2, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xa3, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xa3, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xa3, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xa3, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xa3, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xa3, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xa3, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
-{0xa3, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
-{0xa3, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xa3, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
-{0xa3, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
-{0xa3, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
-{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xa3, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
-{0xa3, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
-{0xa3, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7
-{0xa3, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
-{0xa3, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
-{0xa3, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xa3, -1, 1, 0, 682, 0, 2, 2, 6}, // (subframe number) 1,3,5,7,9
-{0xa3, 0xb3, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
-{0xa3, 0xb3, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xa3, 0xb3, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
-{0xa3, 0xb3, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
-{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xa3, 0xb3, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
-{0xa3, 0xb3, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
-{0xa3, 0xb3, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
-{0xa3, 0xb3, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
-{0xa3, 0xb3, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xb1, -1, 16, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 16, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xb1, -1, 8, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xb1, -1, 4, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xb1, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
-{0xb1, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xb1, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
-{0xb1, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
-{0xb1, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
-{0xb1, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
-{0xb1, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
-{0xb1, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7
-{0xb1, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
-{0xb1, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
-{0xb1, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xb1, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9
-{0xb4, -1, 16, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 16, 1, 16, 0, 2, 1, 12}, // (subframe number) 4
-{0xb4, -1, 8, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 8, 1, 16, 0, 2, 1, 12}, // (subframe number) 4
-{0xb4, -1, 4, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 4, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
-{0xb4, -1, 4, 1, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 2, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 2, 0, 2, 0, 2, 1, 12}, // (subframe number) 1
-{0xb4, -1, 2, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
-{0xb4, -1, 2, 0, 128, 0, 2, 1, 12}, // (subframe number) 7
-{0xb4, -1, 1, 0, 2, 0, 2, 1, 12}, // (subframe number) 1
-{0xb4, -1, 1, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
-{0xb4, -1, 1, 0, 128, 0, 2, 1, 12}, // (subframe number) 7
-{0xb4, -1, 1, 0, 66, 0, 2, 1, 12}, // (subframe number) 1,6
-{0xb4, -1, 1, 0, 132, 0, 2, 1, 12}, // (subframe number) 2,7
-{0xb4, -1, 1, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 1, 0, 146, 0, 2, 1, 12}, // (subframe number) 1,4,7
-{0xb4, -1, 1, 0, 341, 0, 2, 1, 12}, // (subframe number) 0,2,4,6,8
-{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xb4, -1, 1, 0, 682, 0, 2, 1, 12}, // (subframe number) 1,3,5,7,9
-{0xc0, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xc0, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xc0, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xc0, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xc0, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
-{0xc0, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xc0, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
-{0xc0, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
-{0xc0, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
-{0xc0, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xc0, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
-{0xc0, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
-{0xc0, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7
-{0xc0, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
-{0xc0, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
-{0xc0, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xc0, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9
-{0xc2, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xc2, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xc2, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xc2, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xc2, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xc2, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xc2, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
-{0xc2, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
-{0xc2, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xc2, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
-{0xc2, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
-{0xc2, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
-{0xc2, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xc2, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
-{0xc2, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
-{0xc2, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7
-{0xc2, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
-{0xc2, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
-{0xc2, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xc2, -1, 1, 0, 682, 0, 2, 2, 6} // (subframe number) 1,3,5,7,9
-};
-// Table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum
-int64_t table_6_3_3_2_3_prachConfig_Index [256][9] = {
-//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
-{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
-{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4)
-{0, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8)
-{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
-{0, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6)
-{0, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5)
-{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
-{0, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3)
-{0, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2)
-{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6)
-{0, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6)
-{0, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9)
-{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8)
-{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7)
-{0, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9)
-{0, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9)
-{0, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9)
-{0, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9)
-{0, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9)
-{0, -1, 1, 0, 960, 0, -1, -1, 0}, // (subrame number 6,7,8,9)
-{0, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9)
-{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9)
-{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
-{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
-{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
-{1, -1, 2, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
-{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
-{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
-{2, -1, 16, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
-{2, -1, 8, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
-{2, -1, 4, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
-{2, -1, 2, 0, 64, 7, -1, -1, 0}, // (subrame number 6)
-{2, -1, 2, 1, 64, 7, -1, -1, 0}, // (subrame number 6)
-{2, -1, 1, 0, 64, 7, -1, -1, 0}, // (subrame number 6)
-{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
-{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4)
-{3, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8)
-{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
-{3, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6)
-{3, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5)
-{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
-{3, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3)
-{3, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2)
-{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6)
-{3, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6)
-{3, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9)
-{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8)
-{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7)
-{3, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9)
-{3, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9)
-{3, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9)
-{3, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9)
-{3, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9)
-{3, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9)
-{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9)
-{0xa1, -1, 16, 1, 512, 0, 2, 6, 2}, // (subrame number 9)
-{0xa1, -1, 8, 1, 512, 0, 2, 6, 2}, // (subrame number 9)
-{0xa1, -1, 4, 1, 512, 0, 1, 6, 2}, // (subrame number 9)
-{0xa1, -1, 2, 1, 512, 0, 1, 6, 2}, // (subrame number 9)
-{0xa1, -1, 2, 1, 528, 7, 1, 3, 2}, // (subrame number 4,9)
-{0xa1, -1, 2, 1, 640, 7, 1, 3, 2}, // (subrame number 7,9)
-{0xa1, -1, 2, 1, 640, 0, 1, 6, 2}, // (subrame number 7,9)
-{0xa1, -1, 2, 1, 768, 0, 2, 6, 2}, // (subrame number 8,9)
-{0xa1, -1, 2, 1, 528, 0, 2, 6, 2}, // (subrame number 4,9)
-{0xa1, -1, 2, 1, 924, 0, 1, 6, 2}, // (subrame number 2,3,4,7,8,9)
-{0xa1, -1, 1, 0, 512, 0, 2, 6, 2}, // (subrame number 9)
-{0xa1, -1, 1, 0, 512, 7, 1, 3, 2}, // (subrame number 9)
-{0xa1, -1, 1, 0, 512, 0, 1, 6, 2}, // (subrame number 9)
-{0xa1, -1, 1, 0, 768, 0, 2, 6, 2}, // (subrame number 8,9)
-{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subrame number 4,9)
-{0xa1, -1, 1, 0, 640, 7, 1, 3, 2}, // (subrame number 7,9)
-{0xa1, -1, 1, 0, 792, 0, 1, 6, 2}, // (subrame number 3,4,8,9)
-{0xa1, -1, 1, 0, 792, 0, 2, 6, 2}, // (subrame number 3,4,8,9)
-{0xa1, -1, 1, 0, 682, 0, 1, 6, 2}, // (subrame number 1,3,5,7,9)
-{0xa1, -1, 1, 0, 1023, 7, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xa2, -1, 16, 1, 512, 0, 2, 3, 4}, // (subrame number 9)
-{0xa2, -1, 8, 1, 512, 0, 2, 3, 4}, // (subrame number 9)
-{0xa2, -1, 4, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
-{0xa2, -1, 2, 1, 640, 0, 1, 3, 4}, // (subrame number 7,9)
-{0xa2, -1, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9)
-{0xa2, -1, 2, 1, 640, 9, 1, 1, 4}, // (subrame number 7,9)
-{0xa2, -1, 2, 1, 528, 9, 1, 1, 4}, // (subrame number 4,9)
-{0xa2, -1, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9)
-{0xa2, -1, 16, 1, 924, 0, 1, 3, 4}, // (subrame number 2,3,4,7,8,9)
-{0xa2, -1, 1, 0, 4, 0, 1, 3, 4}, // (subrame number 2)
-{0xa2, -1, 1, 0, 128, 0, 1, 3, 4}, // (subrame number 7)
-{0xa2, -1, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
-{0xa2, -1, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9)
-{0xa2, -1, 1, 0, 512, 9, 1, 1, 4}, // (subrame number 9)
-{0xa2, -1, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9)
-{0xa2, -1, 1, 0, 132, 0, 1, 3, 4}, // (subrame number 2,7)
-{0xa2, -1, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9)
-{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9)
-{0xa2, -1, 1, 0, 640, 9, 1, 1, 4}, // (subrame number 7,9)
-{0xa2, -1, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9)
-{0xa2, -1, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9)
-{0xa2, -1, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9)
-{0xa2, -1, 1, 0, 1023, 9, 1, 1, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xa3, -1, 16, 1, 512, 0, 2, 2, 6}, // (subrame number 9)
-{0xa3, -1, 8, 1, 512, 0, 2, 2, 6}, // (subrame number 9)
-{0xa3, -1, 4, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
-{0xa3, -1, 2, 1, 528, 7, 1, 1, 6}, // (subrame number 4,9)
-{0xa3, -1, 2, 1, 640, 7, 1, 1, 6}, // (subrame number 7,9)
-{0xa3, -1, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9)
-{0xa3, -1, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9)
-{0xa3, -1, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9)
-{0xa3, -1, 2, 1, 924, 0, 1, 2, 6}, // (subrame number 2,3,4,7,8,9)
-{0xa3, -1, 1, 0, 4, 0, 1, 2, 6}, // (subrame number 2)
-{0xa3, -1, 1, 0, 128, 0, 1, 2, 6}, // (subrame number 7)
-{0xa3, -1, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
-{0xa3, -1, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9)
-{0xa3, -1, 1, 0, 512, 7, 1, 1, 6}, // (subrame number 9)
-{0xa3, -1, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9)
-{0xa3, -1, 1, 0, 132, 0, 1, 2, 6}, // (subrame number 2,7)
-{0xa3, -1, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9)
-{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9)
-{0xa3, -1, 1, 0, 640, 7, 1, 1, 6}, // (subrame number 7,9)
-{0xa3, -1, 1, 0, 792, 0, 1, 2, 6}, // (subrame number 3,4,8,9)
-{0xa3, -1, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9)
-{0xa3, -1, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9)
-{0xa3, -1, 1, 0, 1023, 7, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xb1, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xb1, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xb1, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
-{0xb1, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
-{0xb1, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
-{0xb1, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
-{0xb1, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
-{0xb1, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xb1, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
-{0xb1, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
-{0xb1, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
-{0xb1, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
-{0xb4, -1, 16, 1, 512, 0, 2, 1, 12}, // (subrame number 9)
-{0xb4, -1, 8, 1, 512, 0, 2, 1, 12}, // (subrame number 9)
-{0xb4, -1, 4, 1, 512, 2, 1, 1, 12}, // (subrame number 9)
-{0xb4, -1, 2, 1, 512, 0, 1, 1, 12}, // (subrame number 9)
-{0xb4, -1, 2, 1, 512, 2, 1, 1, 12}, // (subrame number 9)
-{0xb4, -1, 2, 1, 640, 2, 1, 1, 12}, // (subrame number 7,9)
-{0xb4, -1, 2, 1, 528, 2, 1, 1, 12}, // (subrame number 4,9)
-{0xb4, -1, 2, 1, 528, 0, 2, 1, 12}, // (subrame number 4,9)
-{0xb4, -1, 2, 1, 768, 0, 2, 1, 12}, // (subrame number 8,9)
-{0xb4, -1, 2, 1, 924, 0, 1, 1, 12}, // (subrame number 2,3,4,7,8,9)
-{0xb4, -1, 1, 0, 2, 0, 1, 1, 12}, // (subrame number 1)
-{0xb4, -1, 1, 0, 4, 0, 1, 1, 12}, // (subrame number 2)
-{0xb4, -1, 1, 0, 16, 0, 1, 1, 12}, // (subrame number 4)
-{0xb4, -1, 1, 0, 128, 0, 1, 1, 12}, // (subrame number 7)
-{0xb4, -1, 1, 0, 512, 0, 1, 1, 12}, // (subrame number 9)
-{0xb4, -1, 1, 0, 512, 2, 1, 1, 12}, // (subrame number 9)
-{0xb4, -1, 1, 0, 512, 0, 2, 1, 12}, // (subrame number 9)
-{0xb4, -1, 1, 0, 528, 2, 1, 1, 12}, // (subrame number 4,9)
-{0xb4, -1, 1, 0, 640, 2, 1, 1, 12}, // (subrame number 7,9)
-{0xb4, -1, 1, 0, 768, 0, 2, 1, 12}, // (subrame number 8,9)
-{0xb4, -1, 1, 0, 792, 2, 1, 1, 12}, // (subrame number 3,4,8,9)
-{0xb4, -1, 1, 0, 682, 2, 1, 1, 12}, // (subrame number 1,3,5,7,9)
-{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xb4, -1, 1, 0, 1023, 2, 1, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xc0, -1, 16, 1, 512, 2, 2, 6, 2}, // (subrame number 9)
-{0xc0, -1, 8, 1, 512, 2, 2, 6, 2}, // (subrame number 9)
-{0xc0, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xc0, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xc0, -1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9)
-{0xc0, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
-{0xc0, -1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9)
-{0xc0, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
-{0xc0, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
-{0xc0, -1, 2, 1, 924, 2, 1, 6, 2}, // (subrame number 2,3,4,7,8,9)
-{0xc0, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
-{0xc0, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
-{0xc0, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xc0, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
-{0xc0, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
-{0xc0, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
-{0xc0, -1, 1, 0, 792, 2, 1, 6, 2}, // (subrame number 3,4,8,9)
-{0xc0, -1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9)
-{0xc0, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
-{0xc0, -1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xc2, -1, 16, 1, 512, 2, 2, 2, 6}, // (subrame number 9)
-{0xc2, -1, 8, 1, 512, 2, 2, 2, 6}, // (subrame number 9)
-{0xc2, -1, 4, 1, 512, 2, 1, 2, 6}, // (subrame number 9)
-{0xc2, -1, 2, 1, 512, 2, 1, 2, 6}, // (subrame number 9)
-{0xc2, -1, 2, 1, 768, 2, 2, 2, 6}, // (subrame number 8,9)
-{0xc2, -1, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9)
-{0xc2, -1, 2, 1, 640, 8, 1, 1, 6}, // (subrame number 7,9)
-{0xc2, -1, 2, 1, 528, 8, 1, 1, 6}, // (subrame number 4,9)
-{0xc2, -1, 2, 1, 528, 2, 2, 2, 6}, // (subrame number 4,9)
-{0xc2, -1, 2, 1, 924, 2, 1, 2, 6}, // (subrame number 2,3,4,7,8,9)
-{0xc2, -1, 8, 1, 512, 8, 2, 1, 6}, // (subrame number 9)
-{0xc2, -1, 4, 1, 512, 8, 1, 1, 6}, // (subrame number 9)
-{0xc2, -1, 1, 0, 512, 2, 2, 2, 6}, // (subrame number 9)
-{0xc2, -1, 1, 0, 512, 8, 1, 1, 6}, // (subrame number 9)
-{0xc2, -1, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9)
-{0xc2, -1, 1, 0, 768, 2, 2, 2, 6}, // (subrame number 8,9)
-{0xc2, -1, 1, 0, 528, 2, 1, 2, 6}, // (subrame number 4,9)
-{0xc2, -1, 1, 0, 640, 8, 1, 1, 6}, // (subrame number 7,9)
-{0xc2, -1, 1, 0, 792, 2, 1, 2, 6}, // (subrame number 3,4,8,9)
-{0xc2, -1, 1, 0, 792, 2, 2, 2, 6}, // (subrame number 3,4,8,9)
-{0xc2, -1, 1, 0, 682, 2, 1, 2, 6}, // (subrame number 1,3,5,7,9)
-{0xc2, -1, 1, 0, 1023, 8, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xa1, 0xb1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xa1, 0xb1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
-{0xa1, 0xb1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9)
-{0xa1, 0xb1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
-{0xa1, 0xb1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
-{0xa1, 0xb1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9)
-{0xa1, 0xb1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
-{0xa1, 0xb1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
-{0xa1, 0xb1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xa1, 0xb1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
-{0xa1, 0xb1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
-{0xa1, 0xb1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
-{0xa1, 0xb1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9)
-{0xa1, 0xb1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
-{0xa1, 0xb1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xa2, 0xb2, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
-{0xa2, 0xb2, 2, 1, 528, 6, 1, 2, 4}, // (subrame number 4,9)
-{0xa2, 0xb2, 2, 1, 640, 6, 1, 2, 4}, // (subrame number 7,9)
-{0xa2, 0xb2, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9)
-{0xa2, 0xb2, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9)
-{0xa2, 0xb2, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9)
-{0xa2, 0xb2, 1, 0, 512, 6, 1, 2, 4}, // (subrame number 9)
-{0xa2, 0xb2, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9)
-{0xa2, 0xb2, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9)
-{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9)
-{0xa2, 0xb2, 1, 0, 640, 6, 1, 2, 4}, // (subrame number 7,9)
-{0xa2, 0xb2, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9)
-{0xa2, 0xb2, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9)
-{0xa2, 0xb2, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9)
-{0xa2, 0xb2, 1, 0, 1023, 6, 1, 2, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xa3, 0xb3, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
-{0xa3, 0xb3, 2, 1, 528, 2, 1, 2, 6}, // (subrame number 4,9)
-{0xa3, 0xb3, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9)
-{0xa3, 0xb3, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9)
-{0xa3, 0xb3, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9)
-{0xa3, 0xb3, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9)
-{0xa3, 0xb3, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9)
-{0xa3, 0xb3, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9)
-{0xa3, 0xb3, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9)
-{0xa3, 0xb3, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9)
-{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9)
-{0xa3, 0xb3, 1, 0, 640, 2, 1, 2, 6}, // (subrame number 7,9)
-{0xa3, 0xb3, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9)
-{0xa3, 0xb3, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9)
-{0xa3, 0xb3, 1, 0, 1023, 2, 1, 2, 6} // (subrame number 0,1,2,3,4,5,6,7,8,9)
-};
-// Table 6.3.3.2-4: Random access configurations for FR2 and unpaired spectrum
-int64_t table_6_3_3_2_4_prachConfig_Index [256][10] = {
-//format, format, x, y, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
-{0xa1, -1, 16, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 16, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 8, 1, 2, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39)
-{0xa1, -1, 8, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 8, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 4, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 4, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 4, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 2, 1, -1, 551911719040, 0, 2, 6, 2}, // (subframe number :7,15,23,31,39)
-{0xa1, -1, 2, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 2, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 2, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 1, 0, -1, 549756338176, 7, 1, 3, 2}, // (subframe number :19,39)
-{0xa1, -1, 1, 0, -1, 168, 0, 1, 6, 2}, // (subframe number :3,5,7)
-{0xa1, -1, 1, 0, -1, 567489331200, 7, 1, 3, 2}, // (subframe number :24,29,34,39)
-{0xa1, -1, 1, 0, -1, 550293209600, 7, 2, 3, 2}, // (subframe number :9,19,29,39)
-{0xa1, -1, 1, 0, -1, 687195422720, 0, 1, 6, 2}, // (subframe number :17,19,37,39)
-{0xa1, -1, 1, 0, -1, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39)
-{0xa1, -1, 1, 0, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 1, 0, -1, 567489872400, 7, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 1, 0, -1, 10920, 7, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
-{0xa1, -1, 1, 0, -1, 586405642240, 7, 1, 3, 2}, // (subframe number :23,27,31,35,39)
-{0xa1, -1, 1, 0, -1, 551911719040, 0, 1, 6, 2}, // (subframe number :7,15,23,31,39)
-{0xa1, -1, 1, 0, -1, 586405642240, 0, 1, 6, 2}, // (subframe number :23,27,31,35,39)
-{0xa1, -1, 1, 0, -1, 965830828032, 7, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xa1, -1, 1, 0, -1, 586406201480, 7, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 1, 0, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 1, 0, -1, 733007751850, 0, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
-{0xa1, -1, 1, 0, -1, 1099511627775, 7, 1, 3, 2}, // (subframe number :0,1,2,…,39)
-{0xa2, -1, 16, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 16, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 8, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 8, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 8, 1, 2, 550293209600, 0, 2, 3, 4}, // (subframe number :9,19,29,39)
-{0xa2, -1, 4, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 4, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 4, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 2, 1, -1, 551911719040, 0, 2, 3, 4}, // (subframe number :7,15,23,31,39)
-{0xa2, -1, 2, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 2, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 2, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 1, 0, -1, 549756338176, 5, 1, 2, 4}, // (subframe number :19,39)
-{0xa2, -1, 1, 0, -1, 168, 0, 1, 3, 4}, // (subframe number :3,5,7)
-{0xa2, -1, 1, 0, -1, 567489331200, 5, 1, 2, 4}, // (subframe number :24,29,34,39)
-{0xa2, -1, 1, 0, -1, 550293209600, 5, 2, 2, 4}, // (subframe number :9,19,29,39)
-{0xa2, -1, 1, 0, -1, 687195422720, 0, 1, 3, 4}, // (subframe number :17,19,37,39)
-{0xa2, -1, 1, 0, -1, 550293209600, 0, 2, 3, 4}, // (subframe number :9, 19, 29, 39)
-{0xa2, -1, 1, 0, -1, 551911719040, 0, 1, 3, 4}, // (subframe number :7,15,23,31,39)
-{0xa2, -1, 1, 0, -1, 586405642240, 5, 1, 2, 4}, // (subframe number :23,27,31,35,39)
-{0xa2, -1, 1, 0, -1, 586405642240, 0, 1, 3, 4}, // (subframe number :23,27,31,35,39)
-{0xa2, -1, 1, 0, -1, 10920, 5, 1, 2, 4}, // (subframe number :3,5,7,9,11,13)
-{0xa2, -1, 1, 0, -1, 10920, 0, 1, 3, 4}, // (subframe number :3,5,7,9,11,13)
-{0xa2, -1, 1, 0, -1, 567489872400, 5, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 1, 0, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 1, 0, -1, 965830828032, 5, 2, 2, 4}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xa2, -1, 1, 0, -1, 586406201480, 5, 1, 2, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 1, 0, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 1, 0, -1, 733007751850, 0, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39)
-{0xa2, -1, 1, 0, -1, 1099511627775, 5, 1, 2, 4}, // (subframe number :0,1,2,…,39)
-{0xa3, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
-{0xa3, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 1, 0, -1, 549756338176, 7, 1, 1, 6}, // (subframe number :19,39)
-{0xa3, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7)
-{0xa3, -1, 1, 0, -1, 10752, 2, 1, 2, 6}, // (subframe number :9,11,13)
-{0xa3, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39)
-{0xa3, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39)
-{0xa3, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39)
-{0xa3, -1, 1, 0, -1, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
-{0xa3, -1, 1, 0, -1, 551911719040, 0, 1, 2, 6}, // (subframe number :7,15,23,31,39)
-{0xa3, -1, 1, 0, -1, 586405642240, 7, 1, 1, 6}, // (subframe number :23,27,31,35,39)
-{0xa3, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39)
-{0xa3, -1, 1, 0, -1, 10920, 0, 1, 2, 6}, // (subframe number :3,5,7,9,11,13)
-{0xa3, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13)
-{0xa3, -1, 1, 0, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 1, 0, -1, 567489872400, 7, 1, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xa3, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39)
-{0xa3, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39)
-{0xb1, -1, 16, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 8, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 8, 1, 2, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
-{0xb1, -1, 4, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 2, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 2, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb1, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
-{0xb1, -1, 1, 0, -1, 168, 2, 1, 6, 2}, // (subframe number :3,5,7)
-{0xb1, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39)
-{0xb1, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39)
-{0xb1, -1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39)
-{0xb1, -1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
-{0xb1, -1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39)
-{0xb1, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
-{0xb1, -1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39)
-{0xb1, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
-{0xb1, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb1, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xb1, -1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb1, -1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
-{0xb1, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39)
-{0xb4, -1, 16, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 16, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 8, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 8, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 8, 1, 2, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39)
-{0xb4, -1, 4, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 4, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 4, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 2, 1, -1, 551911719040, 2, 2, 1, 12}, // (subframe number :7,15,23,31,39)
-{0xb4, -1, 2, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 2, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 2, 1, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 1, 0, -1, 549756338176, 2, 2, 1, 12}, // (subframe number :19, 39)
-{0xb4, -1, 1, 0, -1, 687195422720, 0, 1, 1, 12}, // (subframe number :17, 19, 37, 39)
-{0xb4, -1, 1, 0, -1, 567489331200, 2, 1, 1, 12}, // (subframe number :24,29,34,39)
-{0xb4, -1, 1, 0, -1, 550293209600, 2, 2, 1, 12}, // (subframe number :9,19,29,39)
-{0xb4, -1, 1, 0, -1, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39)
-{0xb4, -1, 1, 0, -1, 551911719040, 0, 1, 1, 12}, // (subframe number :7,15,23,31,39)
-{0xb4, -1, 1, 0, -1, 551911719040, 0, 2, 1, 12}, // (subframe number :7,15,23,31,39)
-{0xb4, -1, 1, 0, -1, 586405642240, 0, 1, 1, 12}, // (subframe number :23,27,31,35,39)
-{0xb4, -1, 1, 0, -1, 586405642240, 2, 2, 1, 12}, // (subframe number :23,27,31,35,39)
-{0xb4, -1, 1, 0, -1, 698880, 0, 1, 1, 12}, // (subframe number :9,11,13,15,17,19)
-{0xb4, -1, 1, 0, -1, 10920, 2, 1, 1, 12}, // (subframe number :3,5,7,9,11,13)
-{0xb4, -1, 1, 0, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 1, 0, -1, 567489872400, 2, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 1, 0, -1, 965830828032, 2, 2, 1, 12}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xb4, -1, 1, 0, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 1, 0, -1, 586406201480, 2, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 1, 0, -1, 44739240, 2, 1, 1, 12}, // (subframe number :3, 5, 7, …, 23,25)
-{0xb4, -1, 1, 0, -1, 44739240, 0, 2, 1, 12}, // (subframe number :3, 5, 7, …, 23,25)
-{0xb4, -1, 1, 0, -1, 733007751850, 0, 1, 1, 12}, // (subframe number :1,3,5,7,…,37,39)
-{0xb4, -1, 1, 0, -1, 1099511627775, 2, 1, 1, 12}, // (subframe number :0, 1, 2,…, 39)
-{0xc0, -1, 16, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 16, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 8, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 8, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 8, 1, 2, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39)
-{0xc0, -1, 4, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 4, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 4, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 2, 1, -1, 551911719040, 0, 2, 7, 2}, // (subframe number :7,15,23,31,39)
-{0xc0, -1, 2, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 2, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 2, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
-{0xc0, -1, 1, 0, -1, 168, 0, 1, 7, 2}, // (subframe number :3,5,7)
-{0xc0, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39)
-{0xc0, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39)
-{0xc0, -1, 1, 0, -1, 687195422720, 0, 1, 7, 2}, // (subframe number :17,19,37,39)
-{0xc0, -1, 1, 0, -1, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39)
-{0xc0, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
-{0xc0, -1, 1, 0, -1, 551911719040, 0, 1, 7, 2}, // (subframe number :7,15,23,31,39)
-{0xc0, -1, 1, 0, -1, 586405642240, 0, 1, 7, 2}, // (subframe number :23,27,31,35,39)
-{0xc0, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
-{0xc0, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 1, 0, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xc0, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 1, 0, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 1, 0, -1, 733007751850, 0, 1, 7, 2}, // (subframe number :1,3,5,7,…,37,39)
-{0xc0, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39)
-{0xc2, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
-{0xc2, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 2, 1, -1, 551911719040, 2, 2, 2, 6}, // (subframe number :7,15,23,31,39)
-{0xc2, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39)
-{0xc2, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7)
-{0xc2, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39)
-{0xc2, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39)
-{0xc2, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39)
-{0xc2, -1, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39)
-{0xc2, -1, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39)
-{0xc2, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13)
-{0xc2, -1, 1, 0, -1, 586405642240, 7, 2, 1, 6}, // (subframe number :23,27,31,35,39)
-{0xc2, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39)
-{0xc2, -1, 1, 0, -1, 567489872400, 7, 2, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xc2, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39)
-{0xc2, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39)
-{0xa1, 0xb1, 16, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 16, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, 0xb1, 8, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 8, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, 0xb1, 4, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 4, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, 0xb1, 2, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
-{0xa1, 0xb1, 1, 0, -1, 550293209600, 8, 1, 3, 2}, // (subframe number :9,19,29,39)
-{0xa1, 0xb1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39)
-{0xa1, 0xb1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
-{0xa1, 0xb1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
-{0xa1, 0xb1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39)
-{0xa1, 0xb1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39)
-{0xa1, 0xb1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, 0xb1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
-{0xa2, 0xb2, 16, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 16, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, 0xb2, 8, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 8, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, 0xb2, 4, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 4, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, 0xb2, 2, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 1, 0, -1, 549756338176, 6, 1, 2, 4}, // (subframe number :19,39)
-{0xa2, 0xb2, 1, 0, -1, 550293209600, 6, 1, 2, 4}, // (subframe number :9,19,29,39)
-{0xa2, 0xb2, 1, 0, -1, 687195422720, 2, 1, 3, 4}, // (subframe number :17,19,37,39)
-{0xa2, 0xb2, 1, 0, -1, 550293209600, 2, 2, 3, 4}, // (subframe number :9,19,29,39)
-{0xa2, 0xb2, 1, 0, -1, 586405642240, 6, 1, 2, 4}, // (subframe number :23,27,31,35,39)
-{0xa2, 0xb2, 1, 0, -1, 551911719040, 2, 1, 3, 4}, // (subframe number :7,15,23,31,39)
-{0xa2, 0xb2, 1, 0, -1, 586405642240, 2, 1, 3, 4}, // (subframe number :23,27,31,35,39)
-{0xa2, 0xb2, 1, 0, -1, 567489872400, 6, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 1, 0, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 1, 0, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, 0xb2, 1, 0, -1, 733007751850, 2, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39)
-{0xa3, 0xb3, 16, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 16, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, 0xb3, 8, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 8, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, 0xb3, 4, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 4, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, 0xb3, 2, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39)
-{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 1, 2, 6}, // (subframe number :9,19,29,39)
-{0xa3, 0xb3, 1, 0, -1, 687195422720, 2, 1, 2, 6}, // (subframe number :17,19,37,39)
-{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39)
-{0xa3, 0xb3, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39)
-{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 1, 2, 6}, // (subframe number :23,27,31,35,39)
-{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 2, 2, 6}, // (subframe number :23,27,31,35,39)
-{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 1, 0, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, 0xb3, 1, 0, -1, 733007751850, 2, 1, 2, 6} // (subframe number :1,3,5,7,…,37,39)
-};
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
index e1b80a87a2..a95c519d43 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
@@ -34,15 +34,15 @@
#include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/NR_TRANSPORT/nr_prach.h"
-#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h"
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
-
+#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "T.h"
-void init_nr_prach_tables(int N_ZC);
-void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe) {
+
+/*void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe) {
FILE *fd;
@@ -76,23 +76,13 @@ void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe) {
fprintf(fd,"prach_config: n_ra_prboffset = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.msg1_frequencystart);
fclose(fd);
-}
+}*/
// This function computes the du
-void nr_fill_du(uint8_t prach_fmt)
+void nr_fill_du(uint16_t N_ZC,uint16_t *prach_root_sequence_map)
{
uint16_t iu,u,p;
- uint16_t N_ZC;
- uint16_t *prach_root_sequence_map;
-
- if (prach_fmt<4) {
- N_ZC = 839;
- prach_root_sequence_map = prach_root_sequence_map_0_3;
- } else {
- N_ZC = 139;
- prach_root_sequence_map = prach_root_sequence_map_abc;
- }
for (iu=0; iu<(N_ZC-1); iu++) {
@@ -107,214 +97,49 @@ void nr_fill_du(uint8_t prach_fmt)
}
-int is_nr_prach_subframe(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe) {
-
- uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
- /*
- // For FR1 paired
- if (((frame%table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][2]) == table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][3]) &&
- ((table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][4]&(1<slots_per_subframe;
- // when were in the last slot of the subframe and this is a PRACH subframe ,return 1
- if (((slot%fp->slots_per_subframe) == fp->slots_per_subframe-1)&&
- (is_nr_prach_subframe(fp,frame,subframe))) return (1);
- else return(0);
-}
-
-uint16_t get_nr_prach_fmt(int prach_ConfigIndex,lte_frame_type_t frame_type, nr_frequency_range_e fr)
-{
-
- if (frame_type==FDD) return (table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][0]); // if using table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
- else if (fr==nr_FR1) return (table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][0]); // if using table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum
- else AssertFatal(1==0,"FR2 prach configuration not supported yet\n");
- // For FR2 not implemented. FIXME
-}
-
-void compute_nr_prach_seq(uint16_t rootSequenceIndex,
- uint8_t prach_ConfigIndex,
- uint8_t zeroCorrelationZoneConfig,
- uint8_t highSpeedFlag,
- lte_frame_type_t frame_type,
- nr_frequency_range_e fr,
- uint32_t X_u[64][839])
-{
+void compute_nr_prach_seq(uint8_t short_sequence,
+ uint8_t num_sequences,
+ uint8_t rootSequenceIndex,
+ uint32_t X_u[64][839]){
// Compute DFT of x_u => X_u[k] = x_u(inv(u)*k)^* X_u[k] = exp(j\pi u*inv(u)*k*(inv(u)*k+1)/N_ZC)
- unsigned int k,inv_u,i,NCS=0,num_preambles;
+ unsigned int k,inv_u,i;
int N_ZC;
- uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,frame_type,fr);
+
uint16_t *prach_root_sequence_map;
- uint16_t u, preamble_offset;
- uint16_t n_shift_ra,n_shift_ra_bar, d_start,numshift;
- uint8_t not_found;
+ uint16_t u;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_COMPUTE_PRACH, VCD_FUNCTION_IN);
-#ifdef NR_PRACH_DEBUG
- LOG_I(PHY,"compute_prach_seq: NCS_config %d, prach_fmt %x\n",zeroCorrelationZoneConfig, prach_fmt);
-#endif
+ LOG_D(PHY,"compute_prach_seq: prach short sequence %x, num_sequences %d, rootSequenceIndex %d\n", short_sequence, num_sequences, rootSequenceIndex);
-
- N_ZC = (prach_fmt < 4) ? 839 : 139;
+ N_ZC = (short_sequence) ? 139 : 839;
//init_prach_tables(N_ZC); //moved to phy_init_lte_ue/eNB, since it takes to long in real-time
init_nr_prach_tables(N_ZC);
- if (prach_fmt < 4) {
- prach_root_sequence_map = prach_root_sequence_map_0_3;
- } else {
+ if (short_sequence) {
// FIXME cannot be reached
prach_root_sequence_map = prach_root_sequence_map_abc;
- }
-
-
-#ifdef PRACH_DEBUG
- LOG_I( PHY, "compute_prach_seq: done init prach_tables\n" );
-#endif
-
-
-
-
- int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME
-
- if (highSpeedFlag== 0) {
-
-#ifdef PRACH_DEBUG
- LOG_I(PHY,"Low speed prach : NCS_config %d\n",zeroCorrelationZoneConfig);
-#endif
-
- AssertFatal(zeroCorrelationZoneConfig<=15,
- "FATAL, Illegal Ncs_config for unrestricted format %"PRIu8"\n", zeroCorrelationZoneConfig );
- if (prach_fmt<3) NCS = NCS_unrestricted_delta_f_RA_125[zeroCorrelationZoneConfig];
- if (prach_fmt==3) NCS = NCS_unrestricted_delta_f_RA_5[zeroCorrelationZoneConfig];
- if (prach_fmt>3) NCS = NCS_unrestricted_delta_f_RA_15[zeroCorrelationZoneConfig];
-
- num_preambles = (NCS==0) ? 64 : ((64*NCS)/N_ZC);
-
- if (NCS>0) num_preambles++;
-
- preamble_offset = 0;
} else {
-
-#ifdef PRACH_DEBUG
- LOG_I( PHY, "high speed prach : NCS_config %"PRIu8"\n", zeroCorrelationZoneConfig );
-#endif
-
- AssertFatal(zeroCorrelationZoneConfig<=14,
- "FATAL, Illegal Ncs_config for restricted format %"PRIu8"\n", zeroCorrelationZoneConfig );
- if (prach_fmt<3){
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[zeroCorrelationZoneConfig]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[zeroCorrelationZoneConfig]; // for TypeB, this is hardcoded. FIXME
- }
- if (prach_fmt==3){
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[zeroCorrelationZoneConfig]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[zeroCorrelationZoneConfig]; // for TypeB, this is hardcoded. FIXME
- }
- if (prach_fmt>3){
-
- }
-
- nr_fill_du(prach_fmt);
-
- num_preambles = 64; // compute ZC sequence for 64 possible roots
- // find first non-zero shift root (stored in preamble_offset)
- not_found = 1;
- preamble_offset = 0;
-
- while (not_found == 1) {
- // current root depending on rootSequenceIndex
- int index = (rootSequenceIndex + preamble_offset) % N_ZC;
-
- if (prach_fmt<4) {
- // prach_root_sequence_map points to prach_root_sequence_map0_3
- DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) );
- } else {
- // prach_root_sequence_map points to prach_root_sequence_map4
- DevAssert( index < sizeof(prach_root_sequence_map_abc) / sizeof(prach_root_sequence_map_abc[0]) );
- }
-
- u = prach_root_sequence_map[index];
-
- uint16_t n_group_ra = 0;
-
- if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) {
- n_shift_ra = nr_du[u]/NCS;
- d_start = (nr_du[u]<<1) + (n_shift_ra * NCS);
- n_group_ra = N_ZC/d_start;
- n_shift_ra_bar = max(0,(N_ZC-(nr_du[u]<<1)-(n_group_ra*d_start))/N_ZC);
- } else if ( (nr_du[u]>=(N_ZC/3)) && (nr_du[u]<=((N_ZC - NCS)>>1)) ) {
- n_shift_ra = (N_ZC - (nr_du[u]<<1))/NCS;
- d_start = N_ZC - (nr_du[u]<<1) + (n_shift_ra * NCS);
- n_group_ra = nr_du[u]/d_start;
- n_shift_ra_bar = min(n_shift_ra,max(0,(nr_du[u]- (n_group_ra*d_start))/NCS));
- } else {
- n_shift_ra = 0;
- n_shift_ra_bar = 0;
- }
-
- // This is the number of cyclic shifts for the current root u
- numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar;
-
- // skip to next root and recompute parameters if numshift==0
- if (numshift>0)
- not_found = 0;
- else
- preamble_offset++;
- }
+ prach_root_sequence_map = prach_root_sequence_map_0_3;
}
-#ifdef PRACH_DEBUG
+ LOG_D( PHY, "compute_prach_seq: done init prach_tables\n" );
- if (NCS>0)
- LOG_I( PHY, "Initializing %u preambles for PRACH (NCS_config %"PRIu8", NCS %u, N_ZC/NCS %u)\n",
- num_preambles, zeroCorrelationZoneConfig, NCS, N_ZC/NCS );
+ for (i=0; i u=%d\n",index,u);
inv_u = nr_ZC_inv[u]; // multiplicative inverse of u
@@ -322,8 +147,8 @@ void compute_nr_prach_seq(uint16_t rootSequenceIndex,
// for the unrestricted case X_u[0] is the first root indicated by the rootSequenceIndex
for (k=0; k
-#include "nfapi_interface.h"
-
-// Functions below implement 36-211 and 36-212
-
-/** @addtogroup _PHY_TRANSPORT_
- * @{
- */
-
-void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
-
-int rx_pmch(PHY_VARS_NR_UE *phy_vars_ue,
- unsigned char eNB_id,
- uint8_t subframe,
- unsigned char symbol);
-
-/** \brief Dump OCTAVE/MATLAB files for PMCH debugging
- @param phy_vars_ue Pointer to UE variables
- @param eNB_id index of eNB in ue variables
- @param coded_bits_per_codeword G from 36.211
- @param subframe Index of subframe
- @returns 0 on success
-*/
-void dump_mch(PHY_VARS_NR_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe);
-
-
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qpsk_qpsk(int16_t *stream0_in,
- int16_t *stream1_in,
- int16_t *stream0_out,
- int16_t *rho01,
- int32_t length);
-
-/** \brief This function perform LLR computation for dual-stream (QPSK/QPSK) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr128p pointer to pointer to symbol in dlsch_llr*/
-int32_t nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- int32_t **rho_i,
- int16_t *dlsch_llr,
- uint8_t symbol,
- uint32_t len,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint16_t pbch_pss_sss_adj,
- int16_t **llr128p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/16QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qpsk_qam16(int16_t *stream0_in,
- int16_t *stream1_in,
- short *ch_mag_i,
- int16_t *stream0_out,
- int16_t *rho01,
- int32_t length);
-
-/** \brief This function perform LLR computation for dual-stream (QPSK/16QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr128p pointer to pointer to symbol in dlsch_llr*/
-int32_t nr_dlsch_qpsk_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
- int32_t **rho_i,
- int16_t *dlsch_llr,
- uint8_t symbol,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint16_t pbch_pss_sss_adj,
- int16_t **llr128p);
-
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/64QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qpsk_qam64(int16_t *stream0_in,
- int16_t *stream1_in,
- short *ch_mag_i,
- int16_t *stream0_out,
- int16_t *rho01,
- int32_t length);
-
-/** \brief This function perform LLR computation for dual-stream (QPSK/64QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr128p pointer to pointer to symbol in dlsch_llr*/
-int32_t nr_dlsch_qpsk_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
- int32_t **rho_i,
- int16_t *dlsch_llr,
- uint8_t symbol,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint16_t pbch_pss_sss_adj,
- int16_t **llr128p);
-
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 16QAM/QPSK reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam16_qpsk(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *stream0_out,
- short *rho01,
- int length);
-/** \brief This function perform LLR computation for dual-stream (16QAM/QPSK) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_16qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- short **llr16p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 16QAM/16QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam16_qam16(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *ch_mag_i,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function perform LLR computation for dual-stream (16QAM/16QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
- int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- uint32_t len,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- short **llr16p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 16QAM/64QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam16_qam64(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *ch_mag_i,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function perform LLR computation for dual-stream (16QAM/64QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_16qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
- int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- short **llr16p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/64QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam64_qpsk(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function perform LLR computation for dual-stream (64QAM/64QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_64qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag,
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- short **llr16p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/16QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam64_qam16(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *ch_mag_i,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/16QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam64_qam16_avx2(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *ch_mag_i,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function perform LLR computation for dual-stream (64QAM/16QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_64qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag,
- int **dl_ch_mag_i,
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- short **llr16p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/64QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam64_qam64(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *ch_mag_i,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/64QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam64_qam64_avx2(int32_t *stream0_in,
- int32_t *stream1_in,
- int32_t *ch_mag,
- int32_t *ch_mag_i,
- int16_t *stream0_out,
- int32_t *rho01,
- int length);
-
-/** \brief This function perform LLR computation for dual-stream (64QAM/64QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag,
- int **dl_ch_mag_i,
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- uint32_t len,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- //short **llr16p,
- uint32_t llr_offset);
-
-
-/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr128p pointer to pointer to symbol in dlsch_llr
- @param beamforming_mode beamforming mode
-*/
-int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int16_t *dlsch_llr,
- uint8_t symbol,
- uint32_t len,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint8_t beamforming_mode);
-
-/**
- \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param dlsch_llr llr output
- @param dl_ch_mag Squared-magnitude of channel in each resource element position corresponding to allocation and weighted for mid-point in 16QAM constellation
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adjust Adjustment factor in RE for PBCH/PSS/SSS allocations
- @param llr128p pointer to pointer to symbol in dlsch_llr
- @param beamforming_mode beamforming mode
-*/
-
-int32_t nr_dlsch_qpsk_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int32_t **sic_buffer,
- int **rho_i,
- short *dlsch_llr,
- uint8_t num_pdcch_symbols,
- uint16_t nb_rb,
- uint8_t subframe,
- uint16_t mod_order_0,
- uint32_t rb_alloc);
-
-void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int16_t *dlsch_llr,
- int32_t **dl_ch_mag,
- uint8_t symbol,
- uint32_t len,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- int16_t **llr32p,
- uint8_t beamforming_mode);
-/**
- \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param dlsch_llr llr output
- @param dl_ch_mag Squared-magnitude of channel in each resource element position corresponding to allocation, weighted by first mid-point of 64-QAM constellation
- @param dl_ch_magb Squared-magnitude of channel in each resource element position corresponding to allocation, weighted by second mid-point of 64-QAM constellation
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adjust PBCH/PSS/SSS RE adjustment (in REs)
- @param beamforming_mode beamforming mode
-*/
-void nr_dlsch_16qam_llr_SIC (NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **sic_buffer, //Q15
- int32_t **rho_i,
- int16_t *dlsch_llr,
- uint8_t num_pdcch_symbols,
- int32_t **dl_ch_mag,
- uint16_t nb_rb,
- uint8_t subframe,
- uint16_t mod_order_0,
- uint32_t rb_alloc);
-
-void dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **sic_buffer, //Q15
- int32_t **rho_i,
- int16_t *dlsch_llr,
- uint8_t num_pdcch_symbols,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint16_t nb_rb,
- uint8_t subframe,
- uint16_t mod_order_0,
- uint32_t rb_alloc);
-
-void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int16_t *dlsch_llr,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint32_t len,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint32_t llr_offset,
- uint8_t beamforming_mode);
-
-
-/** \fn dlsch_siso(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- uint8_t l,
- uint16_t nb_rb)
- \brief This function does the first stage of llr computation for SISO, by just extracting the pilots, PBCH and primary/secondary synchronization sequences.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param l symbol in sub-frame
- @param nb_rb Number of RBs in this allocation
-*/
-
-void dlsch_siso(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- uint8_t l,
- uint16_t nb_rb);
-
-/** \fn dlsch_alamouti(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint16_t nb_rb)
- \brief This function does Alamouti combining on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param symbol Symbol in sub-frame
- @param nb_rb Number of RBs in this allocation
-*/
-void dlsch_alamouti(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint16_t nb_rb);
-
-/** \fn dlsch_antcyc(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint16_t nb_rb)
- \brief This function does antenna selection (based on antenna cycling pattern) on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals. Note that this is not LTE, it is just included for comparison purposes.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param symbol Symbol in sub-frame
- @param nb_rb Number of RBs in this allocation
-*/
-void dlsch_antcyc(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint16_t nb_rb);
-
-/** \fn dlsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- int32_t **rho,
- int32_t **rho_i,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint16_t nb_rb,
- uint8_t dual_stream_UE)
-
- \brief This function does maximal-ratio combining for dual-antenna receivers.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param rho Cross correlation between spatial channels
- @param rho_i Cross correlation between signal and inteference channels
- @param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param symbol Symbol in sub-frame
- @param nb_rb Number of RBs in this allocation
- @param dual_stream_UE Flag to indicate dual-stream detection
-*/
-void dlsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- int32_t **rho,
- int32_t **rho_i,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- int32_t **dl_ch_mag_i,
- int32_t **dl_ch_magb_i,
- uint8_t symbol,
- uint16_t nb_rb,
- uint8_t dual_stream_UE);
-
-void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_PDSCH *lte_ue_pdsch_vars,
- int harq_pid,
- int round,
- unsigned char symbol,
- unsigned short nb_rb,
- unsigned char dual_stream_UE);
-
-/** \fn dlsch_extract_rbs_single(int32_t **rxdataF,
- int32_t **dl_ch_estimates,
- int32_t **rxdataF_ext,
- int32_t **dl_ch_estimates_ext,
- uint16_t pmi,
- uint8_t *pmi_ext,
- uint32_t *rb_alloc,
- uint8_t symbol,
- uint8_t subframe,
- NR_DL_FRAME_PARMS *frame_parms)
- \brief This function extracts the received resource blocks, both channel estimates and data symbols,
- for the current allocation and for single antenna eNB transmission.
- @param rxdataF Raw FFT output of received signal
- @param dl_ch_estimates Channel estimates of current slot
- @param rxdataF_ext FFT output for RBs in this allocation
- @param dl_ch_estimates_ext Channel estimates for RBs in this allocation
- @param pmi subband Precoding matrix indicator
- @param pmi_ext Extracted PMI for chosen RBs
- @param rb_alloc RB allocation vector
- @param symbol Symbol to extract
- @param subframe Subframe number
- @param vrb_type Flag to indicate distributed VRB type
- @param high_speed_flag
- @param frame_parms Pointer to frame descriptor
-*/
-/*uint16_t nr_dlsch_extract_rbs_single(int32_t **rxdataF,
- int32_t **dl_ch_estimates,
- int32_t **rxdataF_ext,
- int32_t **dl_ch_estimates_ext,
- uint16_t pmi,
- uint8_t *pmi_ext,
- uint32_t *rb_alloc,
- uint8_t symbol,
- uint8_t subframe,
- uint32_t high_speed_flag,
- NR_DL_FRAME_PARMS *frame_parms);*/
-
-unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
- int **dl_ch_estimates,
- int **rxdataF_ext,
- int **dl_ch_estimates_ext,
- unsigned short pmi,
- unsigned char *pmi_ext,
- unsigned char symbol,
- uint8_t pilots,
- unsigned short start_rb,
- unsigned short nb_pdsch_rb,
- unsigned char nr_tti_rx,
- uint32_t high_speed_flag,
- NR_DL_FRAME_PARMS *frame_parms);
-
-/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF,
- int32_t **dl_ch_estimates,
- int32_t **rxdataF_ext,
- int32_t **dl_ch_estimates_ext,
- uint16_t pmi,
- uint8_t *pmi_ext,
- uint32_t *rb_alloc,
- uint8_t symbol,
- NR_DL_FRAME_PARMS *frame_parms)
- \brief This function extracts the received resource blocks, both channel estimates and data symbols,
- for the current allocation and for dual antenna eNB transmission.
- @param rxdataF Raw FFT output of received signal
- @param dl_ch_estimates Channel estimates of current slot
- @param rxdataF_ext FFT output for RBs in this allocation
- @param dl_ch_estimates_ext Channel estimates for RBs in this allocation
- @param pmi subband Precoding matrix indicator
- @param pmi_ext Extracted PMI for chosen RBs
- @param rb_alloc RB allocation vector
- @param symbol Symbol to extract
- @param subframe Subframe index
- @param high_speed_flag
- @param frame_parms Pointer to frame descriptor
-*/
-unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF,
- int **dl_ch_estimates,
- int **rxdataF_ext,
- int **dl_ch_estimates_ext,
- unsigned short pmi,
- unsigned char *pmi_ext,
- unsigned char symbol,
- uint8_t pilots,
- unsigned short start_rb,
- unsigned short nb_rb_pdsch,
- unsigned char nr_tti_rx,
- uint32_t high_speed_flag,
- NR_DL_FRAME_PARMS *frame_parms,
- MIMO_mode_t mimo_mode);
-
-/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
- int32_t **dl_bf_ch_estimates,
- int32_t **rxdataF_ext,
- int32_t **dl_bf_ch_estimates_ext,
- uint32_t *rb_alloc,
- uint8_t symbol,
- uint8_t subframe,
- uint32_t high_speed_flag,
- NR_DL_FRAME_PARMS *frame_parms)
- \brief This function extracts the received resource blocks, both channel estimates and data symbols,
- for the current allocation and for single antenna eNB transmission.
- @param rxdataF Raw FFT output of received signal
- @param dl_bf_ch_estimates Beamforming channel estimates of current slot
- @param rxdataF_ext FFT output for RBs in this allocation
- @param dl_bf_ch_estimates_ext Beamforming channel estimates for RBs in this allocation
- @param rb_alloc RB allocation vector
- @param symbol Symbol to extract
- @param subframe Subframe number
- @param high_speed_flag
- @param frame_parms Pointer to frame descriptor
-*/
-uint16_t dlsch_extract_rbs_TM7(int32_t **rxdataF,
- int32_t **dl_bf_ch_estimates,
- int32_t **rxdataF_ext,
- int32_t **dl_bf_ch_estimates_ext,
- uint32_t *rb_alloc,
- uint8_t symbol,
- uint8_t subframe,
- uint32_t high_speed_flag,
- NR_DL_FRAME_PARMS *frame_parms);
-
-/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
- @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
- @param dl_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
- @param dl_ch_mag First Channel magnitudes (16QAM/64QAM)
- @param dl_ch_magb Second weighted Channel magnitudes (64QAM)
- @param rxdataF_comp Compensated received waveform
- @param rho Cross-correlation between two spatial channels on each RX antenna
- @param frame_parms Pointer to frame descriptor
- @param symbol Symbol on which to operate
- @param first_symbol_flag set to 1 on first DLSCH symbol
- @param mod_order Modulation order of allocation
- @param nb_rb Number of RBs in allocation
- @param output_shift Rescaling for compensated output (should be energy-normalizing)
- @param phy_measurements Pointer to UE PHY measurements
-*/
-void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
- int32_t **dl_ch_estimates_ext,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- int32_t **rxdataF_comp,
- int32_t **rho,
- NR_DL_FRAME_PARMS *frame_parms,
- uint8_t symbol,
- uint8_t start_symbol,
- uint8_t first_symbol_flag,
- uint8_t mod_order,
- uint16_t nb_rb,
- uint8_t output_shift,
- PHY_NR_MEASUREMENTS *phy_measurements);
-
-void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
- int **dl_ch_estimates_ext,
- int **dl_ch_mag,
- int **dl_ch_magb,
- int **rxdataF_comp,
- int **rho,
- unsigned char n_tx,
- unsigned char n_rx,
- unsigned char mod_order,
- unsigned char output_shift,
- int length,
- 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);
-//This function is used to compute multiplications in Hhermitian * H matrix
-void conjch0_mult_ch1(int *ch0,
- int *ch1,
- int32_t *ch0conj_ch1,
- unsigned short nb_rb,
- unsigned char output_shift0);
-
-void construct_HhH_elements(int *ch0conj_ch0,
- int *ch1conj_ch1,
- int *ch2conj_ch2,
- int *ch3conj_ch3,
- int *ch0conj_ch1,
- int *ch1conj_ch0,
- int *ch2conj_ch3,
- int *ch3conj_ch2,
- int32_t *after_mf_00,
- int32_t *after_mf_01,
- int32_t *after_mf_10,
- int32_t *after_mf_11,
- unsigned short nb_rb);
-
-void squared_matrix_element(int32_t *Hh_h_00,
- int32_t *Hh_h_00_sq,
- unsigned short nb_rb);
-
-void dlsch_channel_level_TM34_meas(int *ch00,
- int *ch01,
- int *ch10,
- int *ch11,
- int *avg_0,
- int *avg_1,
- unsigned short nb_rb);
-
-void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
- int32_t *median,
- int n_tx,
- int n_rx,
- int length,
- int start_point);
-
-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,
- int32_t *after_mf_11,
- int32_t *det_fin_128,
- unsigned short nb_rb);
-
-void numer(int32_t *Hh_h_00_sq,
- int32_t *Hh_h_01_sq,
- int32_t *Hh_h_10_sq,
- int32_t *Hh_h_11_sq,
- int32_t *num_fin,
- unsigned short nb_rb);
-
-uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00,
- int *dl_ch_estimates_01,
- int *dl_ch_estimates_10,
- int *dl_ch_estimates_11,
- unsigned short nb_rb);
-
-void dlsch_channel_compensation_TM56(int **rxdataF_ext,
- int **dl_ch_estimates_ext,
- int **dl_ch_mag,
- int **dl_ch_magb,
- int **rxdataF_comp,
- unsigned char *pmi_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- PHY_NR_MEASUREMENTS *phy_measurements,
- int eNB_id,
- unsigned char symbol,
- unsigned char mod_order,
- unsigned short nb_rb,
- unsigned char output_shift,
- unsigned char dl_power_off);
-
-
-void dlsch_channel_compensation_TM34(NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_PDSCH *lte_ue_pdsch_vars,
- PHY_NR_MEASUREMENTS *phy_measurements,
- int eNB_id,
- unsigned char symbol,
- unsigned char mod_order0,
- unsigned char mod_order1,
- int harq_pid,
- int round,
- MIMO_mode_t mimo_mode,
- unsigned short nb_rb,
- unsigned char output_shift0,
- unsigned char output_shift1);
-
-
-/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal
- @param dl_ch_estimates_ext Channel estimates in allocated RBs
- @param frame_parms Pointer to frame descriptor
- @param avg Pointer to average signal strength
- @param pilots_flag Flag to indicate pilots in symbol
- @param nb_rb Number of allocated RBs
-*/
-void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- int32_t *avg,
- uint8_t symbol,
- uint32_t len,
- unsigned short nb_rb);
-
-
-void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- unsigned char *pmi_ext,
- int *avg_0,
- int *avg_1,
- uint8_t symbol,
- unsigned short nb_rb,
- MIMO_mode_t mimo_mode);
-
-
-void dlsch_channel_level_TM56(int32_t **dl_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- unsigned char *pmi_ext,
- int32_t *avg,
- uint8_t symbol_mod,
- uint16_t nb_rb);
-
-void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- int32_t *avg,
- uint8_t pilots_flag,
- uint16_t nb_rb);
-
-void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_DLSCH_t **dlsch_ue,
- uint8_t symbol,
- uint8_t start_symbol,
- uint16_t nb_rb);
-
-/** \brief This is the top-level entry point for DLSCH decoding in UE. It should be replicated on several
- threads (on multi-core machines) corresponding to different HARQ processes. The routine first
- computes the segmentation information, followed by rate dematching and sub-block deinterleaving the of the
- received LLRs computed by dlsch_demodulation for each transport block segment. It then calls the
- turbo-decoding algorithm for each segment and stops after either after unsuccesful decoding of at least
- one segment or correct decoding of all segments. Only the segment CRCs are check for the moment, the
- overall CRC is ignored. Finally transport block reassembly is performed.
- @param phy_vars_ue Pointer to ue variables
- @param dlsch_llr Pointer to LLR values computed by dlsch_demodulation
- @param lte_frame_parms Pointer to frame descriptor
- @param dlsch Pointer to DLSCH descriptor
- @param frame Frame number
- @param subframe Subframe number
- @param num_pdcch_symbols Number of PDCCH symbols
- @param is_crnti indicates if PDSCH belongs to a CRNTI (necessary for parallelizing decoding threads)
- @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
- @returns 0 on success, 1 on unsuccessful decoding
-*/
-
-uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
- short *dlsch_llr,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_DLSCH_t *dlsch,
- NR_DL_UE_HARQ_t *harq_process,
- uint32_t frame,
- uint16_t nb_symb_sch,
- uint8_t nr_tti_rx,
- uint8_t harq_pid,
- uint8_t is_crnti,
- uint8_t llr8_flag);
-
-uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
- UE_nr_rxtx_proc_t *proc,
- int eNB_id,
- short *dlsch_llr,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_DLSCH_t *dlsch,
- NR_DL_UE_HARQ_t *harq_process,
- uint32_t frame,
- uint16_t nb_symb_sch,
- uint8_t nr_tti_rx,
- uint8_t harq_pid,
- uint8_t is_crnti,
- uint8_t llr8_flag);
-
-void *nr_dlsch_decoding_2thread0(void *arg);
-
-void *nr_dlsch_decoding_2thread1(void *arg);
-
-void nr_dlsch_unscrambling(int16_t* llr,
- uint32_t size,
- uint8_t q,
- uint32_t Nid,
- uint32_t n_RNTI);
-
-uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue,
- uint8_t subframe,
- PDSCH_t dlsch_id,
- uint8_t eNB_id);
-
-/** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation. It performs
- - RB extraction (signal and channel estimates)
- - channel compensation (matched filtering)
- - RE extraction (pilot, PBCH, synch. signals)
- - antenna combining (MRC, Alamouti, cycling)
- - LLR computation
- This function supports TM1, 2, 3, 5, and 6.
- @param PHY_VARS_NR_UE Pointer to PHY variables
- @param type Type of PDSCH (SI_PDSCH,RA_PDSCH,PDSCH,PMCH)
- @param eNB_id eNb index (Nid1) 0,1,2
- @param eNB_id_i Interfering eNB index (Nid1) 0,1,2, or 3 in case of MU-MIMO IC receiver
- @param subframe Subframe number
- @param symbol Symbol on which to act (within sub-frame)
- @param first_symbol_flag set to 1 on first DLSCH symbol
- @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice.
- @param i_mod Modulation order of the interfering stream
-*/
-int32_t nr_rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue,
- PDSCH_t type,
- uint8_t eNB_id,
- uint8_t eNB_id_i,
- uint32_t frame,
- uint8_t subframe,
- uint8_t symbol,
- uint8_t first_symbol_flag,
- RX_type_t rx_type,
- uint8_t i_mod,
- uint8_t harq_pid);
-
-/*! \brief Extract PSS and SSS resource elements
- @param phy_vars_ue Pointer to UE variables
- @param[out] pss_ext contain the PSS signals after the extraction
- @param[out] sss_ext contain the SSS signals after the extraction
- @returns 0 on success
-*/
-int pss_sss_extract(PHY_VARS_NR_UE *phy_vars_ue,
- int32_t pss_ext[4][72],
- int32_t sss_ext[4][72],
- uint8_t subframe);
-
-/*! \brief Extract only PSS resource elements
- @param phy_vars_ue Pointer to UE variables
- @param[out] pss_ext contain the PSS signals after the extraction
- @returns 0 on success
-*/
-int pss_only_extract(PHY_VARS_NR_UE *phy_vars_ue,
- int32_t pss_ext[4][72],
- uint8_t subframe);
-
-/*! \brief Extract only SSS resource elements
- @param phy_vars_ue Pointer to UE variables
- @param[out] sss_ext contain the SSS signals after the extraction
- @returns 0 on success
-*/
-int sss_only_extract(PHY_VARS_NR_UE *phy_vars_ue,
- int32_t sss_ext[4][72],
- uint8_t subframe);
-
-/*! \brief Performs detection of SSS to find cell ID and other framing parameters (FDD/TDD, normal/extended prefix)
- @param phy_vars_ue Pointer to UE variables
- @param tot_metric Pointer to variable containing maximum metric under framing hypothesis (to be compared to other hypotheses
- @param flip_max Pointer to variable indicating if start of frame is in second have of RX buffer (i.e. PSS/SSS is flipped)
- @param phase_max Pointer to variable (0 ... 6) containing rought phase offset between PSS and SSS (can be used for carrier
- frequency adjustment. 0 means -pi/3, 6 means pi/3.
- @returns 0 on success
-*/
-int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uint8_t *phase_max);
-
-/*! \brief receiver for the PBCH
- \returns number of tx antennas or -1 if error
-*/
-int nr_rx_pbch( PHY_VARS_NR_UE *ue,
- UE_nr_rxtx_proc_t *proc,
- NR_UE_PBCH *nr_ue_pbch_vars,
- NR_DL_FRAME_PARMS *frame_parms,
- uint8_t eNB_id,
- uint8_t i_ssb,
- MIMO_mode_t mimo_mode,
- uint32_t high_speed_flag);
-
-int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
- PHY_VARS_NR_UE *ue,
- int pbch_initial_symbol,
- runmode_t mode);
-
-uint16_t rx_pbch_emul(PHY_VARS_NR_UE *phy_vars_ue,
- uint8_t eNB_id,
- uint8_t pbch_phase);
-
-
-/*! \brief PBCH unscrambling
- This is similar to pbch_scrabling with the difference that inputs are signed s16s (llr values) and instead of flipping bits we change signs.
- \param frame_parms Pointer to frame descriptor
- \param llr Output of the demodulator
- \param length Length of the sequence
- \param frame_mod4 Frame number modulo 4*/
-void pbch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
- int8_t* llr,
- uint32_t length,
- uint8_t frame_mod4);
-
-
-void generate_64qam_table(void);
-void generate_16qam_table(void);
-void generate_qpsk_table(void);
-
-uint16_t extract_crc(uint8_t *dci,uint8_t DCI_LENGTH);
-
-/*! \brief LLR from two streams. This function takes two streams (qpsk modulated) and calculates the LLR, considering one stream as interference.
- \param stream0_in pointer to first stream0
- \param stream1_in pointer to first stream1
- \param stream0_out pointer to output stream
- \param rho01 pointer to correlation matrix
- \param length*/
-void qpsk_qpsk_TM3456(short *stream0_in,
- short *stream1_in,
- short *stream0_out,
- short *rho01,
- int length
- );
-
-/** \brief Attempt decoding of a particular DCI with given length and format.
- @param DCI_LENGTH length of DCI in bits
- @param DCI_FMT Format of DCI
- @param e e-sequence (soft bits)
- @param decoded_output Output of Viterbi decoder
-*/
-void dci_decoding(uint8_t DCI_LENGTH,
- uint8_t DCI_FMT,
- int8_t *e,
- uint8_t *decoded_output);
-
-/** \brief Do 36.213 DCI decoding procedure by searching different RNTI options and aggregation levels. Currently does
- not employ the complexity reducing procedure based on RNTI.
- @param phy_vars_ue UE variables
- @param dci_alloc Pointer to DCI_ALLOC_t array to store results for DLSCH/ULSCH programming
- @param do_common If 1 perform search in common search-space else ue-specific search-space
- @param eNB_id eNB Index on which to act
- @param subframe Index of subframe
- @returns bitmap of occupied CCE positions (i.e. those detected)
-*/
-uint16_t dci_decoding_procedure(PHY_VARS_NR_UE *phy_vars_ue,
- DCI_ALLOC_t *dci_alloc,
- int do_common,
- int16_t eNB_id,
- uint8_t subframe);
-
-uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_NR_UE *ue,
- DCI_ALLOC_t *dci_alloc,
- uint8_t DCIFormat,
- uint8_t agregationLevel,
- int16_t eNB_id,
- uint8_t subframe);
-
-uint16_t dci_decoding_procedure_emul(NR_UE_PDCCH **lte_ue_pdcch_vars,
- uint8_t num_ue_spec_dci,
- uint8_t num_common_dci,
- DCI_ALLOC_t *dci_alloc_tx,
- DCI_ALLOC_t *dci_alloc_rx,
- int16_t eNB_id);
-
-/** \brief Compute Q (modulation order) based on I_MCS PDSCH. Implements table 7.1.7.1-1 from 36.213.
- @param I_MCS */
-uint8_t get_Qm(uint8_t I_MCS);
-
-/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213.
- @param I_MCS */
-uint8_t get_Qm_ul(uint8_t I_MCS);
-
-/** \brief Compute I_TBS (transport-block size) based on I_MCS for PDSCH. Implements table 7.1.7.1-1 from 36.213.
- @param I_MCS */
-uint8_t get_I_TBS(uint8_t I_MCS);
-
-/** \brief Compute I_TBS (transport-block size) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213.
- @param I_MCS */
-unsigned char get_I_TBS_UL(unsigned char I_MCS);
-
-/** \brief Compute Q (modulation order) based on downlink I_MCS. Implements table 7.1.7.1-1 from 36.213.
- @param I_MCS
- @param nb_rb
- @return Transport block size */
-uint32_t get_TBS_DL(uint8_t mcs, uint16_t nb_rb);
-
-/** \brief Compute Q (modulation order) based on uplink I_MCS. Implements table 7.1.7.1-1 from 36.213.
- @param I_MCS
- @param nb_rb
- @return Transport block size */
-uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb);
-
-/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type
- @param N_RB_DL number of PRB on DL
- @param indicator for even/odd slot
- @param vrb vrb index
- @param Ngap Gap indicator
-*/
-uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap);
-
-/* \brief Return prb for a given vrb index
- @param vrb_type VRB type (0=localized,1=distributed)
- @param rb_alloc_dci rballoc field from DCI
-*/
-uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci);
-
-
-/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type
- @returns Transmission mode (1-7)
-*/
-uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti);
-
-
-/* \brief
- @param ra_header Header of resource allocation (0,1) (See sections 7.1.6.1/7.1.6.2 of 36.213 Rel8.6)
- @param rb_alloc Bitmap allocation from DCI (format 1,2)
- @returns number of physical resource blocks
-*/
-uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL);
-
-int get_G(NR_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe, uint8_t beamforming_mode);
-
-int adjust_G(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe);
-int adjust_G2(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol);
-
-
-#ifndef modOrder
-#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
-#endif
-
-/** \fn uint8_t I_TBS2I_MCS(uint8_t I_TBS);
- \brief This function maps I_tbs to I_mcs according to Table 7.1.7.1-1 in 3GPP TS 36.213 V8.6.0. Where there is two supported modulation orders for the same I_TBS then either high or low modulation is chosen by changing the equality of the two first comparisons in the if-else statement.
- \param I_TBS Index of Transport Block Size
- \return I_MCS given I_TBS
-*/
-uint8_t I_TBS2I_MCS(uint8_t I_TBS);
-
-/** \fn uint8_t SE2I_TBS(float SE,
- uint8_t N_PRB,
- uint8_t symbPerRB);
- \brief This function maps a requested throughput in number of bits to I_tbs. The throughput is calculated as a function of modulation order, RB allocation and number of symbols per RB. The mapping orginates in the "Transport block size table" (Table 7.1.7.2.1-1 in 3GPP TS 36.213 V8.6.0)
- \param SE Spectral Efficiency (before casting to integer, multiply by 1024, remember to divide result by 1024!)
- \param N_PRB Number of PhysicalResourceBlocks allocated \sa lte_frame_parms->N_RB_DL
- \param symbPerRB Number of symbols per resource block allocated to this channel
- \return I_TBS given an SE and an N_PRB
-*/
-uint8_t SE2I_TBS(float SE,
- uint8_t N_PRB,
- uint8_t symbPerRB);
-/** \brief This function generates the sounding reference symbol (SRS) for the uplink according to 36.211 v8.6.0. If IFFT_FPGA is defined, the SRS is quantized to a QPSK sequence.
- @param frame_parms LTE DL Frame Parameters
- @param soundingrs_ul_config_dedicated Dynamic configuration from RRC during Connection Establishment
- @param txdataF pointer to the frequency domain TX signal
- @returns 0 on success*/
-int generate_srs(NR_DL_FRAME_PARMS *frame_parms,
- SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated,
- int *txdataF,
- int16_t amp,
- uint32_t subframe);
-
-
-/*!
- \brief This function is similar to generate_srs_tx but generates a conjugate sequence for channel estimation. If IFFT_FPGA is defined, the SRS is quantized to a QPSK sequence.
- @param phy_vars_ue Pointer to PHY_VARS structure
- @param eNB_id Index of destination eNB for this SRS
- @param amp Linear amplitude of SRS
- @param subframe Index of subframe on which to act
- @returns 0 on success, -1 on error with message
-*/
-
-int32_t generate_srs_tx(PHY_VARS_NR_UE *phy_vars_ue,
- uint8_t eNB_id,
- int16_t amp,
- uint32_t subframe);
-
-/*!
- \brief This function generates the downlink reference signal for the PUSCH according to 36.211 v8.6.0. The DRS occuies the RS defined by rb_alloc and the symbols 2 and 8 for extended CP and 3 and 10 for normal CP.
-*/
-
-int32_t generate_drs_pusch(PHY_VARS_NR_UE *phy_vars_ue,
- UE_nr_rxtx_proc_t *proc,
- uint8_t eNB_id,
- int16_t amp,
- uint32_t subframe,
- uint32_t first_rb,
- uint32_t nb_rb,
- uint8_t ant);
-
-/*!
- \brief This function initializes the Group Hopping, Sequence Hopping and nPRS sequences for PUCCH/PUSCH according to 36.211 v8.6.0. It should be called after configuration of UE (reception of SIB2/3) and initial configuration of eNB (or after reconfiguration of cell-specific parameters).
- @param frame_parms Pointer to a NR_DL_FRAME_PARMS structure (eNB or UE)*/
-void init_ul_hopping(NR_DL_FRAME_PARMS *frame_parms);
-
-
-/*!
- \brief This function implements the initialization of paging parameters for UE (See Section 7, 36.304).It must be called after setting IMSImod1024 during UE startup and after receiving SIB2
- @param ue Pointer to UE context
- @param defaultPagingCycle T from 36.304 (0=32,1=64,2=128,3=256)
- @param nB nB from 36.304 (0=4T,1=2T,2=T,3=T/2,4=T/4,5=T/8,6=T/16,7=T/32*/
-int init_ue_paging_info(PHY_VARS_NR_UE *ue, long defaultPagingCycle, long nB);
-
-int32_t compareints (const void * a, const void * b);
-
-
-void ulsch_modulation(int32_t **txdataF,
- int16_t amp,
- frame_t frame,
- uint32_t subframe,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_ULSCH_t *ulsch);
-
-
-
-
-
-
-int generate_ue_dlsch_params_from_dci(int frame,
- uint8_t subframe,
- void *dci_pdu,
- rnti_t rnti,
- DCI_format_t dci_format,
- NR_UE_PDCCH *pdcch_vars,
- NR_UE_PDSCH *pdsch_vars,
- NR_UE_DLSCH_t **dlsch,
- NR_DL_FRAME_PARMS *frame_parms,
- PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- uint16_t si_rnti,
- uint16_t ra_rnti,
- uint16_t p_rnti,
- uint8_t beamforming_mode,
- uint16_t tc_rnti);
-
-
-int generate_ue_ulsch_params_from_dci(void *dci_pdu,
- rnti_t rnti,
- uint8_t subframe,
- DCI_format_t dci_format,
- PHY_VARS_NR_UE *phy_vars_ue,
- UE_nr_rxtx_proc_t *proc,
- uint16_t si_rnti,
- uint16_t ra_rnti,
- uint16_t p_rnti,
- uint16_t cba_rnti,
- uint8_t eNB_id,
- uint8_t use_srs);
-
-int32_t generate_ue_ulsch_params_from_rar(PHY_VARS_NR_UE *phy_vars_ue,
- UE_nr_rxtx_proc_t *proc,
- uint8_t eNB_id);
-double sinr_eff_cqi_calc(PHY_VARS_NR_UE *phy_vars_ue,
- uint8_t eNB_id,
- uint8_t subframe);
-
-uint8_t sinr2cqi(double sinr,uint8_t trans_mode);
-
-
-int dump_dci(NR_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci);
-
-int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, char* buffer, int length, runmode_t mode, int input_level_dBm);
-
-void init_transport_channels(uint8_t);
-
-void generate_RIV_tables(void);
-
-/*!
- \brief Encoding of PUSCH/ACK/RI/ACK from 36-212.
- @param a Pointer to ulsch SDU
- @param frame_parms Pointer to Frame parameters
- @param ulsch Pointer to ulsch descriptor
- @param harq_pid HARQ process ID
- @param tmode Transmission mode (1-7)
- @param control_only_flag Generate PUSCH with control information only
- @param Nbundled Parameter for ACK/NAK bundling (36.213 Section 7.3)
-*/
-uint32_t ulsch_encoding(uint8_t *a,
- PHY_VARS_NR_UE *phy_vars_ue,
- uint8_t harq_pid,
- uint8_t eNB_id,
- uint8_t subframe_rx,
- uint8_t tmode,
- uint8_t control_only_flag,
- uint8_t Nbundled);
-
-void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL);
-
-void fill_CQI(NR_UE_ULSCH_t *ulsch,PHY_NR_MEASUREMENTS *meas,uint8_t eNB_id, uint8_t harq_pid,int N_RB_DL, rnti_t rnti, uint8_t trans_mode,double sinr_eff);
-
-void reset_cba_uci(void *o);
-
-/** \brief This routine computes the subband PMI bitmap based on measurements (0,1,2,3 for rank 0 and 0,1 for rank 1) in the format needed for UCI
- @param meas pointer to measurements
- @param eNB_id eNB_id
- @param nb_subbands number of subbands
- @returns subband PMI bitmap
-*/
-uint16_t quantize_subband_pmi(PHY_NR_MEASUREMENTS *meas,uint8_t eNB_id,int nb_subbands);
-
-int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb);
-
-uint16_t quantize_subband_pmi2(PHY_NR_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands);
-
-
-
-uint64_t cqi2hex(uint32_t cqi);
-
-uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
-
-
-/** \brief This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function
- @param N_RB_DL number of resource blocks
- @param mimo_mode
- @param pmi_alloc subband PMI bitmap
- @param rb resource block for which to extract PMI
- @returns subband PMI
-*/
-uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
-
-int get_nCCE_offset_l1(int *CCE_table,
- const unsigned char L,
- const int nCCE,
- const int common_dci,
- const unsigned short rnti,
- const unsigned char subframe);
-
-uint16_t get_nCCE(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi);
-
-uint16_t get_nquad(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi);
-
-uint8_t get_mi(NR_DL_FRAME_PARMS *frame,uint8_t subframe);
-
-uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe);
-
-uint8_t get_num_pdcch_symbols(uint8_t num_dci,DCI_ALLOC_t *dci_alloc,NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
-
-void pdcch_interleaving(NR_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi);
-
-void pdcch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
- uint8_t subframe,
- int8_t* llr,
- uint32_t length);
-
-
-
-void dlsch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
- int mbsfn_flag,
- NR_UE_DLSCH_t *dlsch,
- int G,
- int16_t* llr,
- uint8_t q,
- uint8_t Ns);
-
-void init_ncs_cell(NR_DL_FRAME_PARMS *frame_parms,uint8_t ncs_cell[20][7]);
-
-void generate_pucch1x(int32_t **txdataF,
- NR_DL_FRAME_PARMS *frame_parms,
- uint8_t ncs_cell[20][7],
- PUCCH_FMT_t fmt,
- PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
- uint16_t n1_pucch,
- uint8_t shortened_format,
- uint8_t *payload,
- int16_t amp,
- uint8_t subframe);
-
-void generate_pucch2x(int32_t **txdataF,
- NR_DL_FRAME_PARMS *fp,
- uint8_t ncs_cell[20][7],
- PUCCH_FMT_t fmt,
- PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
- uint16_t n2_pucch,
- uint8_t *payload,
- int A,
- int B2,
- int16_t amp,
- uint8_t subframe,
- uint16_t rnti);
-
-void generate_pucch3x(int32_t **txdataF,
- NR_DL_FRAME_PARMS *frame_parms,
- uint8_t ncs_cell[20][7],
- PUCCH_FMT_t fmt,
- PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
- uint16_t n3_pucch,
- uint8_t shortened_format,
- uint8_t *payload,
- int16_t amp,
- uint8_t subframe,
- uint16_t rnti);
-
-
-void init_ulsch_power_LUT(void);
-
-/*!
- \brief Check for PRACH TXop in subframe
- @param frame_parms Pointer to NR_DL_FRAME_PARMS
- @param frame frame index to check
- @param subframe subframe index to check
- @returns 0 on success
-*/
-int is_prach_subframe(NR_DL_FRAME_PARMS *frame_parms,frame_t frame, uint8_t subframe);
-
-/*!
- \brief Generate PRACH waveform
- @param phy_vars_ue Pointer to ue top-level descriptor
- @param eNB_id Index of destination eNB
- @param subframe subframe index to operate on
- @param index of preamble (0-63)
- @param Nf System frame number
- @returns 0 on success
-
-*/
-int32_t generate_prach(PHY_VARS_NR_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe,uint16_t Nf);
-
-
-/*!
- \brief Helper for MAC, returns number of available PRACH in TDD for a particular configuration index
- @param frame_parms Pointer to NR_DL_FRAME_PARMS structure
- @returns 0-5 depending on number of available prach
-*/
-uint8_t get_num_prach_tdd(module_id_t Mod_id);
-
-/*!
- \brief Return the PRACH format as a function of the Configuration Index and Frame type.
- @param prach_ConfigIndex PRACH Configuration Index
- @param frame_type 0-FDD, 1-TDD
- @returns 0-1 accordingly
-*/
-uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type);
-
-uint16_t get_nr_prach_fmt(int prach_ConfigIndex,lte_frame_type_t frame_type, nr_frequency_range_e fr);
-
-/*!
- \brief Helper for MAC, returns frequency index of PRACH resource in TDD for a particular configuration index
- @param frame_parms Pointer to NR_DL_FRAME_PARMS structure
- @returns 0-5 depending on number of available prach
-*/
-uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index);
-
-/*!
- \brief Comp ute DFT of PRACH ZC sequences. Used for generation of prach in UE and reception of PRACH in eNB.
- @param rootSequenceIndex PRACH root sequence
- #param prach_ConfigIndex PRACH Configuration Index
- @param zeroCorrelationZoneConfig PRACH ncs_config
- @param highSpeedFlat PRACH High-Speed Flag
- @param frame_type TDD/FDD flag
- @param Xu DFT output
-*/
-void compute_prach_seq(uint16_t rootSequenceIndex,
- uint8_t prach_ConfigIndex,
- uint8_t zeroCorrelationZoneConfig,
- uint8_t highSpeedFlag,
- lte_frame_type_t frame_type,
- uint32_t X_u[64][839]);
-
-
-void init_prach_tables(int N_ZC);
-
-void init_unscrambling_lut(void);
-void init_scrambling_lut(void);
-
-/*!
- \brief Return the status of MBSFN in this frame/subframe
- @param frame Frame index
- @param subframe Subframe index
- @param frame_parms Pointer to frame parameters
- @returns 1 if subframe is for MBSFN
-*/
-int is_pmch_subframe(frame_t frame, int subframe, NR_DL_FRAME_PARMS *frame_parms);
-
-uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2ndpilots);
-
-uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode);
-
-uint32_t dlsch_decoding_abstraction(double *dlsch_MIPB,
- NR_DL_FRAME_PARMS *lte_frame_parms,
- NR_UE_DLSCH_t *dlsch,
- uint8_t subframe,
- uint8_t num_pdcch_symbols);
-
-// DL power control functions
-double get_pa_dB(uint8_t pa);
-
-
-double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- NR_UE_DLSCH_t *dlsch_ue,
- uint8_t dl_power_off,
- uint8_t n_antenna_port);
-
-double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- PDSCH_CONFIG_COMMON *pdsch_config_common,
- uint8_t n_antenna_port,
- NR_UE_DLSCH_t *dlsch_ue,
- uint8_t dl_power_off);
-
-/*void compute_sqrt_RhoAoRhoB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- PDSCH_CONFIG_COMMON *pdsch_config_common,
- uint8_t n_antenna_port,
- NR_UE_DLSCH_t *dlsch_ue);
-*/
-
-uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms,
- uint8_t prach_ConfigIndex,
- uint8_t n_ra_prboffset,
- uint8_t tdd_mapindex, uint16_t Nf);
-
-uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
-
-int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
- PDSCH_t type,
- unsigned char eNB_id,
- unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
- uint32_t frame,
- uint8_t nr_tti_rx,
- unsigned char symbol,
- unsigned char first_symbol_flag,
- RX_type_t rx_type,
- unsigned char i_mod,
- unsigned char harq_pid);
-
-uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) ;
-
-uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
- short *dlsch_llr,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_DLSCH_t *dlsch,
- NR_DL_UE_HARQ_t *harq_process,
- uint32_t frame,
- uint16_t nb_symb_sch,
- uint8_t nr_tti_rx,
- uint8_t harq_pid,
- uint8_t is_crnti,
- uint8_t llr8_flag);
-
-/**@}*/
-#endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
index 2bc623a66c..3622e61b61 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
@@ -35,12 +35,59 @@
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
+int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
+
+ uint16_t i;
+ int16_t first_free_index=-1;
+
+ AssertFatal(gNB!=NULL,"gNB is null\n");
+ for (i=0; iulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i);
+ AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i);
+ LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index);
+ if ((gNB->ulsch[i][0]->harq_mask >0) &&
+ (gNB->ulsch[i][0]->rnti==rnti)) return i;
+ else if ((gNB->ulsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
+ }
+ if (type == SEARCH_EXIST) return -1;
+ if (first_free_index != -1)
+ gNB->ulsch[first_free_index][0]->rnti = 0;
+ return first_free_index;
+}
+
+void nr_fill_ulsch(PHY_VARS_gNB *gNB,
+ int frame,
+ int slot,
+ nfapi_nr_pusch_pdu_t *ulsch_pdu) {
+
+
+ int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
+ AssertFatal( (ulsch_id>=0) && (ulsch_idrnti,ulsch_id);
+
+ NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id][0];
+ int harq_pid = ulsch_pdu->pusch_data.harq_process_id;
+ ulsch->rnti = ulsch_pdu->rnti;
+ //ulsch->rnti_type;
+ ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid;
+
+ ulsch->harq_processes[harq_pid]->frame=frame;
+ ulsch->harq_processes[harq_pid]->slot=slot;
+ ulsch->harq_processes[harq_pid]->handled= 0;
+ ulsch->harq_processes[harq_pid]->status= NR_ACTIVE;
+ memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t));
+
+ LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
+
+}
+
void nr_ulsch_unscrambling(int16_t* llr,
- uint32_t size,
- uint8_t q,
- uint32_t Nid,
- uint32_t n_RNTI)
-{
+ uint32_t size,
+ uint8_t q,
+ uint32_t Nid,
+ uint32_t n_RNTI) {
+
uint8_t reset;
uint32_t x1, x2, s=0;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 6c6ff4fd05..e00975eee1 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -218,13 +218,13 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
/// Nfapi ULSCH PDU
//nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
ulsch->harq_processes[i]->frame=0;
- ulsch->harq_processes[i]->subframe=0;
+ ulsch->harq_processes[i]->slot=0;
ulsch->harq_processes[i]->round=0;
ulsch->harq_processes[i]->TPC=0;
ulsch->harq_processes[i]->mimo_mode=0;
ulsch->harq_processes[i]->dci_alloc=0;
ulsch->harq_processes[i]->rar_alloc=0;
- ulsch->harq_processes[i]->status=0;
+ ulsch->harq_processes[i]->status=NR_SCH_IDLE;
ulsch->harq_processes[i]->subframe_scheduling_flag=0;
ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0;
ulsch->harq_processes[i]->phich_active=0;
@@ -357,6 +357,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,1);
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
A = (harq_process->TBS)<<3;
@@ -420,7 +422,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#ifdef DEBUG_ULSCH_DECODING
printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
if (!frame%100)
- printf("K %d C %d Z %d\n", harq_process->K, harq_process->C, harq_process->Z);
+ printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
#endif
}
p_decParams->Z = harq_process->Z;
@@ -527,7 +529,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#ifdef DEBUG_ULSCH_DECODING
if (r==0) {
write_output("decoder_llr.m","decllr",ulsch_llr,G,1,0);
- write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0);
+ write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0);
}
printf("decoder input(segment %u) :", r);
@@ -608,7 +610,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#endif
ret = ulsch->max_ldpc_iterations + 1;
}
-
nb_total_decod++;
if (no_iteration_ldpc > ulsch->max_ldpc_iterations){
@@ -666,8 +667,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
ulsch->harq_mask &= ~(1 << harq_pid);
}
- // LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
- // phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
+ // LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
+ // phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
harq_process->handled = 1;
ret = ulsch->max_ldpc_iterations + 1;
@@ -689,6 +690,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
// LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
+
// Reassembly of Transport block here
offset = 0;
Kr = harq_process->K;
@@ -713,14 +715,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#ifdef DEBUG_ULSCH_DECODING
LOG_I(PHY, "Decoder output (payload): \n");
- for (i = 0; i < harq_process->TBS / 8; i++) {
+ for (i = 0; i < harq_process->TBS ; i++) {
//harq_process_ul_ue->a[i] = (unsigned char) rand();
//printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
- printf("0x%02x",harq_process->b[i]);
+ printf("%02x",harq_process->b[i]);
}
#endif
ulsch->last_iteration_cnt = ret;
-
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
return(ret);
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 363b67960d..a966db5844 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -222,7 +222,6 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
}
-
void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
@@ -230,9 +229,10 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
nfapi_nr_pusch_pdu_t *pusch_pdu,
NR_DL_FRAME_PARMS *frame_parms)
{
+
unsigned short start_re, re, nb_re_pusch;
unsigned char aarx;
- uint8_t K_ptrs;
+ uint8_t K_ptrs = 0;
uint32_t rxF_ext_index = 0;
uint32_t ul_ch0_ext_index = 0;
uint32_t ul_ch0_index = 0;
@@ -259,8 +259,6 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
is_ptrs_symbol_flag = 0;
num_ptrs_symbols = 0;
- K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
-
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
@@ -285,6 +283,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
is_dmrs_re = 0;
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+ K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
if(is_ptrs_symbol(symbol, pusch_vars->ptrs_symbols))
is_ptrs_symbol_flag = is_ptrs_subcarrier((start_re + re) % frame_parms->ofdm_symbol_size,
n_rnti,
@@ -313,7 +312,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
ul_ch0_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index];
#ifdef DEBUG_RB_EXT
- printf("rxF_ext[%d] = %d, %d\n", rxF_ext_index, rxF_ext[rxF_ext_index], rxF_ext[rxF_ext_index+1]);
+ printf("rxF_ext[%d] = (%d,%d)\n", rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1]);
#endif
ul_ch0_ext_index++;
@@ -369,7 +368,6 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
nb_rb = (2*nb_rb)/3;
}
-
for (rb=0;rb=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
- for (aatx=0; aatxnb_antenna_ports_gNB; aatx++)
+ for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) {
for (aarx=0; aarxnb_antennas_rx; aarx++) {
//clear average level
avg128U = vdupq_n_s32(0);
@@ -486,8 +484,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
((int32_t*)&avg128U)[2] +
((int32_t*)&avg128U)[3] ) / (nb_rb*nre);
}
-
-
+ }
#endif
}
@@ -513,12 +510,12 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
ul_ch = (int16_t *)&ul_ch_estimates_ext[0][symbol*nb_rb*12];
printf("--------------------symbol = %d, mod_order = %d, output_shift = %d-----------------------\n", symbol, mod_order, output_shift);
- printf("----------------Before compansation------------------\n");
+ printf("----------------Before compensation------------------\n");
- for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){
+ for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx+=2){
- printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]);
- printf("ul_ch[%d] = %d\n", prnt_idx, ul_ch[prnt_idx]);
+ printf("rxF[%d] = (%d,%d)\n", prnt_idx>>1, rxF[prnt_idx],rxF[prnt_idx+1]);
+ printf("ul_ch[%d] = (%d,%d)\n", prnt_idx>>1, ul_ch[prnt_idx],ul_ch[prnt_idx+1]);
}
@@ -706,7 +703,6 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
if (rho) {
-
for (aarx=0; aarxnb_antennas_rx; aarx++) {
rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_UL*12];
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12];
@@ -788,7 +784,6 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
#elif defined(__arm__)
-
unsigned short rb;
unsigned char aatx,aarx,symbol_mod,is_dmrs_symbol=0;
@@ -990,9 +985,9 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
printf("----------------After compansation------------------\n");
- for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){
+ for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx+=2){
- printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]);
+ printf("rxF[%d] = (%d,%d)\n", prnt_idx>>1, rxF[prnt_idx],rxF[prnt_idx+1]);
}
@@ -1005,9 +1000,9 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
printf("----------------After computation------------------\n");
- for (print_idx=0;print_idx<12*nb_rb*2;print_idx++){
+ for (print_idx=0;print_idx<12*nb_rb*2;print_idx+=2){
- printf("ch_mag[%d] = %d\n", print_idx, ch_mag[print_idx]);
+ printf("ch_mag[%d] = (%d,%d)\n", print_idx>>1, ch_mag[print_idx],ch_mag[print_idx+1]);
}
@@ -1015,37 +1010,35 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
}
-void nr_rx_pusch(PHY_VARS_gNB *gNB,
- uint8_t UE_id,
- uint32_t frame,
- uint8_t nr_tti_rx,
- unsigned char symbol,
- unsigned char harq_pid)
+int nr_rx_pusch(PHY_VARS_gNB *gNB,
+ uint8_t ulsch_id,
+ uint32_t frame,
+ uint8_t nr_tti_rx,
+ unsigned char symbol,
+ unsigned char harq_pid)
{
- uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
+ uint8_t aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
uint32_t nb_re_pusch, bwp_start_subcarrier;
uint8_t L_ptrs = 0; // PTRS parameter
int avgs;
int avg[4];
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
- nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu;
+ nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu;
dmrs_symbol_flag = 0;
- first_symbol_flag = 0;
- gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol = 0;
+ gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol = 0;
if(symbol == rel15_ul->start_symbol_index){
- gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
- gNB->pusch_vars[UE_id]->dmrs_symbol = 0;
- gNB->pusch_vars[UE_id]->cl_done = 0;
- gNB->pusch_vars[UE_id]->ptrs_symbols = 0;
- first_symbol_flag = 1;
+ gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset = 0;
+ gNB->pusch_vars[ulsch_id]->dmrs_symbol = 0;
+ gNB->pusch_vars[ulsch_id]->cl_done = 0;
+ gNB->pusch_vars[ulsch_id]->ptrs_symbols = 0;
if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { // if there is ptrs pdu
L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
- set_ptrs_symb_idx(&gNB->pusch_vars[UE_id]->ptrs_symbols,
+ set_ptrs_symb_idx(&gNB->pusch_vars[ulsch_id]->ptrs_symbols,
rel15_ul->nr_of_symbols,
rel15_ul->start_symbol_index,
L_ptrs,
@@ -1058,15 +1051,25 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
dmrs_symbol_flag = ((rel15_ul->ul_dmrs_symb_pos)>>symbol)&0x01;
if (dmrs_symbol_flag == 1){
- nb_re_pusch = rel15_ul->rb_size * ((rel15_ul->dmrs_config_type==pusch_dmrs_type1)?6:8);
- gNB->pusch_vars[UE_id]->dmrs_symbol = symbol;
+ if (((rel15_ul->ul_dmrs_symb_pos)>>((symbol+1)%frame_parms->symbols_per_slot))&0x01)
+ AssertFatal(1==0,"Double DMRS configuration is not yet supported\n");
+
+ if (rel15_ul->dmrs_config_type == 0) {
+ // if no data in dmrs cdm group is 1 only even REs have no data
+ // if no data in dmrs cdm group is 2 both odd and even REs have no data
+ nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*6));
+ }
+ else {
+ nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*4));
+ }
+ gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol;
} else {
nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
}
if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { // if there is ptrs pdu
- if(is_ptrs_symbol(symbol, gNB->pusch_vars[UE_id]->ptrs_symbols))
- gNB->pusch_vars[UE_id]->ptrs_symbol_index = symbol;
+ if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols))
+ gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = symbol;
}
@@ -1086,75 +1089,88 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
//--------------------- RBs extraction ---------------------
//----------------------------------------------------------
- start_meas(&gNB->ulsch_rbs_extraction_stats);
- nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
- gNB->pusch_vars[UE_id],
- symbol,
- dmrs_symbol_flag,
- rel15_ul,
- frame_parms);
- stop_meas(&gNB->ulsch_rbs_extraction_stats);
+ if (nb_re_pusch > 0) {
- nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
- frame_parms,
- gNB->ulsch[UE_id],
- symbol,
- dmrs_symbol_flag,
- rel15_ul->rb_size,
- rel15_ul->dmrs_config_type);
-
-
- if (first_symbol_flag==1) {
-
- nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
- frame_parms,
- avg,
- symbol,
- nb_re_pusch,
- rel15_ul->rb_size);
- avgs = 0;
-
- for (aatx=0;aatxnb_antennas_tx;aatx++)
- for (aarx=0;aarxnb_antennas_rx;aarx++)
- avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
-
- gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1;
-
- }
-
- start_meas(&gNB->ulsch_channel_compensation_stats);
- nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext,
- gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
- gNB->pusch_vars[UE_id]->ul_ch_mag0,
- gNB->pusch_vars[UE_id]->ul_ch_magb0,
- gNB->pusch_vars[UE_id]->rxdataF_comp,
- (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL,
- frame_parms,
+ start_meas(&gNB->ulsch_rbs_extraction_stats);
+ nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
+ gNB->pusch_vars[ulsch_id],
symbol,
dmrs_symbol_flag,
- rel15_ul->qam_mod_order,
- rel15_ul->rb_size,
- gNB->pusch_vars[UE_id]->log2_maxh);
- stop_meas(&gNB->ulsch_channel_compensation_stats);
+ rel15_ul,
+ frame_parms);
+ stop_meas(&gNB->ulsch_rbs_extraction_stats);
+
+ nr_ulsch_scale_channel(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
+ frame_parms,
+ gNB->ulsch[ulsch_id],
+ symbol,
+ dmrs_symbol_flag,
+ rel15_ul->rb_size,
+ rel15_ul->dmrs_config_type);
+
+
+ if (gNB->pusch_vars[ulsch_id]->cl_done==0) {
+
+ nr_ulsch_channel_level(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
+ frame_parms,
+ avg,
+ symbol,
+ nb_re_pusch,
+ rel15_ul->rb_size);
+
+ avgs = 0;
+
+ for (aatx=0;aatxnb_antennas_tx;aatx++)
+ for (aarx=0;aarxnb_antennas_rx;aarx++)
+ avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
+
+ gNB->pusch_vars[ulsch_id]->log2_maxh = (log2_approx(avgs)/2)+1;
+ gNB->pusch_vars[ulsch_id]->cl_done = 1;
+ }
+
+ start_meas(&gNB->ulsch_channel_compensation_stats);
+ nr_ulsch_channel_compensation(gNB->pusch_vars[ulsch_id]->rxdataF_ext,
+ gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
+ gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
+ gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
+ gNB->pusch_vars[ulsch_id]->rxdataF_comp,
+ (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL,
+ frame_parms,
+ symbol,
+ dmrs_symbol_flag,
+ rel15_ul->qam_mod_order,
+ rel15_ul->rb_size,
+ gNB->pusch_vars[ulsch_id]->log2_maxh);
+ stop_meas(&gNB->ulsch_channel_compensation_stats);
+
+
+ int rxsig = signal_energy(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][(symbol*rel15_ul->rb_size*12)],
+ rel15_ul->rb_size*12);
+
+ if (rxsig==1) return (rxsig);
#ifdef NR_SC_FDMA
- nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
+ nr_idft(&((uint32_t*)gNB->pusch_vars[ulsch_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
#endif
//----------------------------------------------------------
//-------------------- LLRs computation --------------------
//----------------------------------------------------------
- start_meas(&gNB->ulsch_llr_stats);
- nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB],
- gNB->pusch_vars[UE_id]->ul_ch_mag0,
- gNB->pusch_vars[UE_id]->ul_ch_magb0,
- &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order],
- rel15_ul->rb_size,
- nb_re_pusch,
- symbol,
- rel15_ul->qam_mod_order);
- stop_meas(&gNB->ulsch_llr_stats);
+ start_meas(&gNB->ulsch_llr_stats);
+ AssertFatal(gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order+nb_re_pusch*rel15_ul->qam_mod_order < (8*((3*8*6144)+12)) , "Mysterious llr buffer size check");
+ nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB],
+ gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
+ gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
+ &gNB->pusch_vars[ulsch_id]->llr[gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order],
+ rel15_ul->rb_size,
+ nb_re_pusch,
+ symbol,
+ rel15_ul->qam_mod_order);
+ stop_meas(&gNB->ulsch_llr_stats);
+
+ }
+
+ gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset = gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset + nb_re_pusch;
+ return (0);
- gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch - gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol;
-
}
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index 6dfbffc46e..501df8bb35 100644
--- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c
+++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
@@ -20,15 +20,15 @@
*/
/*! \file PHY/NR_TRANSPORT/pucch_rx.c
-* \brief Top-level routines for decoding the PUCCH physical channel
-* \author A. Mico Pereperez, Padarthi Naga Prasanth, Francesco Mani, Raymond Knopp
-* \date 2020
-* \version 0.2
-* \company Eurecom
-* \email:
-* \note
-* \warning
-*/
+ * \brief Top-level routines for decoding the PUCCH physical channel
+ * \author A. Mico Pereperez, Padarthi Naga Prasanth, Francesco Mani, Raymond Knopp
+ * \date 2020
+ * \version 0.2
+ * \company Eurecom
+ * \email:
+ * \note
+ * \warning
+ */
#include
#include
#include
@@ -44,7 +44,6 @@
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
#include
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
@@ -53,6 +52,54 @@
//#define DEBUG_NR_PUCCH_RX 1
+NR_gNB_PUCCH_t *new_gNB_pucch(void){
+ NR_gNB_PUCCH_t *pucch;
+ pucch = (NR_gNB_PUCCH_t *)malloc16(sizeof(NR_gNB_PUCCH_t));
+ pucch->active = 0;
+ return (pucch);
+}
+
+int nr_find_pucch(uint16_t rnti,
+ int frame,
+ int slot,
+ PHY_VARS_gNB *gNB) {
+
+ AssertFatal(gNB!=NULL,"gNB is null\n");
+ int index = -1;
+
+ for (int i=0; ipucch[i]!=NULL,"gNB->pucch[%d] is null\n",i);
+ if ((gNB->pucch[i]->active >0) &&
+ (gNB->pucch[i]->pucch_pdu.rnti==rnti) &&
+ (gNB->pucch[i]->frame==frame) &&
+ (gNB->pucch[i]->slot==slot)) return(i);
+ else if ((gNB->pucch[i]->active == 0) && (index==-1)) index=i;
+ }
+
+ if (index==-1)
+ LOG_E(MAC,"PUCCH list is full\n");
+
+ return(index);
+}
+
+void nr_fill_pucch(PHY_VARS_gNB *gNB,
+ int frame,
+ int slot,
+ nfapi_nr_pucch_pdu_t *pucch_pdu) {
+
+ int id = nr_find_pucch(pucch_pdu->rnti,frame,slot,gNB);
+ AssertFatal( (id>=0) && (idrnti,id);
+
+ NR_gNB_PUCCH_t *pucch = gNB->pucch[id];
+ pucch->frame = frame;
+ pucch->slot = slot;
+ pucch->active = 1;
+ memcpy((void*)&pucch->pucch_pdu, (void*)pucch_pdu, sizeof(nfapi_nr_pucch_pdu_t));
+
+}
+
+
int get_pucch0_cs_lut_index(PHY_VARS_gNB *gNB,nfapi_nr_pucch_pdu_t* pucch_pdu) {
int i=0;
@@ -154,7 +201,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
* Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2
*/
// alpha is cyclic shift
- double alpha;
+ //double alpha;
// lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission
//uint8_t lnormal;
// lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213]
@@ -191,9 +238,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
int16_t x_n_re[nr_sequences][24],x_n_im[nr_sequences][24];
for(i=0;inr_of_symbols; l++){
- alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,pucch_pdu->initial_cyclic_shift,mcs[i],l,pucch_pdu->start_symbol_index,slot);
+ double alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,pucch_pdu->initial_cyclic_shift,mcs[i],l,pucch_pdu->start_symbol_index,slot);
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d/%d,mcs %d)\n",u,v,alpha,l,l+pucch_pdu->start_symbol_index,mcs[i]);
printf("lut output %d\n",gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index]);
@@ -201,14 +248,14 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
alpha=0.0;
for (n=0; n<12; n++){
x_n_re[i][(12*l)+n] = (int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
- - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))); // Re part of base sequence shifted by alpha
+ - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))); // Re part of base sequence shifted by alpha
x_n_im[i][(12*l)+n] =(int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
- + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))); // Im part of base sequence shifted by alpha
+ + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))); // Im part of base sequence shifted by alpha
#ifdef DEBUG_NR_PUCCH_RX
- printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d) %d,%d\n",
- u,v,alpha,l,n,x_n_re[i][(12*l)+n],x_n_im[i][(12*l)+n],
- (int32_t)(round(32767*cos(alpha*n))),
- (int32_t)(round(32767*sin(alpha*n))));
+ printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d) %d,%d\n",
+ u,v,alpha,l,n,x_n_re[i][(12*l)+n],x_n_im[i][(12*l)+n],
+ (int32_t)(round(32767*cos(alpha*n))),
+ (int32_t)(round(32767*sin(alpha*n))));
#endif
}
}
@@ -230,12 +277,12 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
r_re[(12*l)+n]=((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0];
r_im[(12*l)+n]=((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1];
- #ifdef DEBUG_NR_PUCCH_RX
- printf("\t [nr_generate_pucch0] mapping to RE \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
- frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,(l2*frame_parms->ofdm_symbol_size)+re_offset,
- l,n,((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0],
- ((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1]);
- #endif
+#ifdef DEBUG_NR_PUCCH_RX
+ printf("\t [nr_generate_pucch0] mapping to RE \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
+ frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,(l2*frame_parms->ofdm_symbol_size)+re_offset,
+ l,n,((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0],
+ ((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1]);
+#endif
re_offset++;
if (re_offset>= frame_parms->ofdm_symbol_size)
re_offset-=frame_parms->ofdm_symbol_size;
@@ -266,7 +313,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
const int16_t *x_re = table_5_2_2_2_2_Re[u],*x_im = table_5_2_2_2_2_Im[u];
int16_t xr[24] __attribute__((aligned(32)));
- int16_t xrt[24] __attribute__((aligned(32)));
+ //int16_t xrt[24] __attribute__((aligned(32)));
int32_t xrtmag=0;
int maxpos=0;
int n2=0;
@@ -300,7 +347,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
n2=0;
for (l=0;lnr_of_symbols;l++) {
- seq_index = (pucch_pdu->initial_cyclic_shift+
+ seq_index = (pucch_pdu->initial_cyclic_shift+
mcs[i]+
gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
for (n=0;n<12;n++,n2+=2) {
@@ -320,14 +367,14 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
uint8_t xrtmag_dB = dB_fixed(xrtmag);
-#ifdef DEBUG_NR_PUCCH_RX
+//#ifdef DEBUG_NR_PUCCH_RX
printf("PUCCH 0 : maxpos %d\n",maxpos);
-#endif
+//#endif
index=maxpos;
#endif
// first bit of bitmap for sr presence and second bit for acknack presence
- uci_pdu->pdu_bit_map = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
+ uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
uci_pdu->pucch_format = 0; // format 0
uci_pdu->ul_cqi = 0xff; // currently not valid
uci_pdu->timing_advance = 0xffff; // currently not valid
@@ -362,8 +409,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
uci_pdu->harq->harq_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
- uci_pdu->harq->harq_list[0].harq_value = index&0x01;
- uci_pdu->harq->harq_list[1].harq_value = (index>>1)&0x01;
+ uci_pdu->harq->harq_list[1].harq_value = index&0x01;
+ uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01;
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
@@ -505,13 +552,13 @@ void nr_decode_pucch1( int32_t **rxdataF,
if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1
z_dmrs_re_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[0];
z_dmrs_im_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[1];
-// printf("%d\t%d\t%d\n",l,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
+ // printf("%d\t%d\t%d\n",l,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]);
#endif
-// printf("l=%d\ti=%d\tre_offset=%d\treceived dmrs re=%d\tim=%d\n",l,i,re_offset,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
+ // printf("l=%d\ti=%d\tre_offset=%d\treceived dmrs re=%d\tim=%d\n",l,i,re_offset,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
}
re_offset++;
@@ -530,7 +577,7 @@ void nr_decode_pucch1( int32_t **rxdataF,
l,lprime);
#endif
// y_n contains the complex value d multiplied by the sequence r_u_v
- if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop
+ if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n",
@@ -548,18 +595,18 @@ void nr_decode_pucch1( int32_t **rxdataF,
}
else{
r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
- - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of DMRS base sequence shifted by alpha
+ - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of DMRS base sequence shifted by alpha
r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
- + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of DMRS base sequence shifted by alpha
+ + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of DMRS base sequence shifted by alpha
r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_re[n]))>>15);
r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_im[n]))>>15);
}
-// printf("symbol=%d\tr_u_rx_re=%d\tr_u_rx_im=%d\n",l,r_u_v_alpha_delta_dmrs_re[n], r_u_v_alpha_delta_dmrs_im[n]);
+ // printf("symbol=%d\tr_u_rx_re=%d\tr_u_rx_im=%d\n",l,r_u_v_alpha_delta_dmrs_re[n], r_u_v_alpha_delta_dmrs_im[n]);
// PUCCH sequence = DM-RS sequence multiplied by d(0)
-/* y_n_re[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15)
- - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n)
- y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15)
- + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n) */
+ /* y_n_re[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15)
+ - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n)
+ y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15)
+ + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n) */
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n",
u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]);
@@ -609,12 +656,12 @@ void nr_decode_pucch1( int32_t **rxdataF,
if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)){
for (int n=0; n<12 ; n++) {
z_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]=z_re_temp;
z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]=z_im_temp;
-// printf("symbol=%d\tz_re_rx=%d\tz_im_rx=%d\t",l,(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
+ // printf("symbol=%d\tz_re_rx=%d\tz_im_rx=%d\t",l,(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n",
mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
@@ -624,15 +671,15 @@ void nr_decode_pucch1( int32_t **rxdataF,
#endif
// multiplying with conjugate of low papr sequence
z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp;
z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp;
-/* if(z_re_temp<0){
- printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_re[n],z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15));
- }
- printf("z1_re_rx=%d\tz1_im_rx=%d\n",(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); */
+ /* if(z_re_temp<0){
+ printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_re[n],z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15));
+ }
+ printf("z1_re_rx=%d\tz1_im_rx=%d\n",(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); */
}
}
}
@@ -643,12 +690,12 @@ void nr_decode_pucch1( int32_t **rxdataF,
if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)){
for (int n=0; n<12 ; n++) {
z_dmrs_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp;
z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp;
-// printf("symbol=%d\tz_dmrs_re_rx=%d\tz_dmrs_im_rx=%d\t",l,(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
+ // printf("symbol=%d\tz_dmrs_re_rx=%d\tz_dmrs_im_rx=%d\t",l,(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n",
mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
@@ -658,17 +705,17 @@ void nr_decode_pucch1( int32_t **rxdataF,
#endif
//finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays
z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
-/* if(z_dmrs_re_temp<0){
- printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_dmrs_re[n],z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15));
- }*/
+ - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ /* if(z_dmrs_re_temp<0){
+ printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_dmrs_re[n],z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15));
+ }*/
z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp;
z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp;
-// printf("z1_dmrs_re_rx=%d\tz1_dmrs_im_rx=%d\n",(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
- /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n];
- z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */
+ // printf("z1_dmrs_re_rx=%d\tz1_dmrs_im_rx=%d\n",(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
+ /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n];
+ z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */
}
}
}
@@ -695,9 +742,9 @@ void nr_decode_pucch1( int32_t **rxdataF,
if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)){
for (int n=0; n<12 ; n++) {
z_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp;
z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp;
#ifdef DEBUG_NR_PUCCH_RX
@@ -708,9 +755,9 @@ void nr_decode_pucch1( int32_t **rxdataF,
z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif
z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp;
z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp;
}
@@ -723,9 +770,9 @@ void nr_decode_pucch1( int32_t **rxdataF,
if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)){
for (int n=0; n<12 ; n++) {
z_dmrs_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp;
z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp;
#ifdef DEBUG_NR_PUCCH_RX
@@ -737,14 +784,14 @@ void nr_decode_pucch1( int32_t **rxdataF,
#endif
//finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays
z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp;
z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp;
- /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n];
- z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */
+ /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n];
+ z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */
}
}
}
@@ -796,8 +843,8 @@ void nr_decode_pucch1( int32_t **rxdataF,
for(int n=0;n<12;n++){
y_n_re[n]=round(z_re_rx[l*12+n]/floor(nrofSymbols/4))+y_n_re[n];
y_n_im[n]=round(z_im_rx[l*12+n]/floor(nrofSymbols/4))+y_n_im[n];
- }
- }
+ }
+ }
else{
for(int n=0;n<12;n++){
y1_n_re[n]=round(z_re_rx[l*12+n]/round(nrofSymbols/4))+y1_n_re[n];
@@ -829,12 +876,12 @@ void nr_decode_pucch1( int32_t **rxdataF,
}
//Decoding QPSK or BPSK symbols to obtain payload bits
if(nr_bit==1){
- if((d_re+d_im)>0){
- *payload=0;
- }
- else{
- *payload=1;
- }
+ if((d_re+d_im)>0){
+ *payload=0;
+ }
+ else{
+ *payload=1;
+ }
}
else if(nr_bit==2){
if((d_re>0)&&(d_im>0)){
@@ -872,6 +919,9 @@ __m256i *pucch2_lut[9]={pucch2_3bit,
pucch2_10bit,
pucch2_11bit};
+__m64 pucch2_polar_4bit[16];
+__m128i pucch2_polar_llr_num_lut[256],pucch2_polar_llr_den_lut[256];
+
void init_pucch2_luts() {
uint32_t out;
@@ -880,7 +930,9 @@ void init_pucch2_luts() {
for (int b=3;b<12;b++) {
for (uint16_t i=0;i<(1< 0 ? -1 : 1;
@@ -949,6 +1001,62 @@ void init_pucch2_luts() {
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,15);
}
}
+ for (uint16_t i=0;i<16;i++) {
+ __m64 *lut_i=&pucch2_polar_4bit[i];
+
+ bit = (i&0x1) > 0 ? -1 : 1;
+ *lut_i = _mm_insert_pi16(*lut_i,bit,0);
+ bit = (i&0x2) > 0 ? -1 : 1;
+ *lut_i = _mm_insert_pi16(*lut_i,bit,1);
+ bit = (i&0x4) > 0 ? -1 : 1;
+ *lut_i = _mm_insert_pi16(*lut_i,bit,2);
+ bit = (i&0x8) > 0 ? -1 : 1;
+ *lut_i = _mm_insert_pi16(*lut_i,bit,3);
+ }
+ for (int i=0;i<256;i++) {
+ __m128i *lut_num_i=&pucch2_polar_llr_num_lut[i];
+ __m128i *lut_den_i=&pucch2_polar_llr_den_lut[i];
+ bit = (i&0x1) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,0);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,0);
+
+ bit = (i&0x10) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,1);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,1);
+
+ bit = (i&0x2) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,2);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,2);
+
+ bit = (i&0x20) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,3);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,3);
+
+ bit = (i&0x4) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,4);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,4);
+
+ bit = (i&0x40) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,5);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,5);
+
+ bit = (i&0x8) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,6);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,6);
+
+ bit = (i&0x80) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,7);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,7);
+ printf("i %d, lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",i,
+ ((int16_t *)lut_num_i)[0],
+ ((int16_t *)lut_num_i)[1],
+ ((int16_t *)lut_num_i)[2],
+ ((int16_t *)lut_num_i)[3],
+ ((int16_t *)lut_num_i)[4],
+ ((int16_t *)lut_num_i)[5],
+ ((int16_t *)lut_num_i)[6],
+ ((int16_t *)lut_num_i)[7]);
+ }
}
@@ -959,7 +1067,9 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
int32_t **rxdataF = gNB->common_vars.rxdataF;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
- pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
+ //pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
+
+
AssertFatal(pucch_pdu->nr_of_symbols==1 || pucch_pdu->nr_of_symbols==2,
"Illegal number of symbols for PUCCH 2 %d\n",pucch_pdu->nr_of_symbols);
@@ -967,7 +1077,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
//extract pucch and dmrs first
- int l2=-1;
+ int l2=pucch_pdu->start_symbol_index;
int re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset;
if (re_offset>= frame_parms->ofdm_symbol_size)
re_offset-=frame_parms->ofdm_symbol_size;
@@ -984,6 +1094,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
int16_t r_im_ext2[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
int16_t rd_re_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
int16_t rd_im_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
+ int16_t *r_re_ext_p,*r_im_ext_p,*rd_re_ext_p,*rd_im_ext_p;
int16_t *rp[Prx2];
__m64 dmrs_re,dmrs_im;
@@ -1000,156 +1111,166 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
for (int aa=0;aanr_of_symbols == 1) {
- AssertFatal((pucch_pdu->prb_size&1) == 0,"prb_size %d is not a multiple of 2\n",pucch_pdu->prb_size);
- // 24 PRBs contains 48x16-bit, so 6x8x16-bit
- for (int prb=0;prbprb_size;prb+=2) {
- for (int aa=0;aaprb_size&1) == 0,"prb_size %d is not a multiple of 2\n",pucch_pdu->prb_size);
+ // 24 PRBs contains 48x16-bit, so 6x8x16-bit
+ for (int prb=0;prbprb_size;prb+=2) {
+ for (int aa=0;aa (%d,%d)\n",aa,prb+(i>>2),i,rd_re_ext[aa][i],rd_im_ext[aa]);
+ for (int i=0;i<8;i++) printf("Ant %d PRB %d dmrs[%d] -> (%d,%d)\n",aa,prb+(i>>2),i,rd_re_ext_p[i],rd_im_ext_p[i]);
+ for (int i=0;i<16;i++) printf("Ant %d PRB %d data[%d] -> (%d,%d)\n",aa,prb+(i>>3),i,r_re_ext_p[i],r_im_ext_p[i]);
#endif
- } // aa
- } // prb
+ rp[aa]+=48;
+ } // aa
+ } // prb
- // first compute DMRS component
- uint32_t x1, x2, s=0;
- x2 = (((1<<17)*((14*slot) + (pucch_pdu->start_symbol_index) + 1)*((2*pucch_pdu->dmrs_scrambling_id) + 1)) + (2*pucch_pdu->dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
+ // first compute DMRS component
+ uint32_t x1, x2, s=0;
+ x2 = (((1<<17)*((14*slot) + (pucch_pdu->start_symbol_index) + 1)*((2*pucch_pdu->dmrs_scrambling_id) + 1)) + (2*pucch_pdu->dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
#ifdef DEBUG_NR_PUCCH_RX
- printf("slot %d, start_symbol_index %d, dmrs_scrambling_id %d\n",
- slot,pucch_pdu->start_symbol_index,pucch_pdu->dmrs_scrambling_id);
+ printf("slot %d, start_symbol_index %d, dmrs_scrambling_id %d\n",
+ slot,pucch_pdu->start_symbol_index,pucch_pdu->dmrs_scrambling_id);
#endif
- s = lte_gold_generic(&x1, &x2, 1);
+ s = lte_gold_generic(&x1, &x2, 1);
+ for (int group=0;group>=5;
+ corr32_im[group][aa]>>=5;
#ifdef DEBUG_NR_PUCCH_RX
- printf("Group %d: rd ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
- group,
- rd_re_ext[aa][4],rd_im_ext[aa][4],
- rd_re_ext[aa][5],rd_im_ext[aa][5],
- rd_re_ext[aa][6],rd_im_ext[aa][6],
- rd_re_ext[aa][7],rd_im_ext[aa][7]);
+ printf("Group %d: corr32 (%d,%d)\n",group,corr32_re[group][aa],corr32_im[group][aa]);
#endif
- corr32_re[group][aa]+=(rd_re_ext[aa][4]*((int16_t*)&dmrs_re)[0] + rd_im_ext[aa][4]*((int16_t*)&dmrs_im)[0]);
- corr32_im[group][aa]+=(-rd_re_ext[aa][4]*((int16_t*)&dmrs_im)[0] + rd_im_ext[aa][4]*((int16_t*)&dmrs_re)[0]);
- corr32_re[group][aa]+=(rd_re_ext[aa][5]*((int16_t*)&dmrs_re)[1] + rd_im_ext[aa][5]*((int16_t*)&dmrs_im)[1]);
- corr32_im[group][aa]+=(-rd_re_ext[aa][5]*((int16_t*)&dmrs_im)[1] + rd_im_ext[aa][5]*((int16_t*)&dmrs_re)[1]);
- corr32_re[group][aa]+=(rd_re_ext[aa][6]*((int16_t*)&dmrs_re)[2] + rd_im_ext[aa][6]*((int16_t*)&dmrs_im)[2]);
- corr32_im[group][aa]+=(-rd_re_ext[aa][6]*((int16_t*)&dmrs_im)[2] + rd_im_ext[aa][6]*((int16_t*)&dmrs_re)[2]);
- corr32_re[group][aa]+=(rd_re_ext[aa][7]*((int16_t*)&dmrs_re)[3] + rd_im_ext[aa][7]*((int16_t*)&dmrs_im)[3]);
- corr32_im[group][aa]+=(-rd_re_ext[aa][7]*((int16_t*)&dmrs_im)[3] + rd_im_ext[aa][7]*((int16_t*)&dmrs_re)[3]);
- corr32_re[group][aa]>>=5;
- corr32_im[group][aa]>>=5;
-#ifdef DEBUG_NR_PUCCH_RX
- printf("Group %d: corr32 (%d,%d)\n",group,corr32_re[group][aa],corr32_im[group][aa]);
-#endif
- } //aa
+ } //aa
- if ((group&3) == 3) s = lte_gold_generic(&x1, &x2, 0);
- } // group
+ if ((group&1) == 1) s = lte_gold_generic(&x1, &x2, 0);
+ } // group
}
else { // 2 symbol case
- AssertFatal(1==0, "Fill in 2 symbol PUCCH2 case\n");
+ AssertFatal(1==0, "Fill in 2 symbol PUCCH2 case\n");
}
uint32_t x1, x2, s=0;
@@ -1174,47 +1295,47 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
for (int aa=0;aabit_len_csi_part1 + pucch_pdu->bit_len_csi_part2 == 0,"no csi for now\n");
- AssertFatal((pucch_pdu->bit_len_harq+pucch_pdu->sr_flag > 2 ) && (pucch_pdu->bit_len_harq+pucch_pdu->sr_flag < 12),"illegal length (%d,%d)\n",pucch_pdu->bit_len_harq,pucch_pdu->sr_flag);
- int nb_bit = pucch_pdu->bit_len_harq+pucch_pdu->sr_flag;
- __m256i *rp_re[Prx2];
- __m256i *rp2_re[Prx2];
- __m256i *rp_im[Prx2];
- __m256i *rp2_im[Prx2];
- for (int aa=0;aa>1],
- ((int16_t*)&pucch2_lut[nb_bit-3][cw<<1])[1+(i>>1)]);
- }
printf("\n");
#endif
- // do complex correlation
- for (int aa=0;aa corr) {
- corr = corr_tmp;
- cw_ML=cw;
- }
}
- uint8_t corr_dB = dB_fixed64((uint64_t)corr);
- LOG_D(PHY,"cw_ML %d, metric %d dB\n",cw_ML,corr_dB);
- uci_pdu->harq.harq_bit_len = pucch_pdu->bit_len_harq;
+ int nb_bit = pucch_pdu->bit_len_harq+pucch_pdu->sr_flag+pucch_pdu->bit_len_csi_part1+pucch_pdu->bit_len_csi_part2;
+ AssertFatal(nb_bit > 2 && nb_bit< 65,"illegal length (%d : %d,%d,%d,%d)\n",nb_bit,pucch_pdu->bit_len_harq,pucch_pdu->sr_flag,pucch_pdu->bit_len_csi_part1,pucch_pdu->bit_len_csi_part2);
-
- int harq_bytes=pucch_pdu->bit_len_harq>>3;
- if ((pucch_pdu->bit_len_harq&7) > 0) harq_bytes++;
- uci_pdu->harq.harq_payload = (uint8_t*)malloc(harq_bytes);
- uci_pdu->harq.harq_crc = 2;
- for (int i=0;iharq.harq_payload[i] = cw_ML & 255;
- cw_ML>>=8;
+ uint64_t decodedPayload[2];
+ uint8_t corr_dB;
+ int decoderState=2;
+ if (nb_bit < 12) { // short blocklength case
+ __m256i *rp_re[Prx2];
+ __m256i *rp2_re[Prx2];
+ __m256i *rp_im[Prx2];
+ __m256i *rp2_im[Prx2];
+ for (int aa=0;aa>1],
+ ((int16_t*)&pucch2_lut[nb_bit-3][cw<<1])[1+(i>>1)]);
+ }
+ printf("\n");
+#endif
+ // do complex correlation
+ for (int aa=0;aa (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",aa,
+ ((int16_t*)&prod_re[aa])[0],((int16_t*)&prod_re[aa])[1],((int16_t*)&prod_re[aa])[2],((int16_t*)&prod_re[aa])[3],
+ ((int16_t*)&prod_re[aa])[4],((int16_t*)&prod_re[aa])[5],((int16_t*)&prod_re[aa])[6],((int16_t*)&prod_re[aa])[7],
+ ((int16_t*)&prod_re[aa])[8],((int16_t*)&prod_re[aa])[9],((int16_t*)&prod_re[aa])[10],((int16_t*)&prod_re[aa])[11],
+ ((int16_t*)&prod_re[aa])[12],((int16_t*)&prod_re[aa])[13],((int16_t*)&prod_re[aa])[14],((int16_t*)&prod_re[aa])[15]);
+ printf("prod_im[%d] => (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",aa,
+ ((int16_t*)&prod_im[aa])[0],((int16_t*)&prod_im[aa])[1],((int16_t*)&prod_im[aa])[2],((int16_t*)&prod_im[aa])[3],
+ ((int16_t*)&prod_im[aa])[4],((int16_t*)&prod_im[aa])[5],((int16_t*)&prod_im[aa])[6],((int16_t*)&prod_im[aa])[7],
+ ((int16_t*)&prod_im[aa])[8],((int16_t*)&prod_im[aa])[9],((int16_t*)&prod_im[aa])[10],((int16_t*)&prod_im[aa])[11],
+ ((int16_t*)&prod_im[aa])[12],((int16_t*)&prod_im[aa])[13],((int16_t*)&prod_im[aa])[14],((int16_t*)&prod_im[aa])[15]);
+
+#endif
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ }
+ int64_t corr_re=0,corr_im=0;
+
+ int64_t corr_tmp = 0;
+ for (int aa=0;aa corr) {
+ corr = corr_tmp;
+ cw_ML=cw;
+ }
+ }
+ corr_dB = dB_fixed64((uint64_t)corr);
+ LOG_D(PHY,"cw_ML %d, metric %d dB\n",cw_ML,corr_dB);
+ decodedPayload[0]=(uint64_t)cw_ML;
+ }
+ else { // polar coded case
+
+ t_nrPolar_params *currentPtr = nr_polar_params(2,nb_bit,pucch_pdu->prb_size,1,&gNB->uci_polarParams);
+ __m64 *rp_re[Prx2];
+ __m64 *rp2_re[Prx2];
+ __m64 *rp_im[Prx2];
+ __m64 *rp2_im[Prx2];
+ __m128i llrs[pucch_pdu->prb_size*2];
+
+ for (int aa=0;aa>1]);
+ }
+ printf("\n");
+ }
+#endif
+
+ // non-coherent LLR computation on groups of 4 REs (half-PRBs)
+ int32_t corr_re,corr_im,corr_tmp;
+ __m128i corr16,llr_num,llr_den;
+ uint64_t corr = 0;
+
+ for (int half_prb=0;half_prb<(2*pucch_pdu->prb_size);half_prb++) {
+ llr_num=_mm_set1_epi16(0);llr_den=_mm_set1_epi16(0);
+ for (int cw=0;cw<256;cw++) {
+ corr_tmp=0;
+ for (int aa=0;aa>4],rp_im[aa][half_prb])),5);
+ prod_im[aa] = _mm_srai_pi16(_mm_subs_pi16(_mm_mullo_pi16(pucch2_polar_4bit[cw&15],rp2_im[aa][half_prb]),
+ _mm_mullo_pi16(pucch2_polar_4bit[cw>>4],rp2_re[aa][half_prb])),5);
+ prod_re[aa] = _mm_hadds_pi16(prod_re[aa],prod_re[aa]);// 0+1
+ prod_im[aa] = _mm_hadds_pi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm_hadds_pi16(prod_re[aa],prod_re[aa]);// 0+1+2+3
+ prod_im[aa] = _mm_hadds_pi16(prod_im[aa],prod_im[aa]);
+
+ // this is for UL CQI measurement
+ if (cw==0) corr += ((int64_t)corr32_re[half_prb>>2][aa]*corr32_re[half_prb>>2][aa])+
+ ((int64_t)corr32_im[half_prb>>2][aa]*corr32_im[half_prb>>2][aa]);
+
+
+ corr_re = ( corr32_re[half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_re[aa]))[0]);
+ corr_im = ( corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_im[aa]))[0]);
+ corr_tmp += corr_re*corr_re + corr_im*corr_im;
+ /*
+ LOG_D(PHY,"pucch2 half_prb %d cw %d (%d,%d) aa %d: (%d,%d,%d,%d,%d,%d,%d,%d)x(%d,%d,%d,%d,%d,%d,%d,%d) (%d,%d)+(%d,%d) = (%d,%d) => %d\n",
+ half_prb,cw,cw&15,cw>>4,aa,
+ ((int16_t*)&pucch2_polar_4bit[cw&15])[0],((int16_t*)&pucch2_polar_4bit[cw>>4])[0],
+ ((int16_t*)&pucch2_polar_4bit[cw&15])[1],((int16_t*)&pucch2_polar_4bit[cw>>4])[1],
+ ((int16_t*)&pucch2_polar_4bit[cw&15])[2],((int16_t*)&pucch2_polar_4bit[cw>>4])[2],
+ ((int16_t*)&pucch2_polar_4bit[cw&15])[3],((int16_t*)&pucch2_polar_4bit[cw>>4])[3],
+ ((int16_t*)&rp_re[aa][half_prb])[0],((int16_t*)&rp_im[aa][half_prb])[0],
+ ((int16_t*)&rp_re[aa][half_prb])[1],((int16_t*)&rp_im[aa][half_prb])[1],
+ ((int16_t*)&rp_re[aa][half_prb])[2],((int16_t*)&rp_im[aa][half_prb])[2],
+ ((int16_t*)&rp_re[aa][half_prb])[3],((int16_t*)&rp_im[aa][half_prb])[3],
+ corr32_re[half_prb>>2][aa]/(2*nc_group_size*4/2),corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2),
+ ((int16_t*)(&prod_re[aa]))[0],
+ ((int16_t*)(&prod_im[aa]))[0],
+ corr_re,
+ corr_im,
+ corr_tmp);
+ */
+ }
+ corr16 = _mm_set1_epi16((int16_t)(corr_tmp>>8));
+ /*
+ LOG_D(PHY,"half_prb %d cw %d corr16 %d\n",half_prb,cw,corr_tmp>>8);
+ */
+ llr_num = _mm_max_epi16(_mm_mullo_epi16(corr16,pucch2_polar_llr_num_lut[cw]),llr_num);
+ llr_den = _mm_max_epi16(_mm_mullo_epi16(corr16,pucch2_polar_llr_den_lut[cw]),llr_den);
+ /*
+ LOG_D(PHY,"lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[0],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[1],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[2],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[3],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[4],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[5],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[6],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[7]);
+
+ LOG_D(PHY,"llr_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",
+ ((int16_t*)&llr_num)[0],
+ ((int16_t*)&llr_num)[1],
+ ((int16_t*)&llr_num)[2],
+ ((int16_t*)&llr_num)[3],
+ ((int16_t*)&llr_num)[4],
+ ((int16_t*)&llr_num)[5],
+ ((int16_t*)&llr_num)[6],
+ ((int16_t*)&llr_num)[7]);
+ LOG_D(PHY,"llr_den (%d,%d,%d,%d,%d,%d,%d,%d)\n",
+ ((int16_t*)&llr_den)[0],
+ ((int16_t*)&llr_den)[1],
+ ((int16_t*)&llr_den)[2],
+ ((int16_t*)&llr_den)[3],
+ ((int16_t*)&llr_den)[4],
+ ((int16_t*)&llr_den)[5],
+ ((int16_t*)&llr_den)[6],
+ ((int16_t*)&llr_den)[7]);
+ */
+ }
+ // compute llrs
+ llrs[half_prb] = _mm_subs_epi16(llr_num,llr_den);
+ LOG_D(PHY,"llrs[%d] : (%d,%d,%d,%d,%d,%d,%d,%d)\n",
+ half_prb,
+ ((int16_t*)&llrs[half_prb])[0],
+ ((int16_t*)&llrs[half_prb])[1],
+ ((int16_t*)&llrs[half_prb])[2],
+ ((int16_t*)&llrs[half_prb])[3],
+ ((int16_t*)&llrs[half_prb])[4],
+ ((int16_t*)&llrs[half_prb])[5],
+ ((int16_t*)&llrs[half_prb])[6],
+ ((int16_t*)&llrs[half_prb])[7]);
+ } // half_prb
+ // run polar decoder on llrs
+ decoderState = polar_decoder_int16((int16_t*)llrs, decodedPayload, 0, currentPtr);
+ LOG_D(PHY,"UCI decoderState %d, payload[0] %llux\n",decoderState,(unsigned long long)decodedPayload[0]);
+ if (decoderState>0) decoderState=1;
+ corr_dB = dB_fixed64(corr);
+ LOG_D(PHY,"metric %d dB\n",corr_dB);
+ }
+ uci_pdu->harq.harq_bit_len = pucch_pdu->bit_len_harq;
+ uci_pdu->pduBitmap=0;
+ uci_pdu->rnti=pucch_pdu->rnti;
+ uci_pdu->handle=pucch_pdu->handle;
+ uci_pdu->pucch_format=0;
+ uci_pdu->ul_cqi=corr_dB;
+ // need to fill these field!
+ uci_pdu->timing_advance=31;
+ uci_pdu->rssi=0;
+ if (pucch_pdu->bit_len_harq>0) {
+ int harq_bytes=pucch_pdu->bit_len_harq>>3;
+ if ((pucch_pdu->bit_len_harq&7) > 0) harq_bytes++;
+ uci_pdu->pduBitmap|=1;
+ uci_pdu->harq.harq_payload = (uint8_t*)malloc(harq_bytes);
+ uci_pdu->harq.harq_crc = decoderState > 0 ? 1 : 0;
+ int i=0;
+ for (;iharq.harq_payload[i] = decodedPayload[0] & 255;
+ decodedPayload[0]>>=8;
+ }
+ uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_harq&7))-1);
+ decodedPayload[0] >>= pucch_pdu->bit_len_harq;
}
if (pucch_pdu->sr_flag == 1) {
+ uci_pdu->pduBitmap|=2;
uci_pdu->sr.sr_bit_len = 1;
uci_pdu->sr.sr_payload = malloc(1);
- uci_pdu->sr.sr_payload[0] = cw_ML;
+ uci_pdu->sr.sr_payload[0] = decodedPayload[0]&1;
+ decodedPayload[0] = decodedPayload[0]>>1;
}
+ // csi
+ if (pucch_pdu->bit_len_csi_part1>0) {
+ uci_pdu->pduBitmap|=4;
+ int csi_part1_bytes=pucch_pdu->bit_len_csi_part1>>3;
+ if ((pucch_pdu->bit_len_csi_part1&7) > 0) csi_part1_bytes++;
+ uci_pdu->csi_part1.csi_part1_payload = (uint8_t*)malloc(csi_part1_bytes);
+ uci_pdu->csi_part1.csi_part1_crc = decoderState > 0 ? 1 : 0;
+ int i=0;
+ for (;icsi_part1.csi_part1_payload[i] = decodedPayload[0] & 255;
+ decodedPayload[0]>>=8;
+ }
+ uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_csi_part1&7))-1);
+ decodedPayload[0] >>= pucch_pdu->bit_len_csi_part1;
+ }
+
+ if (pucch_pdu->bit_len_csi_part2>0) {
+ uci_pdu->pduBitmap|=8;
+ }
+
}
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
index 7f5872e885..b49443c03c 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
@@ -34,8 +34,9 @@
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
- module_id_t eNB_id,
- uint8_t subframe,
+ module_id_t gNB_id,
+ uint8_t frame,
+ uint8_t subframe,
unsigned char clear,
short coef)
{
@@ -59,8 +60,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
temp = 0;
for (aa=0; aanb_antennas_rx; aa++) {
- Re = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
- Im = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
+ Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
+ Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
@@ -104,17 +105,19 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
//mac_resynch();
//dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH;
+ ue->prach_resources[gNB_id]->sync_frame = frame;
+ ue->prach_resources[gNB_id]->init_msg1 = 0;
}
else {
ue->UE_mode[0] = PUSCH;
}
}
- if ( ue->rx_offset < 0 )
- ue->rx_offset += frame_parms->samples_per_frame;
+ if (ue->rx_offset < 0)
+ ue->rx_offset += frame_parms->samples_per_frame;
- if ( ue->rx_offset >= frame_parms->samples_per_frame )
- ue->rx_offset -= frame_parms->samples_per_frame;
+ if (ue->rx_offset >= frame_parms->samples_per_frame)
+ ue->rx_offset -= frame_parms->samples_per_frame;
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index af06f9a98f..1837664391 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -75,6 +75,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
module_id_t eNB_id,
+ uint8_t frame,
uint8_t subframe,
unsigned char clear,
short coef);
@@ -90,6 +91,7 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
uint32_t rx_power_fil_dB,
uint8_t eNB_id);
-int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index);
+int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
+
#endif
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
index aa1e2b5ade..860ca11d8c 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
@@ -55,8 +55,9 @@ void print_ints(char *s,int *x)
}
#endif
-int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index)
-{
+int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index){
+
+ PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
/*
if (ue->frame_parms.mode1_flag == 1)
@@ -75,9 +76,6 @@ int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index)
//(ue->frame_parms.pdsch_config_common.referenceSignalPower*10))/10));
}
-
-
-
void nr_ue_measurements(PHY_VARS_NR_UE *ue,
unsigned int subframe_offset,
unsigned char N0_symbol,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index ef22b61260..7cde6e31c1 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -29,11 +29,15 @@
* \note
* \warning
*/
+
#ifdef USER_MODE
#include
#include
#include
#endif
+
+#include "executables/softmodem-common.h"
+
#include "nr_transport_proto_ue.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h"
#include "PHY/phy_extern_nr_ue.h"
@@ -799,20 +803,22 @@ void pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms,
#ifdef NR_PDCCH_DCI_RUN
-void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t slot,
- int16_t *z, int16_t *z2,uint32_t length, uint16_t pdcch_DMRS_scrambling_id) {
+void nr_pdcch_unscrambling(int16_t *z,
+ uint16_t scrambling_RNTI,
+ uint32_t length,
+ uint16_t pdcch_DMRS_scrambling_id,
+ int16_t *z2) {
int i;
uint8_t reset;
uint32_t x1, x2, s = 0;
uint16_t n_id; //{0,1,...,65535}
- uint32_t n_rnti;
+ uint32_t rnti = (uint32_t) scrambling_RNTI;
reset = 1;
// x1 is set in first call to lte_gold_generic
- //do_common=1;
- n_id = pdcch_DMRS_scrambling_id;
- n_rnti = (uint32_t)crnti;
+ n_id = pdcch_DMRS_scrambling_id;
+ x2 = ((rnti<<16) + n_id); //mod 2^31 is implicit //this is c_init in 38.211 v15.1.0 Section 7.3.2.3
- x2 = (((1<<16)*n_rnti)+n_id); //mod 2^31 is implicit //this is c_init in 38.211 v15.1.0 Section 7.3.2.3
+ LOG_D(PHY,"PDCCH Unscrambling x2 %x : scrambling_RNTI %x\n", x2, rnti);
for (i = 0; i < length; i++) {
if ((i & 0x1f) == 0) {
@@ -840,38 +846,48 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
rel15 = &pdcch_vars->pdcch_config[i];
int dci_length = rel15->dci_length;
+ //int gNB_id = 0;
int16_t tmp_e[16*108];
+ rnti_t n_rnti;
for (int j=0;jnumber_of_candidates;j++) {
- LOG_D(PHY,"Trying DCI candidate %d, CCE %d (%d), L %d\n",j,rel15->CCE[j],rel15->CCE[j]*9*6*2,rel15->L[j]);
int CCEind = rel15->CCE[j];
int L = rel15->L[j];
uint64_t dci_estimation[2]= {0};
- const t_nrPolar_params *currentPtrDCI=nr_polar_params(1, dci_length, L,1,&ue->polarList);
+ const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
- nr_pdcch_unscrambling(rel15->rnti,
- &ue->frame_parms,
- slot,
- &pdcch_vars->e_rx[CCEind*108],
- tmp_e,
- L*108,
- // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72,
- rel15->coreset.pdcch_dmrs_scrambling_id);
+ LOG_D(PHY, "Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d\n", j, rel15->number_of_candidates, CCEind, CCEind*9*6*2, L);
+
+ nr_pdcch_unscrambling(&pdcch_vars->e_rx[CCEind*108], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
+
+ #ifdef DEBUG_DCI_DECODING
+ uint32_t * z = (uint32_t *) &pdcch_vars->e_rx[CCEind*108];
+ for (int index_z = 0; index_z < 96; index_z++){
+ for (int i=0; i<9; i++) {
+ LOG_D(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]));
+ }
+ }
+ #endif
uint16_t crc = polar_decoder_int16(tmp_e,
dci_estimation,
1,
currentPtrDCI);
- LOG_D(PHY,"Decoded crc %x\n",crc);
- if (crc == rel15->rnti) {
+
+ n_rnti = rel15->rnti;
+
+ if (crc == n_rnti) {
+ LOG_D(PHY,"Decoded crc %x matches rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format);
dci_ind->SFN = frame;
dci_ind->slot = slot;
- dci_ind->dci_list[dci_ind->number_of_dcis].rnti = rel15->rnti;
+ dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format;
dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
dci_ind->number_of_dcis++;
+ } else {
+ LOG_D(PHY,"Decoded crc %x does not match rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format);
}
}
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index e5cbc4e07a..1a6006c3ba 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -32,6 +32,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "PHY/defs_nr_UE.h"
+#include "SCHED_NR_UE/harq_nr.h"
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/CODING/coding_extern.h"
#include "PHY/CODING/coding_defs.h"
@@ -42,6 +43,7 @@
#include "SIMULATION/TOOLS/sim.h"
#include "executables/nr-uesoftmodem.h"
#include "PHY/CODING/nrLDPC_extern.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
//#define DEBUG_DLSCH_DECODING
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
@@ -132,6 +134,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
memset(dlsch,0,sizeof(NR_UE_DLSCH_t));
dlsch->Kmimo = Kmimo;
dlsch->Mdlharq = Mdlharq;
+ dlsch->number_harq_processes_for_pdsch = Mdlharq;
dlsch->Nsoft = Nsoft;
dlsch->Mlimit = 4;
dlsch->max_ldpc_iterations = max_ldpc_iterations;
@@ -142,6 +145,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
if (dlsch->harq_processes[i]) {
memset(dlsch->harq_processes[i],0,sizeof(NR_DL_UE_HARQ_t));
+ init_downlink_harq_status(dlsch->harq_processes[i]);
dlsch->harq_processes[i]->first_tx=1;
dlsch->harq_processes[i]->b = (uint8_t*)malloc16(dlsch_bytes);
@@ -214,16 +218,16 @@ void nr_dlsch_unscrambling(int16_t* llr,
}
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
- short *dlsch_llr,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_DLSCH_t *dlsch,
- NR_DL_UE_HARQ_t *harq_process,
- uint32_t frame,
- uint16_t nb_symb_sch,
- uint8_t nr_tti_rx,
- uint8_t harq_pid,
- uint8_t is_crnti,
- uint8_t llr8_flag)
+ short *dlsch_llr,
+ NR_DL_FRAME_PARMS *frame_parms,
+ NR_UE_DLSCH_t *dlsch,
+ NR_DL_UE_HARQ_t *harq_process,
+ uint32_t frame,
+ uint16_t nb_symb_sch,
+ uint8_t nr_tti_rx,
+ uint8_t harq_pid,
+ uint8_t is_crnti,
+ uint8_t llr8_flag)
{
#if UE_TIMING_TRACE
@@ -263,7 +267,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t dmrs_Type = harq_process->dmrsConfigType;
AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type);
- uint8_t nb_re_dmrs = (dmrs_Type==1)?6:4;
+ uint8_t nb_re_dmrs = (dmrs_Type==1)?6:4; // should be changed based on MAC parameters
uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length);
@@ -317,7 +321,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
- harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, harq_process->Nl);
+ harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, 0, harq_process->Nl);
A = harq_process->TBS;
ret = dlsch->max_ldpc_iterations + 1;
@@ -326,7 +330,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, harq_process->Qm,harq_process->Nl);
G = harq_process->G;
- LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
+ LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,A/8,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
if ((harq_process->R)<1024)
Coderate = (float) (harq_process->R) /(float) 1024;
@@ -801,8 +805,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
//nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config;
//uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;
- uint8_t nb_re_dmrs = (dmrs_type==1)?6:4;
- uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos);
+ uint8_t nb_re_dmrs = 12;//(dmrs_type==1)?6:4;
+ uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos);
uint32_t i,j;
// int nbDlProcessing =0;
@@ -854,7 +858,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
- harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl);
+ harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl);
A = harq_process->TBS;
@@ -1431,7 +1435,7 @@ void nr_dlsch_decoding_process(void *arg)
uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
- harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl);
+ harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl);
A = harq_process->TBS; //2072 for QPSK 1/3
@@ -1697,10 +1701,10 @@ void nr_dlsch_decoding_process(void *arg)
}
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
- (int8_t*)&pl[0],
- llrProcBuf,
- p_nrLDPC_procBuf,
- p_procTime);
+ (int8_t*)&pl[0],
+ llrProcBuf,
+ p_nrLDPC_procBuf,
+ p_procTime);
// 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)) {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index c704efdb1f..a8827b4e92 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -30,6 +30,7 @@
*/
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern_nr_ue.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "nr_transport_proto_ue.h"
//#include "SCHED/defs.h"
//#include "PHY/defs.h"
@@ -131,7 +132,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
unsigned short nb_rb = 0, round;
int avgs = 0;// rb;
- NR_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0;
+ NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
uint8_t beamforming_mode;
@@ -155,82 +156,93 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
uint16_t n_tx=1, n_rx=1;
int32_t median[16];
uint32_t len;
-
+
switch (type) {
case SI_PDSCH:
- pdsch_vars = &ue->pdsch_vars_SI[eNB_id];
+ pdsch_vars = ue->pdsch_vars_SI;
dlsch = &ue->dlsch_SI[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- beamforming_mode = 0;
+ beamforming_mode = 0;
break;
case RA_PDSCH:
- pdsch_vars = &ue->pdsch_vars_ra[eNB_id];
+ pdsch_vars = ue->pdsch_vars_ra;
dlsch = &ue->dlsch_ra[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- beamforming_mode = 0;
+ beamforming_mode = 0;
+
break;
case PDSCH:
pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]];
dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id];
+ beamforming_mode = ue->transmission_mode[eNB_id] < 7 ? 0 :ue->transmission_mode[eNB_id];
+ dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+ dlsch1_harq = dlsch[1]->harq_processes[harq_pid];
- dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
- dlsch[0]->harq_processes[harq_pid]->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
-
- //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
- LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n",
- frame,nr_tti_rx,symbol,harq_pid,
- dlsch[0]->harq_processes[harq_pid]->status,
- dlsch[1]->harq_processes[harq_pid]->status);
+ //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
+ LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_tti_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status);
- if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) &&
- (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE)){
- codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword;
- codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword;
+ if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status == ACTIVE)){
+ codeword_TB0 = dlsch0_harq->codeword;
+ codeword_TB1 = dlsch1_harq->codeword;
dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid];
dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
-#ifdef DEBUG_HARQ
- printf("[DEMOD] I am assuming both TBs are active\n");
-#endif
- }
- else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) &&
- (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) {
- codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword;
+
+ #ifdef DEBUG_HARQ
+ printf("[DEMOD] I am assuming both TBs are active\n");
+ #endif
+
+ } else if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status != ACTIVE) ) {
+ codeword_TB0 = dlsch0_harq->codeword;
+ codeword_TB1 = -1;
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
dlsch1_harq = NULL;
- codeword_TB1 = -1;
-#ifdef DEBUG_HARQ
- printf("[DEMOD] I am assuming only TB0 is active\n");
-#endif
- }
- else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) &&
- (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ){
- codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword;
- dlsch0_harq = dlsch[1]->harq_processes[harq_pid];
- dlsch1_harq = NULL;
+
+ #ifdef DEBUG_HARQ
+ printf("[DEMOD] I am assuming only TB0 is active\n");
+ #endif
+
+ } else if ((dlsch0_harq->status != ACTIVE) && (dlsch1_harq->status == ACTIVE)){
codeword_TB0 = -1;
-#ifdef DEBUG_HARQ
- printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch0_harq->codeword);
-#endif
- }
- else {
- LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n",nr_tti_rx);
+ codeword_TB1 = dlsch1_harq->codeword;
+ dlsch0_harq = NULL;
+ dlsch1_harq = dlsch[1]->harq_processes[codeword_TB1];
+
+ #ifdef DEBUG_HARQ
+ printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch1_harq->codeword);
+ #endif
+
+ LOG_E(PHY, "[UE][FATAL] DLSCH: TB0 not active and TB1 active case is not supported\n");
+ return -1;
+
+ } else {
+ LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx);
return(-1);
}
- beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id];
- break;
- default:
- LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n",nr_tti_rx,type);
- return(-1);
- break;
+ break;
+
+ default:
+ LOG_E(PHY, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type);
+ return(-1);
+ break;
+
}
-#ifdef DEBUG_HARQ
- printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode);
- printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
-#endif
+
+ if (dlsch0_harq == NULL) {
+ LOG_E(PHY, "Done\n");
+ return -1;
+ }
+
+ dlsch0_harq->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
+ dlsch0_harq->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
+
+ #ifdef DEBUG_HARQ
+ printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode);
+ printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
+ #endif
start_rb = dlsch0_harq->start_rb;
nb_rb_pdsch = dlsch0_harq->nb_rb;
@@ -269,7 +281,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
return(-1);
}
-
if (dlsch0_harq->mimo_mode==NR_DUALSTREAM) {
DevAssert(dlsch1_harq);
}
@@ -363,7 +374,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
nr_tti_rx,
ue->high_speed_flag,
frame_parms);
-
+
} /*else if(beamforming_mode>7) {
LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n");
}*/
@@ -624,7 +635,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
write_output("rho2_mrc.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
} */
}
- }
+ }
//printf("start compute LLR\n");
if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
@@ -655,19 +666,19 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
// -> // compute @pointer where llrs should filled for this ofdm-symbol
if (first_symbol_flag==1) pdsch_vars[eNB_id]->llr_offset[symbol-1] = 0;
- llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol-1];
- //pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[eNB_id]->llr[0];
- //pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[eNB_id]->llr[1];
- pllr_symbol_layer0 = pdsch_vars[eNB_id]->layer_llr[0];
- pllr_symbol_layer1 = pdsch_vars[eNB_id]->layer_llr[1];
- pllr_symbol_layer0 += llr_offset_symbol;
- pllr_symbol_layer1 += llr_offset_symbol;
- pllr_symbol_cw0 = pdsch_vars[eNB_id]->llr[0];
- pllr_symbol_cw1 = pdsch_vars[eNB_id]->llr[1];
- pllr_symbol_cw0 += llr_offset_symbol;
- pllr_symbol_cw1 += llr_offset_symbol;
-
- pdsch_vars[eNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol;
+ llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol-1];
+ //pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[eNB_id]->llr[0];
+ //pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[eNB_id]->llr[1];
+ pllr_symbol_layer0 = pdsch_vars[eNB_id]->layer_llr[0];
+ pllr_symbol_layer1 = pdsch_vars[eNB_id]->layer_llr[1];
+ pllr_symbol_layer0 += llr_offset_symbol;
+ pllr_symbol_layer1 += llr_offset_symbol;
+ pllr_symbol_cw0 = pdsch_vars[eNB_id]->llr[0];
+ pllr_symbol_cw1 = pdsch_vars[eNB_id]->llr[1];
+ pllr_symbol_cw0 += llr_offset_symbol;
+ pllr_symbol_cw1 += llr_offset_symbol;
+
+ pdsch_vars[eNB_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",
symbol,
@@ -689,13 +700,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
case 2 :
if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
nr_dlsch_qpsk_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pllr_symbol_cw0,
- symbol,
- len,
- first_symbol_flag,
- nb_rb,
- beamforming_mode);
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pllr_symbol_cw0,
+ symbol,
+ len,
+ first_symbol_flag,
+ nb_rb,
+ beamforming_mode);
} else if (codeword_TB0 == -1){
@@ -964,46 +975,47 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
return(-1);
break;
}
+
if (dlsch1_harq) {
- switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) {
- case 2 :
- if (rx_type==rx_standard) {
- nr_dlsch_qpsk_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pllr_symbol_cw0,
- symbol,len,first_symbol_flag,nb_rb,
- beamforming_mode);
+ switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) {
+ case 2 :
+ if (rx_type==rx_standard) {
+ nr_dlsch_qpsk_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pllr_symbol_cw0,
+ symbol,len,first_symbol_flag,nb_rb,
+ beamforming_mode);
+ }
+ break;
+ case 4:
+ if (rx_type==rx_standard) {
+ nr_dlsch_16qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pdsch_vars[eNB_id]->llr[0],
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ symbol,len,first_symbol_flag,nb_rb,
+ pdsch_vars[eNB_id]->llr128,
+ beamforming_mode);
+ }
+ break;
+ case 6 :
+ if (rx_type==rx_standard) {
+ nr_dlsch_64qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pllr_symbol_cw0,
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ pdsch_vars[eNB_id]->dl_ch_magb0,
+ symbol,len,first_symbol_flag,nb_rb,
+ pdsch_vars[eNB_id]->llr_offset[symbol],
+ beamforming_mode);
+ }
+ break;
+ default:
+ LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
+ return(-1);
+ break;
}
- break;
- case 4:
- if (rx_type==rx_standard) {
- nr_dlsch_16qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id]->llr[0],
- pdsch_vars[eNB_id]->dl_ch_mag0,
- symbol,len,first_symbol_flag,nb_rb,
- pdsch_vars[eNB_id]->llr128,
- beamforming_mode);
- }
- break;
- case 6 :
- if (rx_type==rx_standard) {
- nr_dlsch_64qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pllr_symbol_cw0,
- pdsch_vars[eNB_id]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_magb0,
- symbol,len,first_symbol_flag,nb_rb,
- pdsch_vars[eNB_id]->llr_offset[symbol],
- beamforming_mode);
- }
- break;
- default:
- LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
- return(-1);
- break;
- }
- }
+ }
//nr_dlsch_deinterleaving(symbol,bundle_L,(int16_t*)pllr_symbol_cw0,(int16_t*)pllr_symbol_cw0_deint, nb_rb_pdsch);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index 61748a8e56..5c480d6646 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -38,6 +38,7 @@
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
//#include "SCHED/defs.h"
//#include "SCHED/extern.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common_lib.h"
#include
@@ -135,7 +136,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
stop_meas(&ue->dlsch_channel_estimation_stats);
#endif
- current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im+current_ssb->c_re;
+ current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im;
// generate a list of SSB structures
if (best_ssb == NULL)
@@ -213,6 +214,9 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode,
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
int ret=-1;
int rx_power=0; //aarx,
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN);
+
LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", fp->N_RB_DL);
@@ -477,6 +481,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode,
}
// exit_fun("debug exit");
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_OUT);
return ret;
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index 60306d8e53..612dc6283d 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -505,7 +505,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
return(-1);
}
*/
- if (symbol==1) {
+ if (symbol==2) {
nr_pbch_quantize(pbch_e_rx,
(short *)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]),
144);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
index 013b5ca4a6..79c542cd61 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
@@ -19,13 +19,13 @@
* contact@openairinterface.org
*/
-/*! \file PHY/LTE_TRANSPORT/prach_common.c
- * \brief Common routines for UE/eNB PRACH physical channel V8.6 2009-03
- * \author R. Knopp
- * \date 2011
- * \version 0.1
- * \company Eurecom
- * \email: knopp@eurecom.fr
+/*! \file PHY/NR_TRANSPORT/nr_prach.c
+ * \brief Routines for UE PRACH physical channel
+ * \author R. Knopp, G. Casati
+ * \date 2019
+ * \version 0.2
+ * \company Eurecom, Fraunhofer IIS
+ * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note
* \warning
*/
@@ -35,16 +35,14 @@
#include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
-#include
#include "T.h"
-#include
-
-
+//#define NR_PRACH_DEBUG 1
extern uint16_t NCS_unrestricted_delta_f_RA_125[16];
extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15];
@@ -60,77 +58,77 @@ extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
+extern const char *prachfmt[9];
+extern const char *prachfmt03[4];
+// Note:
+// - prach_fmt_id is an ID used to map to the corresponding PRACH format value in prachfmt
+// WIP todo:
+// - take prach start symbol into account
+// - idft for short sequence assumes we are transmitting starting in symbol 0 of a PRACH slot
+// - Assumes that PRACH SCS is same as PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below
+// - Preamble index different from 0 is not detected by gNB
+int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
-
-
-
-
-
-
-int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf )
-{
-
- //lte_frame_type_t frame_type = ue->frame_parms.frame_type;
- //uint8_t tdd_config = ue->frame_parms.tdd_config;
NR_DL_FRAME_PARMS *fp=&ue->frame_parms;
- uint16_t rootSequenceIndex = fp->prach_config_common.rootSequenceIndex;
- uint8_t prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
- uint8_t Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
- uint8_t restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
- uint8_t preamble_index = ue->prach_resources[eNB_id]->ra_PreambleIndex;
- //uint8_t tdd_mapindex = ue->prach_resources[eNB_id]->ra_TDD_map_index;
- int16_t *prachF = ue->prach_vars[eNB_id]->prachF;
+ fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config;
+ NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_id];
+ fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu;
+
+ uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found;
+ uint16_t rootSequenceIndex, prach_fmt_id, NCS, *prach_root_sequence_map, preamble_offset = 0;
+ uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx;
int16_t prach_tmp[98304*2*4] __attribute__((aligned(32)));
- int16_t *prach = prach_tmp;
- int16_t *prach2;
- int16_t amp = ue->prach_vars[eNB_id]->amp;
- int16_t Ncp;
- uint16_t NCS=0;
- uint16_t *prach_root_sequence_map;
- uint16_t preamble_offset,preamble_shift;
- uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar;
- uint16_t d_start=-1,numshift;
- uint16_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,fp->frame_type,fp->freq_range);
- //uint8_t Nsp=2;
- //uint8_t f_ra,t1_ra;
- uint16_t N_ZC = (prach_fmt<4)?839:139;
- uint8_t not_found;
- int16_t *Xu;
- uint16_t u;
- int32_t Xu_re,Xu_im;
- uint16_t offset,offset2;
- int prach_start;
- int i, prach_len=0;
- uint16_t first_nonzero_root_idx=0;
+ int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu;
+ int32_t Xu_re, Xu_im, samp_count;
+ int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k;
+ //int restricted_Type;
-#if defined(OAI_USRP)
- prach_start = (ue->rx_offset+subframe*fp->samples_per_subframe-ue->hw_timing_advance-ue->N_TA_offset);
-#ifdef NR_PRACH_DEBUG
- LOG_I(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id,
- prach_start,
- ue->rx_offset,
- ue->hw_timing_advance,
- ue->N_TA_offset);
-#endif
+ prach = prach_tmp;
+ prachF = ue->prach_vars[gNB_id]->prachF;
+ amp = ue->prach_vars[gNB_id]->amp;
+ Mod_id = ue->Mod_id;
+ prach_sequence_length = nrUE_config->prach_config.prach_sequence_length;
+ N_ZC = (prach_sequence_length == 0) ? 839:139;
+ mu = nrUE_config->prach_config.prach_sub_c_spacing;
+ restricted_set = prach_pdu->restricted_set;
+ rootSequenceIndex = prach_pdu->root_seq_id;
+ n_ra_prb = prach_pdu->freq_msg1;
+ NCS = prach_pdu->num_cs;
+ prach_fmt_id = prach_pdu->prach_format;
+ preamble_index = prach_resources->ra_PreambleIndex;
+ fd_occasion = 0;
+ prach_len = 0;
+ dftlen = 0;
+ first_nonzero_root_idx = 0;
+ kbar = 1;
+ K = 24;
+ k = 12*n_ra_prb - 6*fp->N_RB_UL;
+ //prachStartSymbol = prach_config_pdu->prach_start_symbol
+ //restricted_Type = 0;
+
+ compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length,
+ nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].num_root_sequences,
+ nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
+ ue->X_u);
+
+ if (mu == 0)
+ samp_count = fp->samples_per_subframe;
+ else
+ samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0;
+
+ #if defined (OAI_USRP)
+ prach_start = (ue->rx_offset + slot*samp_count - ue->hw_timing_advance - ue->N_TA_offset);
+ #else //normal case (simulation)
+ prach_start = slot*samp_count - ue->N_TA_offset;
+ #endif
if (prach_start<0)
- prach_start+=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME);
-
- if (prach_start>=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
- prach_start-=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME);
-
-#else //normal case (simulation)
- prach_start = subframe*fp->samples_per_subframe-ue->N_TA_offset;
- LOG_D(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id,
- prach_start,
- ue->rx_offset,
- ue->hw_timing_advance,
- ue->N_TA_offset);
-
-#endif
+ prach_start += (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME);
+ if (prach_start >= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME))
+ prach_start -= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME);
// First compute physical root sequence
/************************************************************************
@@ -140,41 +138,19 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
* NOTE: Restricted set type B is not implemented
*************************************************************************/
- int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME
- if (prach_fmt<3){
- if (restricted_set == 0) {
- NCS = NCS_unrestricted_delta_f_RA_125[Ncs_config];
- } else {
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[Ncs_config]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[Ncs_config]; // for TypeB, this is hardcoded. FIXME
- }
- }
- if (prach_fmt==3){
- if (restricted_set == 0) {
- NCS = NCS_unrestricted_delta_f_RA_5[Ncs_config];
- } else {
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[Ncs_config]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[Ncs_config]; // for TypeB, this is hardcoded. FIXME
- }
- }
- if (prach_fmt>3){
- NCS = NCS_unrestricted_delta_f_RA_15[Ncs_config];
- }
-
- prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
-
- // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
- preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
+ prach_root_sequence_map = (prach_sequence_length == 0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
if (restricted_set == 0) {
+ // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
+ preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
// This is the \nu corresponding to the preamble index
preamble_shift = (NCS==0)? 0 : (preamble_index % (N_ZC/NCS));
preamble_shift *= NCS;
} else { // This is the high-speed case
-#ifdef NR_PRACH_DEBUG
- LOG_I(PHY,"[UE %d] High-speed mode, NCS_config %d\n",ue->Mod_id,Ncs_config);
-#endif
+ #ifdef NR_PRACH_DEBUG
+ LOG_I(PHY, "PRACH [UE %d] High-speed mode, NCS %d\n", Mod_id, NCS);
+ #endif
not_found = 1;
preamble_index0 = preamble_index;
@@ -185,8 +161,9 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
while (not_found == 1) {
// current root depending on rootSequenceIndex and preamble_offset
int index = (rootSequenceIndex + preamble_offset) % N_ZC;
+ uint16_t n_group_ra = 0;
- if (prach_fmt<4) {
+ if (prach_fmt_id<4) {
// prach_root_sequence_map points to prach_root_sequence_map0_3
DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) );
} else {
@@ -196,8 +173,6 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
u = prach_root_sequence_map[index];
- uint16_t n_group_ra = 0;
-
if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) {
n_shift_ra = nr_du[u]/NCS;
d_start = (nr_du[u]<<1) + (n_shift_ra * NCS);
@@ -231,43 +206,49 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
}
// now generate PRACH signal
-#ifdef NR_PRACH_DEBUG
-
- if (NCS>0)
- LOG_D(PHY,"Generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %x, prach_ConfigIndex %d, NCS %d (NCS_config %d, N_ZC/NCS %d): Preamble_offset %d, Preamble_shift %d\n",
- rootSequenceIndex,preamble_index,prach_fmt,prach_ConfigIndex,NCS,Ncs_config,N_ZC/NCS,
- preamble_offset,preamble_shift);
-
-#endif
+ #ifdef NR_PRACH_DEBUG
+ if (NCS>0)
+ LOG_I(PHY, "PRACH [UE %d] generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d\n", Mod_id,
+ rootSequenceIndex,
+ preamble_index,
+ prach_sequence_length == 0 ? prachfmt03[prach_fmt_id] : prachfmt[prach_fmt_id],
+ NCS,
+ N_ZC,
+ preamble_offset,
+ preamble_shift);
+ #endif
// nsymb = (frame_parms->Ncp==0) ? 14:12;
- // subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*subframe*nsymb;
- int kbar = 1;
- int K = 24;
- if (prach_fmt == 3) {
- K=4;
- kbar=10;
+ // subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*slot*nsymb;
+
+ if (prach_sequence_length == 0 && prach_fmt_id == 3) {
+ K = 4;
+ kbar = 10;
+ } else if (prach_sequence_length == 1) {
+ K = 1;
+ kbar = 2;
}
- else if (prach_fmt > 3) {
- // Note: Assumes that PRACH SCS is same as PUSCH SCS
- K=1;
- kbar=2;
- }
- int n_ra_prb = fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart;
- int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
- k = (12*n_ra_prb) - 6*fp->N_RB_UL;
+ if (k<0)
+ k += fp->ofdm_symbol_size;
- if (k<0) k+=fp->ofdm_symbol_size;
+ k *= K;
+ k += kbar;
+ k *= 2;
- k*=K;
- k+=kbar;
-
- LOG_D(PHY,"placing prach in position %d\n",k);
- k*=2;
+ LOG_I(PHY, "PRACH [UE %d] in slot %d, placing PRACH in position %d, msg1 frequency start %d, preamble_offset %d, first_nonzero_root_idx %d\n", Mod_id,
+ slot,
+ k,
+ n_ra_prb,
+ preamble_offset,
+ first_nonzero_root_idx);
Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx];
+ #if defined (PRACH_WRITE_OUTPUT_DEBUG)
+ LOG_M("X_u.m", "X_u", (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx], N_ZC, 1, 1);
+ #endif
+
/********************************************************
*
* In function init_prach_tables:
@@ -282,10 +263,86 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
*
*********************************************************/
- AssertFatal(prach_fmt>3,"prach_fmt<=3: Fix this for other formats\n");
- int dftlen=2048;
- if (fp->N_RB_UL >= 137) dftlen=4096;
- if (fp->threequarter_fs==1) dftlen=(3*dftlen)/4;
+ if (fp->N_RB_UL <= 100)
+ AssertFatal(1 == 0, "N_RB_UL %d not support for NR PRACH yet\n", fp->N_RB_UL);
+ else if (fp->N_RB_UL < 137) {
+ if (fp->threequarter_fs == 0) {
+ //40 MHz @ 61.44 Ms/s
+ //50 MHz @ 61.44 Ms/s
+ if (prach_sequence_length == 0) {
+ if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+ dftlen = 49152;
+ if (prach_fmt_id == 3)
+ dftlen = 12288;
+ } // 839 sequence
+ else {
+ switch (mu){
+ case 1:
+ dftlen = 2048;
+ break;
+ default:
+ AssertFatal(1 == 0, "Shouldn't get here\n");
+ break;
+ }
+ }
+ } else { // threequarter sampling
+ // 40 MHz @ 46.08 Ms/s
+ if (prach_sequence_length == 0) {
+ AssertFatal(fp->N_RB_UL <= 107, "cannot do 108..136 PRBs with 3/4 sampling\n");
+ if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+ dftlen = 36864;
+ if (prach_fmt_id == 3)
+ dftlen = 9216;
+ } else {
+ switch (mu){
+ case 1:
+ dftlen = 1536;
+ break;
+ default:
+ AssertFatal(1 == 0, "Shouldn't get here\n");
+ break;
+ }
+ } // short format
+ } // 3/4 sampling
+ } // <=50 MHz BW
+ else if (fp->N_RB_UL <= 273) {
+ if (fp->threequarter_fs == 0) {
+ //80,90,100 MHz @ 122.88 Ms/s
+ if (prach_sequence_length == 0) {
+ if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+ dftlen = 98304;
+ if (prach_fmt_id == 3)
+ dftlen = 24576;
+ }
+ } else { // threequarter sampling
+ switch (mu){
+ case 1:
+ dftlen = 4096;
+ break;
+ default:
+ AssertFatal(1 == 0, "Shouldn't get here\n");
+ break;
+ }
+ }
+ } else {
+ AssertFatal(fp->N_RB_UL <= 217, "cannot do more than 217 PRBs with 3/4 sampling\n");
+ // 80 MHz @ 92.16 Ms/s
+ if (prach_sequence_length == 0) {
+ if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+ dftlen = 73728;
+ if (prach_fmt_id == 3)
+ dftlen = 18432;
+ } else {
+ switch (mu){
+ case 1:
+ dftlen = 3072;
+ break;
+ default:
+ AssertFatal(1 == 0, "Shouldn't get here\n");
+ break;
+ }
+ }
+ }
for (offset=0,offset2=0; offset>15);
prachF[k++]= ((Xu_re*nr_ru[offset2<<1]) - (Xu_im*nr_ru[1+(offset2<<1)]))>>15;
prachF[k++]= ((Xu_im*nr_ru[offset2<<1]) + (Xu_re*nr_ru[1+(offset2<<1)]))>>15;
+
if (k==dftlen) k=0;
}
- switch (fp->N_RB_UL) {
- case 6:
- memset((void*)prachF,0,4*1536);
- break;
+ #if defined (PRACH_WRITE_OUTPUT_DEBUG)
+ LOG_M("prachF.m", "prachF", &prachF[1804], 1024, 1, 1);
+ LOG_M("Xu.m", "Xu", Xu, N_ZC, 1, 1);
+ #endif
- case 15:
- memset((void*)prachF,0,4*3072);
- break;
+ if (prach_sequence_length == 0) {
- case 25:
- memset((void*)prachF,0,4*6144);
- break;
+ AssertFatal(prach_fmt_id < 4, "Illegal PRACH format %d for sequence length 839\n", prach_fmt_id);
- case 50:
- memset((void*)prachF,0,4*12288);
- break;
+ switch (prach_fmt_id) {
+ case 0:
+ Ncp = 3168;
+ break;
+ case 1:
+ Ncp = 21024;
+ break;
+ case 2:
+ Ncp = 4688;
+ break;
+ case 3:
+ Ncp = 3168;
+ break;
+ }
- case 75:
- memset((void*)prachF,0,4*18432);
- break;
+ } else {
- case 100:
- if (fp->threequarter_fs == 0)
- memset((void*)prachF,0,4*24576);
- else
- memset((void*)prachF,0,4*18432);
- break;
+ //LOG_D(PHY, "PRACH [UE %d] in slot %d, format %d, msg1 frequency start %d startSymbol %d \n", Mod_id, slot, prachfmt[prach_fmt_id], n_ra_prb, prachStartSymbol);
- case 106:
- memset((void*)prachF,0,4*24576);
- break;
-}
-
- int mu = 1; // numerology is hardcoded. FIXME!!!
- switch (prach_fmt) {
- case 0:
- Ncp = 3168;
- break;
-
- case 1:
- Ncp = 2*21024;
- break;
-
- case 2:
- Ncp = 4688;
- break;
-
- case 3:
- Ncp = 3168;
- break;
-
- case 0xa1:
- Ncp = 288/(1<N_RB_UL <= 100)
AssertFatal(1==0,"N_RB_UL %d not supported for NR PRACH yet\n",fp->N_RB_UL);
else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s
- if (fp->threequarter_fs==0) { //61.44 Ms/s
+ if (fp->threequarter_fs == 0) { // full sampling @ 61.44 Ms/s
Ncp<<=1;
// This is after cyclic prefix (Ncp<<1 samples for 30.72 Ms/s, Ncp<<2 samples for 61.44 Ms/s
prach2 = prach+(Ncp<<1);
- if (prach_fmt == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
- idft(IDFT_49152,prachF,prach2,1);
- // here we have |empty | Prach49152|
- memmove(prach,prach+(49152<<1),(Ncp<<3));
- // here we have |Prefix | Prach49152|
- prach_len = 49152+Ncp;
- dftlen=49152;
+ if (prach_sequence_length == 0){
+ if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
+ idft(IDFT_49152,prachF,prach2,1);
+ // here we have |empty | Prach49152|
+ memmove(prach,prach+(49152<<1),(Ncp<<2));
+ // here we have |Prefix | Prach49152|
+ prach_len = 49152+Ncp;
+ } else if (prach_fmt_id == 1) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
+ idft(IDFT_49152,prachF,prach2,1);
+ memmove(prach2+(49152<<1),prach2,(49152<<2));
+ // here we have |empty | Prach49152 | Prach49152|
+ memmove(prach,prach+(49152<<2),(Ncp<<2));
+ // here we have |Prefix | Prach49152 | Prach49152|
+ prach_len = (49152*2)+Ncp;
+ } else if (prach_fmt_id == 2) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
+ idft(IDFT_49152,prachF,prach2,1);
+ memmove(prach2+(49152<<1),prach2,(49152<<2));
+ // here we have |empty | Prach49152 | Prach49152| empty49152 | empty49152
+ memmove(prach2+(49152<<2),prach2,(49152<<3));
+ // here we have |empty | Prach49152 | Prach49152| Prach49152 | Prach49152
+ memmove(prach,prach+(49152<<3),(Ncp<<2));
+ // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152
+ prach_len = (49152*4)+Ncp;
+ } else if (prach_fmt_id == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
+ idft(IDFT_12288,prachF,prach2,1);
+ memmove(prach2+(12288<<1),prach2,(12288<<2));
+ // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288
+ memmove(prach2+(12288<<2),prach2,(12288<<3));
+ // here we have |empty | Prach12288 | Prach12288| Prach12288 | Prach12288
+ memmove(prach,prach+(12288<<3),(Ncp<<2));
+ // here we have |Prefix | Prach12288 | Prach12288| Prach12288 | Prach12288
+ prach_len = (12288*4)+Ncp;
+ }
+ } else { // short PRACH sequence
+ if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
+ Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_2048,prachF,prach2,1);
+ // here we have |empty | Prach2048 |
+ if (prach_fmt_id != 7) {
+ memmove(prach2+(2048<<1),prach2,(2048<<2));
+ prach_len = (2048*2)+Ncp;
+ }
+ else prach_len = (2048*1)+Ncp;
+ memmove(prach,prach+(2048<<1),(Ncp<<2));
+ // here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) |
+ } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x2048
+ Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_2048,prachF,prach2,1);
+ // here we have |empty | Prach2048 |
+ memmove(prach2+(2048<<1),prach2,(2048<<2));
+ // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 |
+ memmove(prach2+(2048<<2),prach2,(2048<<3));
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 |
+ memmove(prach,prach+(2048<<1),(Ncp<<2));
+ // here we have |Prefix | Prach2048 |
+ prach_len = (2048*4)+Ncp;
+ } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x2048
+ Ncp+=32;
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_2048,prachF,prach2,1);
+ // here we have |empty | Prach2048 |
+ memmove(prach2+(2048<<1),prach2,(2048<<2));
+ // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048
+ memmove(prach2+(2048<<2),prach2,(2048<<3));
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048
+ memmove(prach2+(2048<<3),prach2,(2048<<3));
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048
+ memmove(prach,prach+(2048<<1),(Ncp<<2));
+ // here we have |Prefix | Prach2048 |
+ prach_len = (2048*6)+Ncp;
+ } else if (prach_fmt_id == 6) { // 12x2048
+ Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_2048,prachF,prach2,1);
+ // here we have |empty | Prach2048 |
+ memmove(prach2+(2048<<1),prach2,(2048<<2));
+ // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048
+ memmove(prach2+(2048<<2),prach2,(2048<<3));
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048
+ memmove(prach2+(2048<<3),prach2,(2048<<3));
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048
+ memmove(prach2+(2048<<1)*6,prach2,(2048<<2)*6);
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048|
+ memmove(prach,prach+(2048<<1),(Ncp<<2));
+ // here we have |Prefix | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048|
+ prach_len = (2048*12)+Ncp;
+ }
}
- else if (prach_fmt == 1) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
- idft(IDFT_49152,prachF,prach2,1);
- memmove(prach2+(49152<<1),prach2,(49152<<2));
- // here we have |empty | Prach49152 | Prach49152|
- memmove(prach,prach+(49152<<2),(Ncp<<3));
- // here we have |Prefix | Prach49152 | Prach49152|
- prach_len = (49152*2)+Ncp;
- dftlen=49152;
- }
- else if (prach_fmt == 2) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
- idft(IDFT_49152,prachF,prach2,1);
- memmove(prach2+(49152<<1),prach2,(49152<<2));
- // here we have |empty | Prach49152 | Prach49152| empty49152 | empty49152
- memmove(prach2+(49152<<2),prach2,(49152<<3));
- // here we have |empty | Prach49152 | Prach49152| Prach49152 | Prach49152
- memmove(prach,prach+(49152<<3),(Ncp<<3));
- // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152
- prach_len = (49152*4)+Ncp;
- dftlen=49152;
- }
- else if (prach_fmt == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
- idft(IDFT_12288,prachF,prach2,1);
- memmove(prach2+(12288<<1),prach2,(12288<<2));
- // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288
- memmove(prach2+(12288<<2),prach2,(12288<<3));
- // here we have |empty | Prach12288 | Prach12288| Prach12288 | Prach12288
- memmove(prach,prach+(12288<<3),(Ncp<<3));
- // here we have |Prefix | Prach12288 | Prach12288| Prach12288 | Prach12288
- prach_len = (12288*4)+Ncp;
- dftlen=12288;
- }
- else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
- prach2 = prach+(Ncp<<1);
- idft(IDFT_2048,prachF,prach2,1);
- dftlen=2048;
- // here we have |empty | Prach2048 |
- if (prach_fmt != 0xc0) {
- memmove(prach2+(2048<<1),prach2,(2048<<2));
- prach_len = (2048*2)+Ncp;
- }
- else prach_len = (2048*1)+Ncp;
- memmove(prach,prach+(2048<<1),(Ncp<<2));
- // here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) |
- }
- else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x2048
- idft(IDFT_2048,prachF,prach2,1);
- dftlen=2048;
- // here we have |empty | Prach2048 |
- memmove(prach2+(2048<<1),prach2,(2048<<2));
- // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 |
- memmove(prach2+(2048<<2),prach2,(2048<<3));
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 |
- memmove(prach,prach+(2048<<1),(Ncp<<2));
- // here we have |Prefix | Prach2048 |
- prach_len = (2048*4)+Ncp;
- }
- else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x2048
- prach2 = prach+(Ncp<<1);
- idft(IDFT_2048,prachF,prach2,1);
- dftlen=2048;
- // here we have |empty | Prach2048 |
- memmove(prach2+(2048<<1),prach2,(2048<<2));
- // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048
- memmove(prach2+(2048<<2),prach2,(2048<<3));
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048
- memmove(prach2+((2048<<1)*3),prach2,(2048<<3));
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048
- memmove(prach,prach+(2048<<1),(Ncp<<2));
- // here we have |Prefix | Prach2048 |
- prach_len = (2048*6)+Ncp;
- }
- else if (prach_fmt == 0xb4) { // 12x2048
- idft(IDFT_2048,prachF,prach2,1);
- dftlen=2048;
- // here we have |empty | Prach2048 |
- memmove(prach2+(2048<<1),prach2,(2048<<2));
- // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048
- memmove(prach2+(2048<<2),prach2,(2048<<3));
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048
- memmove(prach2+(2048<<3),prach2,(2048<<3));
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048
- memmove(prach2+(2048<<1)*6,prach2,(2048<<2)*6);
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048|
- memmove(prach,prach+(2048<<1),(Ncp<<2));
- // here we have |Prefix | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048|
- prach_len = (2048*12)+Ncp;
- }
-
- }
- else { // 46.08 Ms/s
+ } else { // threequarter sampling @ 46.08 Ms/s
Ncp = (Ncp*3)/2;
prach2 = prach+(Ncp<<1);
- if (prach_fmt == 0) {
- idft(IDFT_36864,prachF,prach2,1);
- dftlen=36864;
- // here we have |empty | Prach73728|
- memmove(prach,prach+(36864<<1),(Ncp<<2));
- // here we have |Prefix | Prach73728|
- prach_len = (36864*1)+Ncp;
+ if (prach_sequence_length == 0){
+ if (prach_fmt_id == 0) {
+ idft(IDFT_36864,prachF,prach2,1);
+ // here we have |empty | Prach73728|
+ memmove(prach,prach+(36864<<1),(Ncp<<2));
+ // here we have |Prefix | Prach73728|
+ prach_len = (36864*1)+Ncp;
+ } else if (prach_fmt_id == 1) {
+ idft(IDFT_36864,prachF,prach2,1);
+ memmove(prach2+(36864<<1),prach2,(36864<<2));
+ // here we have |empty | Prach73728 | Prach73728|
+ memmove(prach,prach+(36864<<2),(Ncp<<2));
+ // here we have |Prefix | Prach73728 | Prach73728|
+ prach_len = (36864*2)+Ncp;
+ } else if (prach_fmt_id == 2) {
+ idft(IDFT_36864,prachF,prach2,1);
+ memmove(prach2+(36864<<1),prach2,(36864<<2));
+ // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
+ memmove(prach2+(36864<<2),prach2,(36864<<3));
+ // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728
+ memmove(prach,prach+(36864<<3),(Ncp<<2));
+ // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728
+ prach_len = (36864*4)+Ncp;
+ } else if (prach_fmt_id == 3) {
+ idft(IDFT_9216,prachF,prach2,1);
+ memmove(prach2+(9216<<1),prach2,(9216<<2));
+ // here we have |empty | Prach9216 | Prach9216| empty9216 | empty9216
+ memmove(prach2+(9216<<2),prach2,(9216<<3));
+ // here we have |empty | Prach9216 | Prach9216| Prach9216 | Prach9216
+ memmove(prach,prach+(9216<<3),(Ncp<<2));
+ // here we have |Prefix | Prach9216 | Prach9216| Prach9216 | Prach9216
+ prach_len = (9216*4)+Ncp;
+ }
+ } else { // short sequence
+ if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
+ Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_1536,prachF,prach2,1);
+ // here we have |empty | Prach1536 |
+ if (prach_fmt_id != 7) {
+ memmove(prach2+(1536<<1),prach2,(1536<<2));
+ prach_len = (1536*2)+Ncp;
+ } else prach_len = (1536*1)+Ncp;
+
+ memmove(prach,prach+(1536<<1),(Ncp<<2));
+ // here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) |
+
+ } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x1536
+
+ Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_1536,prachF,prach2,1);
+ // here we have |empty | Prach1536 |
+ memmove(prach2+(1536<<1),prach2,(1536<<2));
+ // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 |
+ memmove(prach2+(1536<<2),prach2,(1536<<3));
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 |
+ memmove(prach,prach+(1536<<1),(Ncp<<2));
+ // here we have |Prefix | Prach1536 |
+ prach_len = (1536*4)+Ncp;
+ } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x1536
+ Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_1536,prachF,prach2,1);
+ // here we have |empty | Prach1536 |
+ memmove(prach2+(1536<<1),prach2,(1536<<2));
+ // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536
+ memmove(prach2+(1536<<2),prach2,(1536<<3));
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536
+ memmove(prach2+(1536<<3),prach2,(1536<<3));
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536
+ memmove(prach,prach+(1536<<1),(Ncp<<2));
+ // here we have |Prefix | Prach1536 |
+ prach_len = (1536*6)+Ncp;
+ } else if (prach_fmt_id == 6) { // 12x1536
+ Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_1536,prachF,prach2,1);
+ // here we have |empty | Prach1536 |
+ memmove(prach2+(1536<<1),prach2,(1536<<2));
+ // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536
+ memmove(prach2+(1536<<2),prach2,(1536<<3));
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536
+ memmove(prach2+(1536<<3),prach2,(1536<<3));
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536
+ memmove(prach2+(1536<<1)*6,prach2,(1536<<2)*6);
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536|
+ memmove(prach,prach+(1536<<1),(Ncp<<2));
+ // here we have |Prefix | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536|
+ prach_len = (1536*12)+Ncp;
+ }
}
- else if (prach_fmt == 1) {
- idft(IDFT_36864,prachF,prach2,1);
- dftlen=36864;
- memmove(prach2+(36864<<1),prach2,(36864<<2));
- // here we have |empty | Prach73728 | Prach73728|
- memmove(prach,prach+(36864<<2),(Ncp<<2));
- // here we have |Prefix | Prach73728 | Prach73728|
- prach_len = (36864*2)+Ncp;
- }
- if (prach_fmt == 2) {
- idft(IDFT_36864,prachF,prach2,1);
- dftlen=36864;
- memmove(prach2+(36864<<1),prach2,(36864<<2));
- // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
- memmove(prach2+(36864<<2),prach2,(36864<<3));
- // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728
- memmove(prach,prach+(36864<<3),(Ncp<<2));
- // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728
- prach_len = (36864*4)+Ncp;
- }
- else if (prach_fmt == 3) {
- idft(IDFT_9216,prachF,prach2,1);
- dftlen=36864;
- memmove(prach2+(9216<<1),prach2,(9216<<2));
- // here we have |empty | Prach9216 | Prach9216| empty9216 | empty9216
- memmove(prach2+(9216<<2),prach2,(9216<<3));
- // here we have |empty | Prach9216 | Prach9216| Prach9216 | Prach9216
- memmove(prach,prach+(9216<<3),(Ncp<<2));
- // here we have |Prefix | Prach9216 | Prach9216| Prach9216 | Prach9216
- prach_len = (9216*4)+Ncp;
- }
- else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
- idft(IDFT_1536,prachF,prach2,1);
- dftlen=1536;
- // here we have |empty | Prach1536 |
- if (prach_fmt != 0xc0)
- memmove(prach2+(1536<<1),prach2,(1536<<2));
- memmove(prach,prach+(1536<<1),(Ncp<<2));
- // here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) |
- prach_len = (1536*2)+Ncp;
- }
- else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x1536
- idft(IDFT_1536,prachF,prach2,1);
- dftlen=1536;
- // here we have |empty | Prach1536 |
- memmove(prach2+(1536<<1),prach2,(1536<<2));
- // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 |
- memmove(prach2+(1536<<2),prach2,(1536<<3));
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 |
- memmove(prach,prach+(1536<<1),(Ncp<<2));
- // here we have |Prefix | Prach1536 |
- prach_len = (1536*4)+Ncp;
- }
- else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x1536
- idft(IDFT_1536,prachF,prach2,1);
- dftlen=1536;
- // here we have |empty | Prach1536 |
- memmove(prach2+(1536<<1),prach2,(1536<<2));
- // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536
- memmove(prach2+(1536<<2),prach2,(1536<<3));
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536
- memmove(prach2+((1536<<1)*3),prach2,(1536<<3));
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536
- memmove(prach,prach+(1536<<1),(Ncp<<2));
- // here we have |Prefix | Prach1536 |
- prach_len = (1536*6)+Ncp;
- }
- else if (prach_fmt == 0xb4) { // 12x1536
- idft(IDFT_1536,prachF,prach2,1);
- dftlen=1536;
- // here we have |empty | Prach1536 |
- memmove(prach2+(1536<<1),prach2,(1536<<2));
- // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536
- memmove(prach2+(1536<<2),prach2,(1536<<3));
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536
- memmove(prach2+(1536<<3),prach2,(1536<<3));
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536
- memmove(prach2+(1536<<1)*6,prach2,(1536<<2)*6);
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536|
- memmove(prach,prach+(1536<<1),(Ncp<<2));
- // here we have |Prefix | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536|
- prach_len = (1536*12)+Ncp;
- }
}
- }
- else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s
- if (fp->threequarter_fs==0) { //122.88 Ms/s
+ } else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s
+ if (fp->threequarter_fs == 0) { // full sampling @ 122.88 Ms/s
Ncp<<=2;
prach2 = prach+(Ncp<<1);
- if (prach_fmt == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s
- idft(IDFT_98304,prachF,prach2,1);
- dftlen=98304;
- // here we have |empty | Prach98304|
- memmove(prach,prach+(98304<<1),(Ncp<<2));
- // here we have |Prefix | Prach98304|
- prach_len = (98304*1)+Ncp;
+ if (prach_sequence_length == 0){
+ if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s
+ idft(IDFT_98304,prachF,prach2,1);
+ // here we have |empty | Prach98304|
+ memmove(prach,prach+(98304<<1),(Ncp<<2));
+ // here we have |Prefix | Prach98304|
+ prach_len = (98304*1)+Ncp;
+ } else if (prach_fmt_id == 1) {
+ idft(IDFT_98304,prachF,prach2,1);
+ memmove(prach2+(98304<<1),prach2,(98304<<2));
+ // here we have |empty | Prach98304 | Prach98304|
+ memmove(prach,prach+(98304<<2),(Ncp<<2));
+ // here we have |Prefix | Prach98304 | Prach98304|
+ prach_len = (98304*2)+Ncp;
+ } else if (prach_fmt_id == 2) {
+ idft(IDFT_98304,prachF,prach2,1);
+ memmove(prach2+(98304<<1),prach2,(98304<<2));
+ // here we have |empty | Prach98304 | Prach98304| empty98304 | empty98304
+ memmove(prach2+(98304<<2),prach2,(98304<<3));
+ // here we have |empty | Prach98304 | Prach98304| Prach98304 | Prach98304
+ memmove(prach,prach+(98304<<3),(Ncp<<2));
+ // here we have |Prefix | Prach98304 | Prach98304| Prach98304 | Prach98304
+ prach_len = (98304*4)+Ncp;
+ } else if (prach_fmt_id == 3) { // 4x6144, Ncp 3168
+ idft(IDFT_24576,prachF,prach2,1);
+ memmove(prach2+(24576<<1),prach2,(24576<<2));
+ // here we have |empty | Prach24576 | Prach24576| empty24576 | empty24576
+ memmove(prach2+(24576<<2),prach2,(24576<<3));
+ // here we have |empty | Prach24576 | Prach24576| Prach24576 | Prach24576
+ memmove(prach,prach+(24576<<3),(Ncp<<2));
+ // here we have |Prefix | Prach24576 | Prach24576| Prach24576 | Prach24576
+ prach_len = (24576*4)+Ncp;
+ }
+ } else { // short sequence
+ if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
+ Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_4096,prachF,prach2,1);
+ // here we have |empty | Prach4096 |
+ if (prach_fmt_id != 7) {
+ memmove(prach2+(4096<<1),prach2,(4096<<2));
+ prach_len = (4096*2)+Ncp;
+ } else prach_len = (4096*1)+Ncp;
+ memmove(prach,prach+(4096<<1),(Ncp<<2));
+ // here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) |
+ } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x4096
+ Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_4096,prachF,prach2,1);
+ // here we have |empty | Prach4096 |
+ memmove(prach2+(4096<<1),prach2,(4096<<2));
+ // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 |
+ memmove(prach2+(4096<<2),prach2,(4096<<3));
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 |
+ memmove(prach,prach+(4096<<1),(Ncp<<2));
+ // here we have |Prefix | Prach4096 |
+ prach_len = (4096*4)+Ncp;
+ } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x4096
+ Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_4096,prachF,prach2,1);
+ // here we have |empty | Prach4096 |
+ memmove(prach2+(4096<<1),prach2,(4096<<2));
+ // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096
+ memmove(prach2+(4096<<2),prach2,(4096<<3));
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096
+ memmove(prach2+(4096<<3),prach2,(4096<<3));
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096
+ memmove(prach,prach+(4096<<1),(Ncp<<2));
+ // here we have |Prefix | Prach4096 |
+ prach_len = (4096*6)+Ncp;
+ } else if (prach_fmt_id == 6) { // 12x4096
+ Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_4096,prachF,prach2,1);
+ // here we have |empty | Prach4096 |
+ memmove(prach2+(4096<<1),prach2,(4096<<2));
+ // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096
+ memmove(prach2+(4096<<2),prach2,(4096<<3));
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096
+ memmove(prach2+(4096<<3),prach2,(4096<<3));
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096
+ memmove(prach2+(4096<<1)*6,prach2,(4096<<2)*6);
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096|
+ memmove(prach,prach+(4096<<1),(Ncp<<2));
+ // here we have |Prefix | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096|
+ prach_len = (4096*12)+Ncp;
+ }
}
- else if (prach_fmt == 1) {
- idft(IDFT_98304,prachF,prach2,1);
- dftlen=98304;
- memmove(prach2+(98304<<1),prach2,(98304<<2));
- // here we have |empty | Prach98304 | Prach98304|
- memmove(prach,prach+(98304<<2),(Ncp<<2));
- // here we have |Prefix | Prach98304 | Prach98304|
- prach_len = (98304*2)+Ncp;
- }
- else if (prach_fmt == 2) {
- idft(IDFT_98304,prachF,prach2,1);
- dftlen=98304;
- memmove(prach2+(98304<<1),prach2,(98304<<2));
- // here we have |empty | Prach98304 | Prach98304| empty98304 | empty98304
- memmove(prach2+(98304<<2),prach2,(98304<<3));
- // here we have |empty | Prach98304 | Prach98304| Prach98304 | Prach98304
- memmove(prach,prach+(98304<<3),(Ncp<<2));
- // here we have |Prefix | Prach98304 | Prach98304| Prach98304 | Prach98304
- prach_len = (98304*4)+Ncp;
- }
- else if (prach_fmt == 3) { // 4x6144, Ncp 3168
- idft(IDFT_24576,prachF,prach2,1);
- dftlen=24576;
- memmove(prach2+(24576<<1),prach2,(24576<<2));
- // here we have |empty | Prach24576 | Prach24576| empty24576 | empty24576
- memmove(prach2+(24576<<2),prach2,(24576<<3));
- // here we have |empty | Prach24576 | Prach24576| Prach24576 | Prach24576
- memmove(prach,prach+(24576<<3),(Ncp<<2));
- // here we have |Prefix | Prach24576 | Prach24576| Prach24576 | Prach24576
- prach_len = (24576*4)+(Ncp<<1);
- }
- else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
- idft(IDFT_4096,prachF,prach2,1);
- dftlen=4096;
- // here we have |empty | Prach4096 |
- if (prach_fmt != 0xc0) {
- memmove(prach2+(4096<<1),prach2,(4096<<2));
- prach_len = (4096*2)+Ncp;
- }
- else prach_len = (4096*1)+Ncp;
- memmove(prach,prach+(4096<<1),(Ncp<<2));
- // here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) |
-
- }
- else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x4096
- idft(IDFT_4096,prachF,prach2,1);
- dftlen=4096;
- // here we have |empty | Prach4096 |
- memmove(prach2+(4096<<1),prach2,(4096<<2));
- // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 |
- memmove(prach2+(4096<<2),prach2,(4096<<3));
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 |
- memmove(prach,prach+(4096<<1),(Ncp<<2));
- // here we have |Prefix | Prach4096 |
- prach_len = (4096*4)+Ncp;
- }
- else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x4096
- idft(IDFT_4096,prachF,prach2,1);
- dftlen=4096;
- // here we have |empty | Prach4096 |
- memmove(prach2+(4096<<1),prach2,(4096<<2));
- // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096
- memmove(prach2+(4096<<2),prach2,(4096<<3));
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096
- memmove(prach2+((4096<<1)*3),prach2,(4096<<3));
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096
- memmove(prach,prach+(4096<<1),(Ncp<<2));
- // here we have |Prefix | Prach4096 |
- prach_len = (4096*6)+Ncp;
- }
- else if (prach_fmt == 0xb4) { // 12x4096
- idft(IDFT_4096,prachF,prach2,1);
- dftlen=4096;
- // here we have |empty | Prach4096 |
- memmove(prach2+(4096<<1),prach2,(4096<<2));
- // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096
- memmove(prach2+(4096<<2),prach2,(4096<<3));
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096
- memmove(prach2+(4096<<3),prach2,(4096<<3));
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096
- memmove(prach2+(4096<<1)*6,prach2,(4096<<2)*6);
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096|
- memmove(prach,prach+(4096<<1),(Ncp<<2));
- // here we have |Prefix | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096|
- prach_len = (4096*12)+Ncp;
- }
- }
- else { // 92.16 Ms/s
+ } else { // three quarter sampling @ 92.16 Ms/s
Ncp = (Ncp*3);
prach2 = prach+(Ncp<<1);
- if (prach_fmt == 0) {
- idft(IDFT_73728,prachF,prach2,1);
- dftlen=73728;
- // here we have |empty | Prach73728|
- memmove(prach,prach+(73728<<1),(Ncp<<4));
- // here we have |Prefix | Prach73728|
- prach_len = (73728*1)+Ncp;
- }
- else if (prach_fmt == 1) {
- idft(IDFT_73728,prachF,prach2,1);
- dftlen=73728;
- memmove(prach2+(73728<<1),prach2,(73728<<2));
- // here we have |empty | Prach73728 | Prach73728|
- memmove(prach,prach+(73728<<2),(Ncp<<4));
- // here we have |Prefix | Prach73728 | Prach73728|
- prach_len = (73728*2)+Ncp;
- }
- if (prach_fmt == 2) {
- idft(IDFT_73728,prachF,prach2,1);
- dftlen=73728;
- memmove(prach2+(73728<<1),prach2,(73728<<2));
- // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
- memmove(prach2+(73728<<2),prach2,(73728<<3));
- // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728
- memmove(prach,prach+(73728<<3),(Ncp<<4));
- // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728
- prach_len = (73728*4)+Ncp;
- }
- else if (prach_fmt == 3) {
- idft(IDFT_18432,prachF,prach2,1);
- dftlen=18432;
- memmove(prach2+(18432<<1),prach2,(18432<<2));
- // here we have |empty | Prach18432 | Prach18432| empty18432 | empty18432
- memmove(prach2+(18432<<2),prach2,(18432<<3));
- // here we have |empty | Prach18432 | Prach18432| Prach18432 | Prach18432
- memmove(prach,prach+(18432<<3),(Ncp<<4));
- // here we have |Prefix | Prach18432 | Prach18432| Prach18432 | Prach18432
- prach_len = (18432*4)+Ncp;
- }
- else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
- idft(IDFT_3072,prachF,prach2,1);
- dftlen=3072;
- // here we have |empty | Prach3072 |
- if (prach_fmt != 0xc0) {
- memmove(prach2+(3072<<1),prach2,(3072<<2));
- prach_len = (3072*2)+Ncp;
- }
- else prach_len = (3072*1)+Ncp;
- memmove(prach,prach+(3072<<1),(Ncp<<2));
- // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) |
- }
- else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x3072
- idft(IDFT_3072,prachF,prach2,1);
- dftlen=3072;
- // here we have |empty | Prach3072 |
- memmove(prach2+(3072<<1),prach2,(3072<<2));
- // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072
- memmove(prach2+(3072<<2),prach2,(3072<<3));
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072
- memmove(prach2+((3072<<1)*3),prach2,(3072<<3));
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072
- memmove(prach,prach+(3072<<1),(Ncp<<2));
- // here we have |Prefix | Prach3072 |
- prach_len = (3072*6)+Ncp;
- }
- else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x3072
- idft(IDFT_3072,prachF,prach2,1);
- dftlen=3072;
- // here we have |empty | Prach3072 |
- memmove(prach2+(3072<<1),prach2,(3072<<2));
- // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 |
- memmove(prach2+(3072<<2),prach2,(3072<<3));
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 |
- memmove(prach,prach+(3072<<1),(Ncp<<2));
- // here we have |Prefix | Prach3072 |
- prach_len = (3072*4)+Ncp;
- }
- else if (prach_fmt == 0xb4) { // 12x3072
- idft(IDFT_3072,prachF,prach2,1);
- dftlen=3072;
- // here we have |empty | Prach3072 |
- memmove(prach2+(3072<<1),prach2,(3072<<2));
- // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072
- memmove(prach2+(3072<<2),prach2,(3072<<3));
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072
- memmove(prach2+(3072<<3),prach2,(3072<<3));
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072
- memmove(prach2+(3072<<1)*6,prach2,(3072<<2)*6);
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072|
- memmove(prach,prach+(3072<<1),(Ncp<<2));
- // here we have |Prefix | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072|
- prach_len = (3072*12)+Ncp;
+ if (prach_sequence_length == 0){
+ if (prach_fmt_id == 0) {
+ idft(IDFT_73728,prachF,prach2,1);
+ // here we have |empty | Prach73728|
+ memmove(prach,prach+(73728<<1),(Ncp<<2));
+ // here we have |Prefix | Prach73728|
+ prach_len = (73728*1)+Ncp;
+ } else if (prach_fmt_id == 1) {
+ idft(IDFT_73728,prachF,prach2,1);
+ memmove(prach2+(73728<<1),prach2,(73728<<2));
+ // here we have |empty | Prach73728 | Prach73728|
+ memmove(prach,prach+(73728<<2),(Ncp<<2));
+ // here we have |Prefix | Prach73728 | Prach73728|
+ prach_len = (73728*2)+Ncp;
+ } if (prach_fmt_id == 2) {
+ idft(IDFT_73728,prachF,prach2,1);
+ memmove(prach2+(73728<<1),prach2,(73728<<2));
+ // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
+ memmove(prach2+(73728<<2),prach2,(73728<<3));
+ // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728
+ memmove(prach,prach+(73728<<3),(Ncp<<2));
+ // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728
+ prach_len = (73728*4)+Ncp;
+ } else if (prach_fmt_id == 3) {
+ idft(IDFT_18432,prachF,prach2,1);
+ memmove(prach2+(18432<<1),prach2,(18432<<2));
+ // here we have |empty | Prach18432 | Prach18432| empty18432 | empty18432
+ memmove(prach2+(18432<<2),prach2,(18432<<3));
+ // here we have |empty | Prach18432 | Prach18432| Prach18432 | Prach18432
+ memmove(prach,prach+(18432<<3),(Ncp<<2));
+ // here we have |Prefix | Prach18432 | Prach18432| Prach18432 | Prach18432
+ prach_len = (18432*4)+Ncp;
+ }
+ } else { // short sequence
+ if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
+ Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_3072,prachF,prach2,1);
+ // here we have |empty | Prach3072 |
+ if (prach_fmt_id != 7) {
+ memmove(prach2+(3072<<1),prach2,(3072<<2));
+ prach_len = (3072*2)+Ncp;
+ } else prach_len = (3072*1)+Ncp;
+ memmove(prach,prach+(3072<<1),(Ncp<<2));
+ // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) |
+ } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x3072
+ Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_3072,prachF,prach2,1);
+ // here we have |empty | Prach3072 |
+ memmove(prach2+(3072<<1),prach2,(3072<<2));
+ // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072
+ memmove(prach2+(3072<<2),prach2,(3072<<3));
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072
+ memmove(prach2+(3072<<3),prach2,(3072<<3));
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072
+ memmove(prach,prach+(3072<<1),(Ncp<<2));
+ // here we have |Prefix | Prach3072 |
+ prach_len = (3072*6)+Ncp;
+ } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x3072
+ Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_3072,prachF,prach2,1);
+ // here we have |empty | Prach3072 |
+ memmove(prach2+(3072<<1),prach2,(3072<<2));
+ // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 |
+ memmove(prach2+(3072<<2),prach2,(3072<<3));
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 |
+ memmove(prach,prach+(3072<<1),(Ncp<<2));
+ // here we have |Prefix | Prach3072 |
+ prach_len = (3072*4)+Ncp;
+ } else if (prach_fmt_id == 6) { // 12x3072
+ Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_3072,prachF,prach2,1);
+ // here we have |empty | Prach3072 |
+ memmove(prach2+(3072<<1),prach2,(3072<<2));
+ // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072
+ memmove(prach2+(3072<<2),prach2,(3072<<3));
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072
+ memmove(prach2+(3072<<3),prach2,(3072<<3));
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072
+ memmove(prach2+(3072<<1)*6,prach2,(3072<<2)*6);
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072|
+ memmove(prach,prach+(3072<<1),(Ncp<<2));
+ // here we have |Prefix | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072|
+ prach_len = (3072*12)+Ncp;
+ }
}
}
- }
-
-
-
-
-#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
- int j;
- int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe;
- LOG_D( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow );
-
- for (i=prach_start,j=0; isamples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,prach_start+prach_len); i++,j++) {
- ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j];
- ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
}
- for (i=0; icommon_vars.txdata[0])[2*i] = prach[2*j];
- ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
- }
-#else
+ #ifdef NR_PRACH_DEBUG
+ LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", Mod_id,
+ fp->N_RB_UL,
+ prach_start,
+ prach_len,
+ ue->rx_offset,
+ ue->hw_timing_advance,
+ ue->N_TA_offset);
+ #endif
- LOG_D( PHY, "prach_start=%d\n", prach_start);
+ #if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+ int j, overflow = prach_start + prach_len - NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe;
- for (i=0; icommon_vars.txdata[0][prach_start]))[2*i] = prach[2*i];
- ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1];
- }
-#endif
+ #ifdef NR_PRACH_DEBUG
+ LOG_I( PHY, "PRACH [UE %d] overflow = %d\n", Mod_id, overflow);
+ #endif
+ // prach_start=414.730, overflow=-39470 prach_len=6600 fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME 460.800 prach_start+prach_len 421.330 fp->samples_per_subframe 46080
+ // from prach_start=414.730 to prach_start+prach_len 421.330
+ for (i = prach_start, j = 0; i < min(fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME, prach_start + prach_len); i++, j++) {
+ ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j];
+ ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
+ }
-#if defined(PRACH_WRITE_OUTPUT_DEBUG)
- LOG_M("prach_txF0.m","prachtxF0",prachF,prach_len-Ncp,1,1);
- LOG_M("prach_tx0.m","prachtx0",prach+(Ncp<<1),prach_len-Ncp,1,1);
- LOG_M("txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]),fp->samples_per_subframe,1,1);
- exit(-1);
-#endif
+ for (i = 0; i < overflow; i++,j++) {
+ ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j];
+ ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
+ }
+ #else // simulators
+ for (i=0; icommon_vars.txdata[0][prach_start]))[2*i] = prach[2*i];
+ ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1];
+ }
+ #endif
- return signal_energy( (int*)prach, 256 );
+ //printf("----------------------\n");
+ //for(int ii = prach_start; ii<2*(prach_start + prach_len); ii++){
+ // printf("PRACH rx data[%d] = %d\n", ii, ue->common_vars.txdata[0][ii]);
+ //}
+ //printf(" \n");
+
+ #if defined(PRACH_WRITE_OUTPUT_DEBUG)
+ LOG_M("prach_tx0.m", "prachtx0", prach+(Ncp<<1), prach_len-Ncp, 1, 1);
+ LOG_M("Prach_txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]), 2*(prach_start+prach_len), 1, 1)
+ #endif
+
+ return signal_energy((int*)prach, 256);
}
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 4aae9ef7b4..bde9ae03f1 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -37,6 +37,9 @@
#include
#include "nfapi_interface.h"
+#define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
+#define NR_PUSCH_y 3 // UCI placeholder bit
+
// Functions below implement 36-211 and 36-212
/** @addtogroup _PHY_TRANSPORT_
@@ -66,24 +69,6 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulsch,unsigned char N_RB_UL);
NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag);
-void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
-
-int rx_pmch(PHY_VARS_NR_UE *phy_vars_ue,
- unsigned char eNB_id,
- uint8_t subframe,
- unsigned char symbol);
-
-/** \brief Dump OCTAVE/MATLAB files for PMCH debugging
- @param phy_vars_ue Pointer to UE variables
- @param eNB_id index of eNB in ue variables
- @param coded_bits_per_codeword G from 36.211
- @param subframe Index of subframe
- @returns 0 on success
-*/
-void dump_mch(PHY_VARS_NR_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe);
-
-
-
/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception.
@param stream0_in Input from channel compensated (MR combined) stream 0
@param stream1_in Input from channel compensated (MR combined) stream 1
@@ -1402,8 +1387,10 @@ void ulsch_modulation(int32_t **txdataF,
NR_UE_ULSCH_t *ulsch);
-
-
+uint8_t allowed_ulsch_re_in_dmrs_symbol(uint16_t k,
+ uint16_t start_sc,
+ uint8_t numDmrsCdmGrpsNoData,
+ uint8_t dmrs_type);
int generate_ue_dlsch_params_from_dci(int frame,
@@ -1540,11 +1527,11 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,DCI_ALLOC_t *dci_alloc,NR_DL_FRAME
void pdcch_interleaving(NR_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi);
-void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t slot,
- int16_t *z, int16_t *z2,uint32_t length, uint16_t pdcch_DMRS_scrambling_id);
-
-
-
+void nr_pdcch_unscrambling(int16_t *z,
+ uint16_t scrambling_RNTI,
+ uint32_t length,
+ uint16_t pdcch_DMRS_scrambling_id,
+ int16_t *z2);
void dlsch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
int mbsfn_flag,
@@ -1757,9 +1744,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t is_crnti,
uint8_t llr8_flag);
-
-
-int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf );
+int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe);
void *dlsch_thread(void *arg);
/**@}*/
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index bb92508934..6b2d5e7255 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -42,9 +42,8 @@
#include "UTIL/LISTS/list.h"
#endif
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h"
-//#include "../LTE_TRANSPORT/transport_common.h"
+
// structures below implement 36-211 and 36-212
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 7299b085bb..4b36f91e69 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -225,7 +225,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
unsigned int crc;
NR_UL_UE_HARQ_t *harq_process;
uint16_t nb_rb ;
- uint8_t nb_symb_sch ;
uint32_t A, Z, F;
uint32_t *pz;
uint8_t mod_order;
@@ -263,8 +262,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
///////////
/////////////////////////////////////////////////////////////////////////////////////////
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_IN);
LOG_D(PHY,"ulsch coding nb_rb %d, Nl = %d\n", nb_rb, harq_process->pusch_pdu.nrOfLayers);
LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
@@ -284,6 +282,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
printf("%02x.",a[i]);
printf("\n");
*/
+
if (A > 3824) {
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(harq_process->a,A)>>8;
@@ -313,7 +312,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
memcpy(harq_process->b,harq_process->a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc
}
-
///////////
///////////////////////////////////////////////////////////////////////////
@@ -332,6 +330,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
BG = 1;
}
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN);
Kb=nr_segmentation(harq_process->b,
harq_process->c,
harq_process->B,
@@ -340,6 +339,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
pz,
&harq_process->F,
BG);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT);
F = harq_process->F;
Kr = harq_process->K;
@@ -390,7 +390,11 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
impp.n_segments=harq_process->C;
impp.macro_num=0;
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
+
nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,&impp);
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT);
//stop_meas(te_stats);
//printf("end ldpc encoder -- output\n");
@@ -436,6 +440,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers,harq_process->C);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
BG,
@@ -447,6 +452,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
Kr-F-2*(*pz),
harq_process->pusch_pdu.pusch_data.rv_index,
E);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_OUT);
@@ -465,10 +471,14 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
//stop_meas(rm_stats);
//start_meas(i_stats);
- nr_interleaving_ldpc(E,
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_IN);
+
+ nr_interleaving_ldpc(E,
mod_order,
harq_process->e+r_offset,
harq_process->f+r_offset);
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_OUT);
//stop_meas(i_stats);
@@ -489,7 +499,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
memcpy(ulsch->g,harq_process->f,G); // g is the concatenated code block
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
return(0);
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 69b3421ace..93acda23f8 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -98,6 +98,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint8_t thread_id,
int gNB_id) {
+ LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);
+
uint32_t available_bits, TBS;
uint8_t mod_order, cwd_index, num_of_codewords, l;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
@@ -110,7 +112,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint8_t dmrs_type, nb_dmrs_re_per_rb, number_of_symbols, mcs, Nl;
int ap, start_symbol, Nid_cell, i;
int sample_offsetF, N_RE_prime, N_PRB_oh;
- uint16_t n_rnti, ul_dmrs_symb_pos;
+ uint16_t ul_dmrs_symb_pos;
uint8_t data_existing =0;
uint8_t L_ptrs, K_ptrs; // PTRS parameters
uint16_t beta_ptrs; // PTRS parameter related to power control
@@ -146,7 +148,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
rnti = harq_process_ul_ue->pusch_pdu.rnti;
ulsch_ue->Nid_cell = Nid_cell;
- nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4);
+
+ nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*harq_process_ul_ue->pusch_pdu.num_dmrs_cdm_grps_no_data;
N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh;
@@ -165,6 +168,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
number_of_symbols,
nb_dmrs_re_per_rb*number_dmrs_symbols,
0,
+ 0,
harq_process_ul_ue->pusch_pdu.nrOfLayers);
uint8_t access_mode = SCHEDULED_ACCESS;
@@ -176,38 +180,38 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
TBS = harq_process_ul_ue->pusch_pdu.pusch_data.tb_size;
data_existing = 0;
- if (IS_SOFTMODEM_NOS1){
+ if (IS_SOFTMODEM_NOS1){
data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame,
slot, 0, ulsch_input_buffer, TBS/8, &access_mode);
- //IP traffic to be transmitted
+ //IP traffic to be transmitted
if(data_existing){
- //harq_process_ul_ue->a = (unsigned char*)calloc(TBS/8, sizeof(unsigned char));
+ //harq_process_ul_ue->a = (unsigned char*)calloc(harq_process_ul_ue->TBS/8, sizeof(unsigned char));
memcpy(harq_process_ul_ue->a, ulsch_input_buffer, TBS/8);
-
- #ifdef DEBUG_MAC_PDU
- LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS/8);
- for (i = 0; i < TBS / 8; i++) {
- printf("0x%02x",harq_process_ul_ue->a[i]);
- }
- printf("\n");
- #endif
- }
+ }
}
//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
if (!IS_SOFTMODEM_NOS1 || !data_existing) {
//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
//and block this traffic from being forwarded to the upper layers at the gNB
- uint16_t payload_offset = 5;
LOG_D(PHY, "Random data to be tranmsitted: \n");
- //Give the header bytes some dummy value in order to block the random packet at the MAC layer of the receiver
- for (i = 0; ia[i] = 0;
- for (i = payload_offset; i < TBS / 8; i++) {
+ //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
+ //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
+ //have a valid LCID (nr_process_mac_pdu function)
+ harq_process_ul_ue->a[0] = 0x31;
+
+ for (i = 1; i < TBS / 8; i++) {
harq_process_ul_ue->a[i] = (unsigned char) rand();
//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
}
}
+#ifdef DEBUG_MAC_PDU
+ LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS/8);
+ for (i = 0; i < TBS / 8; i++) {
+ printf("%02x",harq_process_ul_ue->a[i]);
+ }
+ printf("\n");
+#endif
} else {
LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n");
return;
@@ -220,7 +224,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
unsigned int G = nr_get_G(nb_rb, number_of_symbols,
nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl);
-
nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G);
///////////
@@ -264,7 +267,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/////////////////////////DMRS Modulation/////////////////////////
///////////
pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
- n_dmrs = (nb_rb*nb_dmrs_re_per_rb*number_dmrs_symbols);
+ n_dmrs = (nb_rb*((dmrs_type == pusch_dmrs_type1) ? 6:4)*number_dmrs_symbols);
int16_t mod_dmrs[n_dmrs<<1];
///////////
////////////////////////////////////////////////////////////////////////
@@ -301,9 +304,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
tx_layers = (int16_t **)pusch_ue->txdataF_layers;
nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id],
- Nl,
- available_bits/mod_order,
- tx_layers);
+ Nl,
+ available_bits/mod_order,
+ tx_layers);
///////////
////////////////////////////////////////////////////////////////////////
@@ -365,7 +368,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint8_t k_prime=0;
- uint8_t is_dmrs, is_ptrs;
+ uint8_t is_dmrs, is_ptrs, is_dmrs_symbol;
uint16_t m=0, n=0, dmrs_idx=0, ptrs_idx = 0;
for (l=start_symbol; l> l) & 0x01) {
+ is_dmrs_symbol = 1;
if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size))
is_dmrs = 1;
}
@@ -432,18 +437,24 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
ptrs_idx++;
- } else {
+ } else if (!is_dmrs_symbol || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,harq_process_ul_ue->pusch_pdu.num_dmrs_cdm_grps_no_data,dmrs_type)) {
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1];
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1];
- #ifdef DEBUG_PUSCH_MAPPING
- printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
- m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]);
- #endif
+ #ifdef DEBUG_PUSCH_MAPPING
+ printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
+ m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
+ ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]);
+ #endif
m++;
+
+ } else {
+
+ ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = 0;
+ ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = 0;
+
}
if (++k >= frame_parms->ofdm_symbol_size)
@@ -453,6 +464,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
}
//}
+ NR_UL_UE_HARQ_t *harq_process_ulsch=NULL;
+ harq_process_ulsch = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid];
+ harq_process_ulsch->status = SCH_IDLE;
///////////
////////////////////////////////////////////////////////////////////////
@@ -498,21 +512,51 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
txdata = UE->common_vars.txdata;
txdataF = UE->common_vars.txdataF;
- for (ap = 0; ap < Nl; ap++) {
+ if(UE->N_TA_offset > tx_offset) {
+ int32_t *tmp_idft_out = (int32_t*)malloc16(frame_parms->get_samples_per_slot(slot, frame_parms) * sizeof(int32_t));
+
+ for(ap = 0; ap < Nl; ap++) {
if (frame_parms->Ncp == 1) { // extended cyclic prefix
- PHY_ofdm_mod(txdataF[ap],
- &txdata[ap][tx_offset],
- frame_parms->ofdm_symbol_size,
- 12,
- frame_parms->nb_prefix_samples,
- CYCLIC_PREFIX);
+ PHY_ofdm_mod(txdataF[ap],
+ tmp_idft_out,
+ frame_parms->ofdm_symbol_size,
+ 12,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
} else { // normal cyclic prefix
- nr_normal_prefix_mod(txdataF[ap],
- &txdata[ap][tx_offset],
- 14,
- frame_parms);
+ nr_normal_prefix_mod(txdataF[ap],
+ tmp_idft_out,
+ 14,
+ frame_parms);
+ }
+
+ memcpy((void *) &txdata[ap][frame_parms->samples_per_frame - UE->N_TA_offset + tx_offset],
+ (void *) tmp_idft_out,
+ (UE->N_TA_offset - tx_offset) * sizeof(int32_t));
+
+ memcpy((void *) &txdata[ap][0],
+ (void *) &tmp_idft_out[UE->N_TA_offset - tx_offset],
+ (frame_parms->get_samples_per_slot(slot, frame_parms) - UE->N_TA_offset + tx_offset) * sizeof(int32_t));
+ }
+
+ free(tmp_idft_out);
+ } else { // UE->N_TA_offset <= tx_offset
+ for (ap = 0; ap < Nl; ap++) {
+ if (frame_parms->Ncp == 1) { // extended cyclic prefix
+ PHY_ofdm_mod(txdataF[ap],
+ &txdata[ap][tx_offset-UE->N_TA_offset],
+ frame_parms->ofdm_symbol_size,
+ 12,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
+ } else { // normal cyclic prefix
+ nr_normal_prefix_mod(txdataF[ap],
+ &txdata[ap][tx_offset-UE->N_TA_offset],
+ 14,
+ frame_parms);
}
}
+ }
///////////
////////////////////////////////////////////////////
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index baf34ade92..c977118df3 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -38,6 +38,7 @@
#include "PHY/defs_nr_UE.h"
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
#define DEFINE_VARIABLES_PSS_NR_H
#include "PHY/NR_REFSIG/pss_nr.h"
@@ -672,6 +673,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
int **rxdata = NULL;
int fo_flag = PHY_vars_UE->UE_fo_compensation; // flag to enable freq offset estimation and compensation
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SYNCHRO_NR, VCD_FUNCTION_IN);
#ifdef DBG_PSS_NR
LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], frame_parms->samples_per_frame, 1, 1);
@@ -710,6 +712,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
#endif
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR, VCD_FUNCTION_IN);
synchro_position = pss_search_time_nr(rxdata,
frame_parms,
fo_flag,
@@ -717,6 +720,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
(int *)&PHY_vars_UE->common_vars.eNb_id,
(int *)&PHY_vars_UE->common_vars.freq_offset);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR, VCD_FUNCTION_OUT);
#if TEST_SYNCHRO_TIMING_PSS
@@ -749,6 +753,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
}
#endif
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SYNCHRO_NR, VCD_FUNCTION_OUT);
return synchro_position;
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
index c8f7268d04..d2a8e64749 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
@@ -54,7 +54,8 @@
void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
- PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
+ long pucch_GroupHopping,
+ long hoppingId,
int16_t amp,
int nr_tti_tx,
uint8_t m0,
@@ -111,7 +112,7 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
for (int l=0; lpucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
+ nr_group_sequence_hopping(pucch_GroupHopping,hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_tti_tx);
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l);
@@ -799,27 +800,47 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
}
#endif //0
-inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) __attribute__((always_inline));
-inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) {
+inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) __attribute__((always_inline));
+inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) {
uint32_t x1, x2, s=0;
int i;
uint8_t c;
// c_init=nRNTI*2^15+n_id according to TS 38.211 Subclause 6.3.2.6.1
//x2 = (rnti) + ((uint32_t)(1+nr_tti_tx)<<16)*(1+(fp->Nid_cell<<1));
x2 = ((rnti)<<15)+n_id;
- s = lte_gold_generic(&x1, &x2, 1);
#ifdef DEBUG_NR_PUCCH_TX
- printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x\n",s);
+ printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x, M_bit %d\n",s,M_bit);
#endif
- for (i=0; i>i)&1);
- btilde[i] = (((B>>i)&1) ^ c);
+ uint8_t *btildep=btilde;
+ int M_bit2=M_bit > 31 ? 32 : (M_bit&31), M_bit3=M_bit;
+ uint32_t B;
+ for (int iprime=0;iprime<=(M_bit>>5);iprime++,btildep+=32) {
+ s = lte_gold_generic(&x1, &x2, (iprime==0) ? 1 : 0);
+ B=((uint32_t*)B64)[iprime];
+ for (int n=0;n>n)&1,
+ (B>>(n+1))&1,
+ (B>>(n+2))&1,
+ (B>>(n+3))&1,
+ (B>>(n+4))&1,
+ (B>>(n+5))&1,
+ (B>>(n+6))&1,
+ (B>>(n+7))&1
+ );
+ for (i=0; i>i)&1);
+ btildep[i] = (((B>>i)&1) ^ c);
#ifdef DEBUG_NR_PUCCH_TX
- //printf("\t\t\t btilde[%d]=%lx from scrambled bit %d\n",i,btilde[i],((B>>i)&1));
+ printf("\t\t\t btilde[%d]=%lx from unscrambled bit %d and scrambling %d (%x)\n",i+(iprime<<5),btilde[i],((B>>i)&1),c,s>>i);
#endif
+ }
+ M_bit3-=32;
+ M_bit2=M_bit3 > 31 ? 32 : (M_bit3&31);
}
+
#ifdef DEBUG_NR_PUCCH_TX
printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit);
#endif
@@ -909,24 +930,13 @@ void nr_uci_encoding(uint64_t payload,
// CRC bits are not attached, and coding small block lengths (subclause 5.3.3)
b[0] = encodeSmallBlock((uint16_t*)&payload,A);
} else if (A>=12) {
- AssertFatal(1==0,"Polar encoding not supported yet for UCI\n");
- // procedure in subclause 6.3.1.2.1 (UCI encoded by Polar code -> subclause 6.3.1.3.1)
- /*if ((A>=360 && E>=1088)||(A>=1013)) {
- I_seg = 1;
- } else {
- I_seg = 0;
- }*/
-
- /*if (A>=20) {
- // parity bits (subclause 5.2.1) computed by setting L=11 and using generator polynomial gCRC11(D) (subclause 5.1)
- L=11;
- } else if (A<=19) {
- // parity bits (subclause 5.2.1) computed by setting L=6 and using generator polynomial gCRC6(D) (subclause 5.1)
- L=6;
- }*/
-
- // code block segmentation and CRC attachment is performed according to subclause 5.2.1
- // polar coding subclause 5.3.1
+ AssertFatal(A<65,"Polar encoding not supported yet for UCI with more than 64 bits\n");
+ t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_UCI_PUCCH_MESSAGE_TYPE,
+ A,
+ nrofPRB,
+ 1,
+ NULL);
+ polar_encoder_fast(&payload, b, 0,0,currentPtr);
}
}
@@ -950,10 +960,10 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
printf("\t [nr_generate_pucch2] start function at slot(nr_tti_tx)=%d with payload=%lu and nr_bit=%d\n",nr_tti_tx, payload, nr_bit);
#endif
// b is the block of bits transmitted on the physical channel after payload coding
- uint64_t b;
+ uint64_t b[16]; // limit to 1024-bit encoded length
// M_bit is the number of bits of block b (payload after encoding)
uint16_t M_bit;
- nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,&b,&M_bit);
+ nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,(void*)b,&M_bit);
/*
* Implementing TS 38.211
* Subclauses 6.3.2.5.1 Scrambling (PUCCH format 2)
@@ -1119,7 +1129,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
printf("\t [nr_generate_pucch3_4] start function at slot(nr_tti_tx)=%d with payload=%lu and nr_bit=%d\n", nr_tti_tx, payload, nr_bit);
#endif
// b is the block of bits transmitted on the physical channel after payload coding
- uint64_t b;
+ uint64_t b[16];
// M_bit is the number of bits of block b (payload after encoding)
uint16_t M_bit;
// parameter PUCCH-F4-preDFT-OCC-length set of {2,4} -> to use table -1 or -2
@@ -1144,7 +1154,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
//nrofPRB = 2; // only for test purposes
if (fmt == pucch_format4_nr) nrofPRB = 1;
- nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,&b,&M_bit);
+ nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,(void*)b,&M_bit);
/*
* Implementing TS 38.211
* Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
index a2446dccf9..0e81045d66 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
@@ -49,7 +49,8 @@
void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
- PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
+ long pucch_GroupHopping,
+ long hoppingId,
int16_t amp,
int nr_tti_tx,
uint8_t m0,
diff --git a/openair1/PHY/TOOLS/Makefile b/openair1/PHY/TOOLS/Makefile
index c71717dc87..a59700bb7c 100644
--- a/openair1/PHY/TOOLS/Makefile
+++ b/openair1/PHY/TOOLS/Makefile
@@ -1,16 +1,16 @@
-lte_dfts_sse4: lte_dfts.c
- gcc-7 -O3 -std=gnu99 -msse4.1 -o lte_dfts_sse4 lte_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS
+oai_dfts_sse4: oai_dfts.c
+ gcc-7 -O3 -std=gnu99 -msse4.1 -o oai_dfts_sse4 oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_TARGETS/ARCH/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS
-lte_dfts_avx2: lte_dfts.c
- gcc -O2 -std=gnu99 -mavx2 -g -ggdb -o lte_dfts_avx2 lte_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS
+oai_dfts_avx2: oai_dfts.c
+ gcc -O2 -std=gnu99 -mavx2 -g -ggdb -o oai_dfts_avx2 oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_TARGETS/ARCH/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS
-lte_dfts_avx2.s: lte_dfts.c
- gcc -O2 -std=gnu99 -mavx2 -S lte_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS
+oai_dfts_avx2.s: oai_dfts.c
+ gcc -O2 -std=gnu99 -mavx2 -S oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_TARGETS/ARCH/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS
-lte_dfts_sse4.s: lte_dfts.c
- gcc -O2 -std=gnu99 -msse4.1 -S lte_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS
+oai_dfts_sse4.s: oai_dfts.c
+ gcc -O2 -std=gnu99 -msse4.1 -S oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_TARGETS/ARCH/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS
-dft_cycles_avx2: lte_dfts_avx2
- ./lte_dfts_avx2 | egrep cycles
+dft_cycles_avx2: oai_dfts_avx2
+ ./oai_dfts_avx2 | egrep cycles
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index 67ec027a9d..dfb148d34e 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -9,6 +9,8 @@
*
* http://www.openairinterface.org/?page_id=698
*
+ * Author and copyright: Laurent Thomas, open-cells.com
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,8 +26,10 @@
#include
#include "nr_phy_scope.h"
#include "executables/nr-softmodem-common.h"
+#include
#define TPUT_WINDOW_LENGTH 100
+#define localBuff(NaMe,SiZe) float NaMe[SiZe]; memset(NaMe,0,sizeof(NaMe));
int otg_enabled;
FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
@@ -36,836 +40,29 @@ float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
float tput_ue_max[NUMBER_OF_UE_MAX] = {0};
-
-static void ia_receiver_on_off( FL_OBJECT *button, long arg)
-{
-
- if (fl_get_button(button)) {
- fl_set_object_label(button, "IA Receiver ON");
- // PHY_vars_UE_g[0][0]->use_ia_receiver = 1;
- fl_set_object_color(button, FL_GREEN, FL_GREEN);
- } else {
- fl_set_object_label(button, "IA Receiver OFF");
- // PHY_vars_UE_g[0][0]->use_ia_receiver = 0;
- fl_set_object_color(button, FL_RED, FL_RED);
- }
-}
-
-static void dl_traffic_on_off( FL_OBJECT *button, long arg)
-{
-
- if (fl_get_button(button)) {
- fl_set_object_label(button, "DL Traffic ON");
- otg_enabled = 1;
- fl_set_object_color(button, FL_GREEN, FL_GREEN);
- } else {
- fl_set_object_label(button, "DL Traffic OFF");
- otg_enabled = 0;
- fl_set_object_color(button, FL_RED, FL_RED);
- }
-}
-
-FD_phy_scope_gnb *create_phy_scope_gnb( void )
-{
-
- FL_OBJECT *obj;
- FD_phy_scope_gnb *fdui = fl_malloc( sizeof *fdui );
-
- // Define form
- fdui->phy_scope_gnb = fl_bgn_form( FL_NO_BOX, 800, 800 );
-
- // This the whole UI box
- obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
- fl_set_object_color( obj, FL_BLACK, FL_BLACK );
-
- // Received signal
- fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
- fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
- fl_set_xyplot_ybounds(fdui->rxsig_t,10,70);
-
- // Time-domain channel response
- fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "SRS Frequency Response (samples, abs)" );
- fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
-
- // Frequency-domain channel response
- fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
- fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
- fl_set_xyplot_ybounds( fdui->chest_f,30,70);
-
- // LLR of PUSCH
- fdui->pusch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pusch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pusch_llr, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pusch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pusch_llr,2);
-
- // I/Q PUSCH comp
- fdui->pusch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 200, "PUSCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pusch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pusch_comp, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pusch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pusch_comp,2);
- fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
-
- // I/Q PUCCH comp (format 1)
- fdui->pucch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 480, 240, 100, "PUCCH1 Energy (SR)" );
- fl_set_object_boxtype( fdui->pucch_comp1, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pucch_comp1, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pucch_comp1, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pucch_comp1,2);
- // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
-
- // I/Q PUCCH comp (fromat 1a/b)
- fdui->pucch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 600, 240, 100, "PUCCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pucch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pucch_comp, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pucch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pucch_comp,2);
- // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
-
- // Throughput on PUSCH
- fdui->pusch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 480, 500, 100, "PUSCH Throughput [frame]/[kbit/s]" );
- fl_set_object_boxtype( fdui->pusch_tput, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pusch_tput, FL_BLACK, FL_WHITE );
- fl_set_object_lcolor( fdui->pusch_tput, FL_WHITE ); // Label color
-
- // Generic eNB Button
- fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" );
- fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
- fl_set_button(fdui->button_0,0);
- otg_enabled = 0;
- fl_set_object_label(fdui->button_0, "DL Traffic OFF");
- fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
- fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 );
-
- fl_end_form( );
- fdui->phy_scope_gnb->fdui = fdui;
-
- return fdui;
-}
-
-void phy_scope_gNB(FD_phy_scope_gnb *form,
- PHY_VARS_gNB *phy_vars_gnb,
- RU_t *phy_vars_ru,
- int UE_id)
-{
- int i, arx; //int i,i2,arx,atx,ind,k;
- NR_DL_FRAME_PARMS *frame_parms = &phy_vars_gnb->frame_parms;
- //int nsymb_ce = 12*frame_parms->N_RB_UL*frame_parms->symbols_per_tti;
- uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
- //uint8_t nb_antennas_tx = 1; // frame_parms->nb_antennas_tx; // in LTE Rel. 8 and 9 only a single transmit antenna is assumed at the UE
- int16_t **rxsig_t, **rxsig_f;
- // int16_t **chest_t=NULL;
- // int16_t **chest_f=NULL;
- // int16_t *pusch_llr=NULL;
- // int32_t *pusch_comp=NULL;
- // int32_t *pucch1_comp=NULL;
- // int32_t *pucch1_thres=NULL;
- // int32_t *pucch1ab_comp=NULL;
- // float Re,Im,ymax;
- float *llr, *bit;
- // float I[nsymb_ce*2], Q[nsymb_ce*2];
- // float I_pucch[10240],Q_pucch[10240],A_pucch[10240],B_pucch[10240],C_pucch[10240];
- float *rxsig_t_dB[nb_antennas_rx];
- float *rxsig_f_dB[nb_antennas_rx];
- float time[frame_parms->samples_per_frame];
- // float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
- // uint32_t total_dlsch_bitrate = phy_vars_gnb->total_dlsch_bitrate;
- int coded_bits_per_codeword = 0;
- // uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2
- int Qm = 2;
-
- /*
- if (!RC.nrmac[0]->UE_info.active[UE_id])
- return;
-
- // choose max MCS to compute coded_bits_per_codeword
- if (phy_vars_gnb->ulsch[UE_id][0]!=NULL) {
- for (harq_pid=0; harq_pid<3; harq_pid++) {
- //Qm = cmax(phy_vars_gnb->ulsch[UE_id][0]->harq_processes->Qm,Qm);
- }
- }
- */
- coded_bits_per_codeword = frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
-
- for (arx=0; arxsamples_per_frame,sizeof(float));
- rxsig_f_dB[arx] = (float*) calloc(frame_parms->samples_per_slot_wCP,sizeof(float));
- }
- llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
- bit = malloc(coded_bits_per_codeword*sizeof(float));
-
- rxsig_t = (int16_t**) phy_vars_ru->common.rxdata;
- rxsig_f = (int16_t**) phy_vars_ru->common.rxdataF;
- //chest_t = (int16_t**) phy_vars_gnb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id];
- /* chest_t = (int16_t**) phy_vars_gnb->srs_vars[UE_id].srs_ch_estimates;
- chest_f = (int16_t**) phy_vars_gnb->pusch_vars[UE_id]->drs_ch_estimates;
- pusch_llr = (int16_t*) phy_vars_gnb->pusch_vars[UE_id]->llr;
- pusch_comp = (int32_t*) phy_vars_gnb->pusch_vars[UE_id]->rxdataF_comp;
- pucch1_comp = (int32_t*) phy_vars_gnb->pucch1_stats[UE_id];
- pucch1_thres = (int32_t*) phy_vars_gnb->pucch1_stats_thres[UE_id];
- pucch1ab_comp = (int32_t*) phy_vars_gnb->pucch1ab_stats[UE_id];
- */
-
- // Received signal in time domain of receive antenna 0
- if (rxsig_t != NULL) {
- if (rxsig_t[0] != NULL) {
- for (i=0; isamples_per_frame; i++) {
- rxsig_t_dB[0][i] = 10*log10(1.0+(float) ((rxsig_t[0][2*i])*(rxsig_t[0][2*i])+(rxsig_t[0][2*i+1])*(rxsig_t[0][2*i+1])));
- time[i] = (float) i;
- }
-
- fl_set_xyplot_data(form->rxsig_t,time,rxsig_t_dB[0],frame_parms->samples_per_frame,"","","");
- }
-
- for (arx=1; arxsamples_per_frame; i++) {
- rxsig_t_dB[arx][i] = 10*log10(1.0+(float) ((rxsig_t[arx][2*i])*(rxsig_t[arx][2*i])+(rxsig_t[arx][2*i+1])*(rxsig_t[arx][2*i+1])));
- }
-
- fl_add_xyplot_overlay(form->rxsig_t,arx,time,rxsig_t_dB[arx],frame_parms->samples_per_frame,rx_antenna_colors[arx]);
- }
- }
- }
-
- /*
- // Channel Impulse Response
- if (chest_t != NULL) {
- ymax = 0;
-
- if (chest_t[0] !=NULL) {
- for (i=0; i<(frame_parms->ofdm_symbol_size); i++) {
- //i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size;
- i2=i;
- //time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1));
- time2[i] = (float)i;
- chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1]));
-
- if (chest_t_abs[0][i] > ymax)
- ymax = chest_t_abs[0][i];
- }
-
- fl_set_xyplot_data(form->chest_t,time2,chest_t_abs[0],(frame_parms->ofdm_symbol_size),"","","");
- }
-
- for (arx=1; arxofdm_symbol_size>>3); i++) {
- chest_t_abs[arx][i] = 10*log10((float) (1+chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1]));
-
- if (chest_t_abs[arx][i] > ymax)
- ymax = chest_t_abs[arx][i];
- }
-
- fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
- fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
- }
- }
-
- // Avoid flickering effect
- // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
- fl_set_xyplot_ybounds(form->chest_t,0,ymax);
- }
- */
-
- // Channel Frequency Response
- if (rxsig_f != NULL) {
- if (rxsig_f[0] != NULL) {
- for (i=0; isamples_per_slot_wCP; i++) {
- rxsig_f_dB[0][i] = 10*log10(1.0+(float) ((rxsig_f[0][2*i])*(rxsig_f[0][2*i])+(rxsig_f[0][2*i+1])*(rxsig_f[0][2*i+1])));
- time[i] = (float) i;
- }
-
- fl_set_xyplot_data(form->chest_t,time,rxsig_f_dB[0],frame_parms->samples_per_slot_wCP,"","","");
- }
- }
-
- /*
-
- for (arx=0; arxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
- fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,3);
- fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
- fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
-
- for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
-
- // other tx antennas
- if (nb_antennas_tx > 1) {
- if (nb_antennas_rx > 1) {
- for (atx=1; atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- }
- } else { // 1 rx antenna
- atx=1;
- arx=0;
- fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- }
- }
-
- // PUSCH LLRs
- if (pusch_llr != NULL) {
- for (i=0; ipusch_llr,bit,llr,coded_bits_per_codeword,"","","");
- }
-
- // PUSCH I/Q of MF Output
- if (pusch_comp!=NULL) {
- ind=0;
-
- for (k=0; ksymbols_per_tti; k++) {
- for (i=0; i<12*frame_parms->N_RB_UL; i++) {
- I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i];
- Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1];
- ind++;
- }
- }
-
- fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","","");
- }
-
- // PUSCH I/Q of MF Output
- if (pucch1ab_comp!=NULL) {
- for (ind=0; ind<10240; ind++) {
-
- I_pucch[ind] = (float)pucch1ab_comp[2*(ind)];
- Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1];
- A_pucch[ind] = pucch1_comp?(10*log10(pucch1_comp[ind])):0;
- B_pucch[ind] = ind;
- C_pucch[ind] = pucch1_thres?(float)pucch1_thres[ind]:0;
- }
- fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","","");
- fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","","");
- fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED);
- fl_set_xyplot_ybounds(form->pucch_comp,-5000,5000);
- fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000);
-
- fl_set_xyplot_ybounds(form->pucch_comp1,0,80);
- }
-
-
- // PUSCH Throughput
- memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
- memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
-
- tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1] = (float) 0;
-// tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
-
- fl_set_xyplot_data(form->pusch_tput,tput_time_enb[UE_id],tput_enb[UE_id],TPUT_WINDOW_LENGTH,"","","");
-
- // fl_get_xyplot_ybounds(form->pusch_tput,&ymin,&ymax);
- // fl_set_xyplot_ybounds(form->pusch_tput,0,ymax);
-
- */
-
- fl_check_forms();
-
- free(llr);
- free(bit);
-}
-
-FD_phy_scope_nrue *create_phy_scope_nrue( void )
-{
-
- FL_OBJECT *obj;
- FD_phy_scope_nrue *fdui = fl_malloc( sizeof *fdui );
-
- // Define form
- fdui->phy_scope_nrue = fl_bgn_form( FL_NO_BOX, 800, 900 );
-
- // This the whole UI box
- obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 900, "" );
- fl_set_object_color( obj, FL_BLACK, FL_BLACK );
-
- // Received signal
- fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
- fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
- fl_set_xyplot_ybounds(fdui->rxsig_t,10,70);
-
- // Time-domain channel response
- fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" );
- fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
-
- // Frequency-domain channel response
- fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
- fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
- fl_set_xyplot_ybounds( fdui->chest_f,30,70);
-
- // LLR of PBCH
- fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN );
- fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pbch_llr,2);
- fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR);
- //fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
-
- // I/Q PBCH comp
- fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN );
- fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pbch_comp,2);
- // fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
- // fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
-
- // LLR of PDCCH
- fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN );
- fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdcch_llr,2);
-
- // I/Q PDCCH comp
- fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN );
- fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdcch_comp,2);
- fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR);
-
- // LLR of PDSCH
- fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdsch_llr,2);
- fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR);
-
- // I/Q PDSCH comp
- fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500, 240, 200, "PDSCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdsch_comp,2);
-
- // Throughput on PDSCH
- fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" );
- fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
- fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
-
- // Generic UE Button
- fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
- fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
- //openair_daq_vars.use_ia_receiver = 0;
- fl_set_button(fdui->button_0,0);
- fl_set_object_label(fdui->button_0, "IA Receiver OFF");
- fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
- fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 );
- fl_hide_object(fdui->button_0);
-
- fl_end_form( );
- fdui->phy_scope_nrue->fdui = fdui;
-
- return fdui;
-}
-
-void phy_scope_nrUE(FD_phy_scope_nrue *form,
- PHY_VARS_NR_UE *phy_vars_ue,
- int eNB_id,
- int UE_id,
- uint8_t subframe)
-{
- int i,arx,atx,ind,k;
- NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
- //int nsymb_ce = frame_parms->ofdm_symbol_size;//*frame_parms->symbols_per_tti;
- int samples_per_frame = frame_parms->samples_per_frame;
- uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
- uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_gNB;
- int16_t **rxsig_t;
- float **rxsig_t_dB;
- float *time;
- float *corr;
- int16_t **chest_t;
- int16_t **chest_f;
- int16_t *pdsch_llr;
- int16_t *pdsch_comp;
- //int16_t *pdsch_mag;
- int8_t *pdcch_llr;
- int16_t *pdcch_comp;
- int16_t *pbch_llr;
- int16_t *pbch_comp;
- float llr_pbch[1920], bit_pbch[1920];
- float *llr, *bit;
- float *llr_pdcch, *bit_pdcch;
- float *I, *Q;
- int num_pdcch_symbols=2;
- int num_re = 4500;
- int Qm = 2;
- int coded_bits_per_codeword = num_re*Qm;
- int symbol, first_symbol=2,nb_re;
- int nb_rb_pdsch=50,nb_symb_sch=9;
- float ymax=1;
- float **chest_t_abs;
- float Re,Im;
- float *chest_f_abs;
- float *freq;
- static int overlay = 0;
- /*
- int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
- int mcs = 0;
- unsigned char harq_pid = 0;
- */
-
- /*
- if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
- harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
-
- if (harq_pid>=8)
- return;
-
- mcs = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs;
-
- // Button 0
- if(!phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
- // we are in TM5
- fl_show_object(form->button_0);
- }
- }
-
- if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
- num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
- }
-
- // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
- if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
- coded_bits_per_codeword = get_G(frame_parms,
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
- get_Qm(mcs),
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
- num_pdcch_symbols,
- frame,
- subframe,
- beamforming_mode);
- } else {
- coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
- }
- */
- I = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
- Q = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
-
- chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*));
-
- for (arx=0; arxofdm_symbol_size,sizeof(float));
- }
-
- chest_f_abs = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
- freq = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
-
- llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
- bit = malloc(coded_bits_per_codeword*sizeof(float));
-
- llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
- bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
-
- rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
- rxsig_t_dB = calloc(nb_antennas_rx,sizeof(float*));
- for (arx=0; arxpbch_vars[eNB_id]->dl_ch_estimates_time;
- chest_f = (int16_t**) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
-
- pbch_llr = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
- pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
-
- pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
- pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
- pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
- // pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0
- pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
- //pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
-
- // Received signal in time domain of receive antenna 0
- if (rxsig_t != NULL) {
- if (rxsig_t[0] != NULL) {
- for (i=0; irxsig_t,time,rxsig_t_dB[0],samples_per_frame,"","","");
- }
-
- /*
- for (arx=1; arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
- }
- }
- */
- }
-
- if (phy_vars_ue->is_synchronized==0) {
- for (ind=0;ind<3;ind++) {
- /*
- if (pss_corr_ue[ind]) {
- for (i=0; ichest_t,time,corr,samples_per_frame,"","","");
- else
- fl_add_xyplot_overlay(form->chest_t,ind,time,corr,samples_per_frame,rx_antenna_colors[ind]);
-
- overlay = 1;
- }
- */
- }
- }
- else {
-
- if (overlay) { //there was a previous overlay
- fl_clear_xyplot(form->chest_t);
- overlay = 0;
- }
-
- // Channel Impulse Response
- if (chest_t != NULL) {
- ymax = 0;
-
- if (chest_t[0] !=NULL) {
- for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
- chest_t_abs[0][i] = (float) (chest_t[0][2*i]*chest_t[0][2*i]+chest_t[0][2*i+1]*chest_t[0][2*i+1]);
- time[i] = (float) i;
-
- if (chest_t_abs[0][i] > ymax)
- ymax = chest_t_abs[0][i];
- }
-
- fl_set_xyplot_data(form->chest_t,time,chest_t_abs[0],(frame_parms->ofdm_symbol_size>>3),"","","");
- }
- /*
- for (arx=1; arxofdm_symbol_size>>3); i++) {
- chest_t_abs[arx][i] = (float) (chest_t[arx][4*i]*chest_t[arx][4*i]+chest_t[arx][4*i+1]*chest_t[arx][4*i+1]);
-
- if (chest_t_abs[arx][i] > ymax)
- ymax = chest_t_abs[arx][i];
- }
-
- fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
- fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
- }
- }
- */
- // Avoid flickering effect
- // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); // Does not always work...
- fl_set_xyplot_ybounds(form->chest_t,0,(double) ymax);
- }
- }
-
- // Channel Frequency Response (includes 5 complex sample for filter)
- if (chest_f != NULL) {
- ind = 0;
-
- for (atx=0; atxofdm_symbol_size; k++) {
- freq[ind] = (float)ind;
- Re = (float)(chest_f[(atx<<1)+arx][6144+(2*k)]);
- Im = (float)(chest_f[(atx<<1)+arx][6144+(2*k)+1]);
-
- chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im));
- ind++;
- }
- }
- }
- }
-
- // tx antenna 0
- //fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
- //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
- // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
- //fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
- fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,frame_parms->ofdm_symbol_size,"","","");
-
- /*
- for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
-
- // other tx antennas
- if (nb_antennas_tx > 1) {
- if (nb_antennas_rx > 1) {
- for (atx=1; atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- }
- } else { // 1 rx antenna
- atx=1;
- arx=0;
- fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- }
- */
- }
-
- // PBCH LLRs
- if (pbch_llr != NULL) {
- for (i=0; i<864; i++) {
- llr_pbch[i] = (float) pbch_llr[i];
- bit_pbch[i] = (float) i;
- }
-
- fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,864,"","","");
- }
-
- first_symbol=1;
-
- // PBCH I/Q of MF Output
- if (pbch_comp!=NULL) {
- for (symbol=first_symbol; symbol<(first_symbol+3); symbol++) {
- if (symbol == 2 || symbol == 6)
- nb_re = 72;
- else
- nb_re = 180;
- for (i=0; ipbch_comp,I,Q,432,"","","");
- }
-
- // PDCCH LLRs
- if (pdcch_llr != NULL) {
- for (i=0; i<100; i++) { //12*frame_parms->N_RB_DL*2*num_pdcch_symbols
- llr_pdcch[i] = (float) pdcch_llr[2*24*9 +i];
- bit_pdcch[i] = (float) i;
- }
-
- fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
- }
-
- // PDCCH I/Q of MF Output
- if (pdcch_comp!=NULL) {
- for (i=0; i<100; i++) {
- I[i] = pdcch_comp[2*50*12+2*i];
- Q[i] = pdcch_comp[2*50*12+2*i+1];
- }
- fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
- }
-
- // PDSCH LLRs
- if (pdsch_llr != NULL) {
- for (i=0; ipdsch_llr,0,coded_bits_per_codeword);
- fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","","");
- }
-
- first_symbol = 2;
- ind = 0;
- // PDSCH I/Q of MF Output
- if (pdsch_comp!=NULL) {
- for (symbol=0;symbolN_RB_DL*12+i) ];
- Q[ind] = pdsch_comp[2*((first_symbol+symbol)*frame_parms->N_RB_DL*12+i)+1];
- ind++;
- }
- }
-
- fl_set_xyplot_data(form->pdsch_comp,I,Q,nb_symb_sch*nb_rb_pdsch*12,"","","");
- }
- /*
-
- // PDSCH Throughput
- memmove( tput_time_ue[UE_id], &tput_time_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
- memmove( tput_ue[UE_id], &tput_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
-
- tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame;
- tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
-
- if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) {
- tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
- }
-
- fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","","");
-
- fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
- */
-
- fl_check_forms();
-
- free(time);
- free(corr);
- for (arx=0; arx graph->maxX || maxY > graph->maxY || minX < graph->minX || minY < graph->minY ) {
+ graph->maxX=max(graph->maxX,maxX);
+ graph->minX=min(graph->minX,minX);
+ graph->maxY=max(graph->maxY,maxY);
+ graph->minY=min(graph->minY,minY);
+ fl_set_xyplot_ybounds(graph->graph, graph->minY, graph->maxY);
+ fl_set_xyplot_xbounds(graph->graph, graph->minX, graph->maxX);
+ }
+}
+
+static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, int NoAutoScale) {
+ if (layer==0)
+ fl_set_xyplot_data(graph->graph,x,y,len,"","","");
+ else
+ fl_add_xyplot_overlay(graph->graph,layer,x,y,len,rx_antenna_colors[layer]);
+
+ if ( NoAutoScale && graph->iteration%NoAutoScale == 0) {
+ float maxX=0, maxY=0, minX=0, minY=0;
+
+ for (int k=0; kiteration++;
+}
+
+static void genericLogPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
+ float *values=malloc(len*sizeof(*values));
+ float *time=malloc(len*sizeof(*time));
+
+ for (int ant=0; antcommon.rxdata)
+ return;
+
+ NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+ genericLogPowerPerAntena(graph, frame_parms->nb_antennas_rx,
+ (const scopeSample_t **)phy_vars_ru->common.rxdata,
+ frame_parms->samples_per_frame);
+}
+
+static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+ const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size;
+ float values[len];
+ float time[len];
+ const int ant=0; // display antenna 0 for each UE
+
+ for (int ue=0; uepusch_vars[ue]->ul_ch_estimates_time[ant];
+
+ if (data != NULL) {
+ for (int i=0; iframe_parms;
+ genericLogPowerPerAntena(graph, frame_parms->nb_antennas_rx,
+ (const scopeSample_t **)phy_vars_ru->common.rxdataF,
+ frame_parms->samples_per_slot_wCP);
+}
+
+static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+ //int Qm = 2;
+ int coded_bits_per_codeword =3*8*6144+12; // (8*((3*8*6144)+12)); // frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
+ float llr[coded_bits_per_codeword];
+ float bit[coded_bits_per_codeword];
+
+ for (int ue=0; uepusch_vars[ue]->llr;
+
+ if (pusch_llr) {
+ for (int i=0; iframe_parms;
+ int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot;
+ float I[sz], Q[sz];
+
+ for (int ue=0; uepusch_vars[ue]->rxdataF_comp[0];
+
+ if (pusch_comp) {
+ for (int k=0; kpucch1ab_stats[UE_id];
+ int32_t *pucch1_comp = (int32_t *) NULL; //phy_vars_gnb->pucch1_stats[UE_id];
+ float I_pucch[10240],Q_pucch[10240],A_pucch[10240],B_pucch[10240],C_pucch[10240];
+
+ for (int ind=0; ind<10240; ind++) {
+ I_pucch[ind] = (float)pucch1ab_comp[2*(ind)];
+ Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1];
+ A_pucch[ind] = pucch1_comp?(10*log10(pucch1_comp[ind])):0;
+ B_pucch[ind] = ind;
+ int32_t *pucch1_thres = (int32_t *) NULL; // phy_vars_gnb->pucch1_stats_thres[UE_id];
+ C_pucch[ind] = pucch1_thres?(float)pucch1_thres[ind]:0;
+ }
+
+ fl_set_xyplot_data(graph,I_pucch,Q_pucch,10240,"","","");
+ fl_set_xyplot_data(graph,B_pucch,A_pucch,1024,"","","");
+ fl_add_xyplot_overlay(graph,1,B_pucch,C_pucch,1024,FL_RED);
+ fl_set_xyplot_ybounds(graph,-5000,5000);
+ fl_set_xyplot_xbounds(graph,-5000,5000);
+ fl_set_xyplot_ybounds(graph,0,80);
+ }
+ */
+}
+
+static void pucchIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+}
+
+static void puschThroughtput (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+ // PUSCH Throughput
+ /*
+ memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
+ memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
+ tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1] = (float) 0;
+ // tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
+ fl_set_xyplot_data(graph,tput_time_enb[UE_id],tput_enb[UE_id],TPUT_WINDOW_LENGTH,"","","");
+ // fl_get_xyplot_ybounds(form->pusch_tput,&ymin,&ymax);
+ // fl_set_xyplot_ybounds(form->pusch_tput,0,ymax);
+ */
+}
+
+static OAI_phy_scope_t *create_phy_scope_gnb(void) {
+ FL_OBJECT *obj;
+ OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
+ // Define form
+ fdui->phy_scope = fl_bgn_form( FL_NO_BOX, 800, 800 );
+ // This the whole UI box
+ obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
+ fl_set_object_color( obj, FL_BLACK, FL_WHITE );
+ int curY=0,x,y,w,h;
+ // Received signal
+ fdui->graph[0] = gNBcommonGraph( timeSignal, FL_NORMAL_XYPLOT, 0, curY, 400, 100,
+ "Received Signal (Time-Domain, dB)", FL_RED );
+ // Time-domain channel response
+ fdui->graph[1] = gNBcommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, curY, 400, 100,
+ "SRS Frequency Response (samples, abs)", FL_RED );
+ fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h);
+ curY+=h;
+ // Frequency-domain channel response
+ fdui->graph[2] = gNBcommonGraph( frequencyResponse, FL_NORMAL_XYPLOT, 0, curY, 800, 100,
+ "Channel Frequency Response (RE, dB)", FL_RED );
+ fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
+ curY+=h;
+ // LLR of PUSCH
+ fdui->graph[3] = gNBcommonGraph( puschLLR, FL_POINTS_XYPLOT, 0, curY, 500, 200,
+ "PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
+ // I/Q PUSCH comp
+ fdui->graph[4] = gNBcommonGraph( puschIQ, FL_POINTS_XYPLOT, 500, curY, 300, 200,
+ "PUSCH I/Q of MF Output", FL_YELLOW );
+ fl_get_object_bbox(fdui->graph[3].graph,&x, &y,&w, &h);
+ curY+=h;
+ // I/Q PUCCH comp (format 1)
+ fdui->graph[5] = gNBcommonGraph( pucchEnergy, FL_POINTS_XYPLOT, 0, curY, 300, 100,
+ "PUCCH1 Energy (SR)", FL_YELLOW );
+ // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
+ // I/Q PUCCH comp (fromat 1a/b)
+ fdui->graph[6] = gNBcommonGraph( pucchIQ, FL_POINTS_XYPLOT, 500, curY, 300, 100,
+ "PUCCH I/Q of MF Output", FL_YELLOW );
+ fl_get_object_bbox(fdui->graph[6].graph,&x, &y,&w, &h);
+ curY+=h;
+ // Throughput on PUSCH
+ fdui->graph[7] = gNBcommonGraph( puschThroughtput, FL_NORMAL_XYPLOT, 0, curY, 500, 100,
+ "PUSCH Throughput [frame]/[kbit/s]", FL_WHITE );
+ fdui->graph[8].graph=NULL;
+ fl_end_form( );
+ fdui->phy_scope->fdui = fdui;
+ fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "LTE UL SCOPE gNB");
+ return fdui;
+}
+
+static const int scope_enb_num_ue = 1;
+void phy_scope_gNB(OAI_phy_scope_t *form,
+ PHY_VARS_gNB *phy_vars_gnb,
+ RU_t *phy_vars_ru,
+ int UE_id) {
+ static OAI_phy_scope_t *remeberForm=NULL;
+
+ if (form==NULL)
+ form=remeberForm;
+ else
+ remeberForm=form;
+
+ if (form==NULL) return;
+
+ int i=0;
+
+ while (form->graph[i].graph) {
+ form->graph[i].gNBfunct(form->graph+i, phy_vars_gnb, phy_vars_ru, UE_id);
+ i++;
+ }
+
+ fl_check_forms();
+}
+
+static void *scope_thread_gNB(void *arg) {
+ scopeParms_t *p=(scopeParms_t *) arg;
+ //# ifdef ENABLE_XFORMS_WRITE_STATS
+ // FILE *gNB_stats = fopen("gNB_stats.txt", "w");
+ //#endif
+ size_t stksize=0;
+ pthread_attr_t atr= {0};
+ pthread_attr_getstacksize(&atr, &stksize);
+ pthread_attr_setstacksize(&atr,32*1024*1024 );
+ sleep(3); // no clean interthread barriers
+ fl_initialize (p->argc, p->argv, NULL, 0, 0);
+ int nb_ue=min(NUMBER_OF_UE_MAX, scope_enb_num_ue);
+ OAI_phy_scope_t *form_gnb = create_phy_scope_gnb();
+
+ while (!oai_exit) {
+ phy_scope_gNB(form_gnb, p->gNB, p->ru, nb_ue);
+ usleep(99*1000);
+ }
+
+ return NULL;
+}
+
+void gNBinitScope(scopeParms_t *p) {
+ static scopeParms_t parms;
+ memcpy(&parms,p,sizeof(parms));
+ pthread_t forms_thread;
+ threadCreate(&forms_thread, scope_thread_gNB, &parms, "scope", -1, OAI_PRIORITY_RT_LOW);
+}
+
+static void ueTimeResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // Received signal in time domain of receive antenna 0
+ genericLogPowerPerAntena(graph, phy_vars_ue->frame_parms.nb_antennas_rx,
+ (const scopeSample_t **) phy_vars_ue->common_vars.rxdata,
+ phy_vars_ue->frame_parms.samples_per_frame);
+}
+
+static void ueChannelResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // Channel Impulse Response
+ genericPowerPerAntena(graph, phy_vars_ue->frame_parms.nb_antennas_rx,
+ (const scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time,
+ phy_vars_ue->frame_parms.ofdm_symbol_size>>3);
+}
+
+static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // Channel Frequency Response (includes 5 complex sample for filter)
+ if (!phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates)
+ return;
+
+ NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_gNB;
+ scopeSample_t **chest_f = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
+ int ind = 0;
+ float chest_f_abs[frame_parms->ofdm_symbol_size];
+ float freq[frame_parms->ofdm_symbol_size];
+
+ for (int atx=0; atxofdm_symbol_size; k++) {
+ freq[ind] = (float)ind;
+ chest_f_abs[ind] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][6144+k]));
+ ind++;
+ }
+ }
+ }
+ }
+
+ // tx antenna 0
+ //fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
+ //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
+ // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
+ //fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
+ oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10);
+}
+
+static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // PBCH LLRs
+ if ( !phy_vars_ue->pbch_vars[eNB_id]->llr)
+ return;
+
+ int16_t *pbch_llr = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->llr;
+ float llr_pbch[864], bit_pbch[864];
+
+ for (int i=0; i<864; i++) {
+ llr_pbch[i] = (float) pbch_llr[i];
+ bit_pbch[i] = (float) i;
+ }
+
+ oai_xygraph(graph,bit_pbch,llr_pbch,864,0,10);
+}
+
+static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // PBCH I/Q of MF Output
+ if (!phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0])
+ return;
+
+ scopeSample_t *pbch_comp = (scopeSample_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
+ localBuff(I,180*3);
+ localBuff(Q,180*3);
+ int first_symbol=1;
+ int base=0;
+
+ for (int symbol=first_symbol; symbol<(first_symbol+3); symbol++) {
+ int nb_re;
+
+ if (symbol == 2 || symbol == 6)
+ nb_re = 72;
+ else
+ nb_re = 180;
+
+ AssertFatal(base+nb_re<180*3,"");
+
+ for (int i=0; ipdcch_vars[0][eNB_id]->llr)
+ return;
+
+ NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ uint8_t nb_antennas_tx = frame_parms->nb_antennas_tx;
+ scopeSample_t **chest_f = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
+ int ind = 0;
+ float chest_f_abs[frame_parms->ofdm_symbol_size];
+ float freq[frame_parms->ofdm_symbol_size];
+
+ for (int atx=0; atxofdm_symbol_size; k++) {
+ freq[ind] = (float)ind;
+ chest_f_abs[ind] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][6144+k]));
+ ind++;
+ }
+ }
+ }
+ }
+
+ // tx antenna 0
+ //fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
+ //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
+ // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
+ //fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
+ oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10);
+}
+
+static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // PDCCH I/Q of MF Output
+ if (!phy_vars_ue->pdcch_vars[0][eNB_id]->rxdataF_comp[0])
+ return;
+
+ int nb=4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
+ localBuff(I,nb*RX_NB_TH_MAX);
+ localBuff(Q,nb*RX_NB_TH_MAX);
+ int base=0;
+
+ for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
+ scopeSample_t *pdcch_comp = (scopeSample_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->rxdataF_comp[0];
+
+ for (int i=0; i< nb; i++) {
+ I[base+i] = pdcch_comp[i].r;
+ Q[base+i] = pdcch_comp[i].i;
+ }
+
+ base+=nb;
+ }
+
+ oai_xygraph(graph,I,Q,base,0,10);
+}
+
+static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // PDSCH LLRs
+ if (!phy_vars_ue->pdsch_vars[0][eNB_id]->llr[0])
+ return;
+
+ int num_re = 4500;
+ int Qm = 2;
+ int coded_bits_per_codeword = num_re*Qm;
+ localBuff(llr,coded_bits_per_codeword*RX_NB_TH_MAX);
+ localBuff(bit,coded_bits_per_codeword*RX_NB_TH_MAX);
+ int base=0;
+
+ for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
+ int16_t *pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[thr][eNB_id]->llr[0]; // stream 0
+
+ for (int i=0; ipdsch_llr,0,coded_bits_per_codeword);
+ oai_xygraph(graph,bit,llr,base,0,10);
+}
+
+static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // PDSCH I/Q of MF Output
+ if (!phy_vars_ue->pdsch_vars[0][eNB_id]->rxdataF_comp0[0])
+ return;
+
+ NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+ int sz=7*2*frame_parms->N_RB_DL*12; // size of the malloced buffer
+ localBuff(I,sz*RX_NB_TH_MAX);
+ localBuff(Q,sz*RX_NB_TH_MAX);
+ int base=0;
+
+ for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
+ scopeSample_t *pdsch_comp = (scopeSample_t *) phy_vars_ue->pdsch_vars[thr][eNB_id]->rxdataF_comp0[0];
+
+ for (int s=0; s tput_ue_max[UE_id]) {
+ tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
+ }
+
+ fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","","");
+
+ fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
+ */
+}
+
+static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
+ FL_OBJECT *obj;
+ OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
+ // Define form
+ fdui->phy_scope = fl_bgn_form( FL_NO_BOX, 800, 900 );
+ // This the whole UI box
+ obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 900, "" );
+ fl_set_object_color( obj, FL_BLACK, FL_BLACK );
+ int curY=0,x,y,w,h;
+ // Received signal
+ fdui->graph[0] = nrUEcommonGraph(ueTimeResponse,
+ FL_NORMAL_XYPLOT, 0, curY, 400, 100, "Received Signal (Time-Domain, dB)", FL_RED );
+ // Time-domain channel response
+ fdui->graph[1] = nrUEcommonGraph(ueChannelResponse,
+ FL_NORMAL_XYPLOT, 400, curY, 400, 100, "Channel Impulse Response (samples, abs)", FL_RED );
+ fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h);
+ curY+=h;
+ // Frequency-domain channel response
+ fdui->graph[2] = nrUEcommonGraph(uePbchFrequencyResp,
+ FL_IMPULSE_XYPLOT, 0, curY, 800, 100, "Channel Frequency data (RE, dB)", FL_RED );
+ fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
+ curY+=h;
+ // LLR of PBCH
+ fdui->graph[3] = nrUEcommonGraph(uePbchLLR,
+ FL_POINTS_XYPLOT, 0, curY, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)", FL_GREEN );
+ fl_set_xyplot_xgrid(fdui->graph[3].graph,FL_GRID_MAJOR);
+ // I/Q PBCH comp
+ fdui->graph[4] = nrUEcommonGraph(uePbchIQ,
+ FL_POINTS_XYPLOT, 500, curY, 300, 100, "PBCH I/Q of MF Output", FL_GREEN );
+ fl_get_object_bbox(fdui->graph[3].graph,&x, &y,&w, &h);
+ curY+=h;
+ // LLR of PDCCH
+ fdui->graph[5] = nrUEcommonGraph(uePcchLLR,
+ FL_POINTS_XYPLOT, 0, curY, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)", FL_CYAN );
+ // I/Q PDCCH comp
+ fdui->graph[6] = nrUEcommonGraph(uePcchIQ,
+ FL_POINTS_XYPLOT, 500, curY, 300, 100, "PDCCH I/Q of MF Output", FL_CYAN );
+ fl_get_object_bbox(fdui->graph[5].graph,&x, &y,&w, &h);
+ curY+=h;
+ // LLR of PDSCH
+ fdui->graph[7] = nrUEcommonGraph(uePdschLLR,
+ FL_POINTS_XYPLOT, 0, curY, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
+ // I/Q PDSCH comp
+ fdui->graph[8] = nrUEcommonGraph(uePdschIQ,
+ FL_POINTS_XYPLOT, 500, curY, 300, 200, "PDSCH I/Q of MF Output", FL_YELLOW );
+ fl_get_object_bbox(fdui->graph[8].graph,&x, &y,&w, &h);
+ curY+=h;
+ // Throughput on PDSCH
+ fdui->graph[9] = nrUEcommonGraph(uePdschThroughput,
+ FL_NORMAL_XYPLOT, 0, curY, 500, 100, "PDSCH Throughput [frame]/[kbit/s]", FL_WHITE );
+ fdui->graph[10].graph=NULL;
+ // Generic UE Button
+#if 0
+ fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
+ fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
+ //openair_daq_vars.use_ia_receiver = 0;
+ fl_set_button(fdui->button_0,0);
+ fl_set_object_label(fdui->button_0, "IA Receiver OFF");
+ fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
+ fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 );
+ fl_hide_object(fdui->button_0);
+#endif
+ fl_end_form( );
+ fdui->phy_scope->fdui = fdui;
+ char buf[100];
+ sprintf(buf,"NR DL SCOPE UE %d", ID);
+ fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, buf);
+ return fdui;
+}
+
+void phy_scope_nrUE(OAI_phy_scope_t *form,
+ PHY_VARS_NR_UE *phy_vars_ue,
+ int eNB_id,
+ int UE_id) {
+ static OAI_phy_scope_t *remeberForm=NULL;
+
+ if (form==NULL)
+ form=remeberForm;
+ else
+ remeberForm=form;
+
+ if (form==NULL)
+ return;
+
+ int i=0;
+
+ while (form->graph[i].graph) {
+ form->graph[i].nrUEfunct(form->graph+i, phy_vars_ue, eNB_id, UE_id);
+ i++;
+ }
+
+ fl_check_forms();
+}
+
+
+static void *nrUEscopeThread(void *arg) {
+ PHY_VARS_NR_UE *ue=(PHY_VARS_NR_UE *)arg;
+ size_t stksize;
+ pthread_attr_t atr;
+ pthread_attr_getstacksize(&atr, &stksize);
+ pthread_attr_setstacksize(&atr,32*1024*1024 );
+ int fl_argc=1;
+ char *name="5G-UE-scope";
+ fl_initialize (&fl_argc, &name, NULL, 0, 0);
+ OAI_phy_scope_t *form_nrue=create_phy_scope_nrue(0);
+
+ while (!oai_exit) {
+ phy_scope_nrUE(form_nrue,
+ ue,
+ 0,0);
+ usleep(99*1000);
+ }
+
+ pthread_exit((void *)arg);
+}
+
+void nrUEinitScope(PHY_VARS_NR_UE *ue) {
+ pthread_t forms_thread;
+ threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
+}
+
+// Kept to put back the functionality soon
+#if 0
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
//char title[255];
-unsigned char scope_enb_num_ue = 1;
//static pthread_t forms_thread; //xforms
-
-
-void reset_stats_gNB(FL_OBJECT *button,
- long arg)
-{
+static void reset_stats_gNB(FL_OBJECT *button,
+ long arg) {
int i,k;
//PHY_VARS_gNB *phy_vars_gNB = RC.gNB[0][0];
for (i=0; idlsch[i][0]->Mlimit; j++) {
- phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0;
- phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0;
- phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0;
- }
- phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0;
- phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0;
- phy_vars_gNB->UE_stats[i].ulsch_consecutive_errors=0;
- phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0;
- phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0;
- phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0;*/
- }
- }
-}
-
-
-static void *scope_thread_gNB(void *arg) {
- int UE_id;
- int ue_cnt=0;
-//# ifdef ENABLE_XFORMS_WRITE_STATS
-// FILE *gNB_stats = fopen("gNB_stats.txt", "w");
-//#endif
-
- while (!oai_exit) {
- ue_cnt=0;
-
- for(UE_id=0; UE_idUE_stats[i].dlsch_NAK[k][j]=0;
+ phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0;
+ phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0;
}
+ phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0;
+ phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0;
+ phy_vars_gNB->UE_stats[i].ulsch_consecutive_errors=0;
+ phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0;
+ phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0;
+ phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0;*/
}
- sleep(1);
}
-
-// printf("%s",stats_buffer);
-/*#ifdef ENABLE_XFORMS_WRITE_STATS
-
- if (eNB_stats) {
- rewind (gNB_stats);
- fwrite (stats_buffer, 1, len, gNB_stats);
- fclose (gNB_stats);
- }
-
-#endif
- pthread_exit((void *)arg);
-}*/
-
- return NULL;
}
-FD_stats_form * create_form_stats_form( void ) {
+static FD_stats_form *create_form_stats_form(int ID) {
FL_OBJECT *obj;
- FD_stats_form *fdui = fl_malloc( sizeof *fdui );
+ FD_stats_form *fdui = calloc(( sizeof *fdui ),1);
fdui->vdata = fdui->cdata = NULL;
fdui->ldata = 0;
fdui->stats_form = fl_bgn_form( FL_NO_BOX, 1115, 900 );
@@ -964,24 +813,8 @@ FD_stats_form * create_form_stats_form( void ) {
fdui->stats_form->fdui = fdui;
return fdui;
}
+#endif
+
+
-void startScope(scopeParms_t * p) {
- //FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
- char title[255];
- fl_initialize (p->argc, p->argv, NULL, 0, 0);
- /*
- form_stats_l2 = create_form_stats_form();
- fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
- form_stats = create_form_stats_form();
- fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
- */
-
- for(int UE_id=0; UE_idphy_scope_gnb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
- } // UE_id
- pthread_t forms_thread;
- threadCreate(&forms_thread, scope_thread_gNB, NULL, "scope", -1, OAI_PRIORITY_RT_LOW);
-}
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.h b/openair1/PHY/TOOLS/nr_phy_scope.h
index aaee08a554..429537141a 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.h
+++ b/openair1/PHY/TOOLS/nr_phy_scope.h
@@ -26,71 +26,22 @@
#include
#include
#include
-#include
#include "common/ran_context.h"
#include
-#include
#include "PHY/defs_gNB.h"
//#include "PHY/defs_nrUE.h"
//#include "PHY/impl_defs_top.h"
#include "PHY/defs_nr_UE.h"
-/* Forms and Objects */
-typedef struct {
- FL_FORM * phy_scope_gnb;
- FL_OBJECT * rxsig_t;
- FL_OBJECT * chest_f;
- FL_OBJECT * chest_t;
- FL_OBJECT * pusch_comp;
- FL_OBJECT * pucch_comp;
- FL_OBJECT * pucch_comp1;
- FL_OBJECT * pusch_llr;
- FL_OBJECT * pusch_tput;
- FL_OBJECT * button_0;
-} FD_phy_scope_gnb;
-
-typedef struct {
- FL_FORM * phy_scope_nrue;
- FL_OBJECT * rxsig_t;
- FL_OBJECT * chest_f;
- FL_OBJECT * chest_t;
- FL_OBJECT * pbch_comp;
- FL_OBJECT * pbch_llr;
- FL_OBJECT * pdcch_comp;
- FL_OBJECT * pdcch_llr;
- FL_OBJECT * pdsch_comp;
- FL_OBJECT * pdsch_llr;
- FL_OBJECT * pdsch_comp1;
- FL_OBJECT * pdsch_llr1;
- FL_OBJECT * pdsch_tput;
- FL_OBJECT * button_0;
-} FD_phy_scope_nrue;
-
typedef struct {
int *argc;
char **argv;
+ RU_t *ru;
+ PHY_VARS_gNB *gNB;
} scopeParms_t;
-extern unsigned char scope_enb_num_ue;
-FD_phy_scope_gnb * create_phy_scope_gnb( void );
-FD_phy_scope_nrue * create_phy_scope_nrue( void );
-
-
-void phy_scope_gNB(FD_phy_scope_gnb *form,
- PHY_VARS_gNB *phy_vars_gnb,
- RU_t *phy_vars_ru,
- int UE_id);
-
-
-void phy_scope_nrUE(FD_phy_scope_nrue *form,
- PHY_VARS_NR_UE *phy_vars_ue,
- int eNB_id,
- int UE_id,
- uint8_t subframe);
-
-
-void startScope(scopeParms_t * p);
-
+void gNBinitScope(scopeParms_t *p);
+void nrUEinitScope(PHY_VARS_NR_UE *ue);
extern RAN_CONTEXT_t RC;
#endif
diff --git a/openair1/PHY/TOOLS/oai_dfts.c b/openair1/PHY/TOOLS/oai_dfts.c
index bd516cd1e0..25244eeff5 100644
--- a/openair1/PHY/TOOLS/oai_dfts.c
+++ b/openair1/PHY/TOOLS/oai_dfts.c
@@ -5353,6 +5353,607 @@ void idft8192(int16_t *x,int16_t *y,unsigned char scale)
#endif
+int16_t tw16384[3*2*4096];
+
+#ifndef __AVX2__
+void dft16384(int16_t *x,int16_t *y,unsigned char scale)
+{
+
+ simd_q15_t xtmp[4096],ytmp[4096],*tw16384_128p=(simd_q15_t *)tw16384,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
+ simd_q15_t *ytmpp = &ytmp[0];
+ int i,j;
+
+ for (i=0,j=0; i<4096; i+=4,j++) {
+ transpose16_ooff(x128+i,xtmp+j,1024);
+ }
+
+
+ dft4096((int16_t*)(xtmp),(int16_t*)(ytmp),1);
+ dft4096((int16_t*)(xtmp+1024),(int16_t*)(ytmp+1024),1);
+ dft4096((int16_t*)(xtmp+2048),(int16_t*)(ytmp+2048),1);
+ dft4096((int16_t*)(xtmp+3072),(int16_t*)(ytmp+3072),1);
+
+ for (i=0; i<1024; i++) {
+ bfly4(ytmpp,ytmpp+1024,ytmpp+2048,ytmpp+3072,
+ y128p,y128p+1024,y128p+2048,y128p+3072,
+ tw16384_128p,tw16384_128p+1024,tw16384_128p+2048);
+ tw16384_128p++;
+ y128p++;
+ ytmpp++;
+ }
+
+ if (scale>0) {
+
+ for (i=0; i<256; i++) {
+ y128[0] = shiftright_int16(y128[0],1);
+ y128[1] = shiftright_int16(y128[1],1);
+ y128[2] = shiftright_int16(y128[2],1);
+ y128[3] = shiftright_int16(y128[3],1);
+ y128[4] = shiftright_int16(y128[4],1);
+ y128[5] = shiftright_int16(y128[5],1);
+ y128[6] = shiftright_int16(y128[6],1);
+ y128[7] = shiftright_int16(y128[7],1);
+ y128[8] = shiftright_int16(y128[8],1);
+ y128[9] = shiftright_int16(y128[9],1);
+ y128[10] = shiftright_int16(y128[10],1);
+ y128[11] = shiftright_int16(y128[11],1);
+ y128[12] = shiftright_int16(y128[12],1);
+ y128[13] = shiftright_int16(y128[13],1);
+ y128[14] = shiftright_int16(y128[14],1);
+ y128[15] = shiftright_int16(y128[15],1);
+
+ y128+=16;
+ }
+
+ }
+
+ _mm_empty();
+ _m_empty();
+
+}
+
+
+
+void idft16384(int16_t *x,int16_t *y,unsigned char scale)
+{
+
+ simd_q15_t xtmp[4096],ytmp[4096],*tw16384_128p=(simd_q15_t *)tw16384,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
+ simd_q15_t *ytmpp = &ytmp[0];
+ int i,j;
+
+ for (i=0,j=0; i<4096; i+=4,j++) {
+ transpose16_ooff(x128+i,xtmp+j,1024);
+ }
+
+
+ idft4096((int16_t*)(xtmp),(int16_t*)(ytmp),1);
+ idft4096((int16_t*)(xtmp+1024),(int16_t*)(ytmp+1024),1);
+ idft4096((int16_t*)(xtmp+2048),(int16_t*)(ytmp+2048),1);
+ idft4096((int16_t*)(xtmp+3072),(int16_t*)(ytmp+3072),1);
+
+ for (i=0; i<1024; i++) {
+ ibfly4(ytmpp,ytmpp+1024,ytmpp+2048,ytmpp+3072,
+ y128p,y128p+1024,y128p+2048,y128p+3072,
+ tw16384_128p,tw16384_128p+1024,tw16384_128p+2048);
+ tw16384_128p++;
+ y128p++;
+ ytmpp++;
+ }
+
+ if (scale>0) {
+
+ for (i=0; i<256; i++) {
+ y128[0] = shiftright_int16(y128[0],scale);
+ y128[1] = shiftright_int16(y128[1],scale);
+ y128[2] = shiftright_int16(y128[2],scale);
+ y128[3] = shiftright_int16(y128[3],scale);
+ y128[4] = shiftright_int16(y128[4],scale);
+ y128[5] = shiftright_int16(y128[5],scale);
+ y128[6] = shiftright_int16(y128[6],scale);
+ y128[7] = shiftright_int16(y128[7],scale);
+ y128[8] = shiftright_int16(y128[8],scale);
+ y128[9] = shiftright_int16(y128[9],scale);
+ y128[10] = shiftright_int16(y128[10],scale);
+ y128[11] = shiftright_int16(y128[11],scale);
+ y128[12] = shiftright_int16(y128[12],scale);
+ y128[13] = shiftright_int16(y128[13],scale);
+ y128[14] = shiftright_int16(y128[14],scale);
+ y128[15] = shiftright_int16(y128[15],scale);
+
+ y128+=16;
+ }
+
+ }
+
+ _mm_empty();
+ _m_empty();
+
+}
+
+#else //__AVX2__
+void dft16384(int16_t *x,int16_t *y,unsigned char scale)
+{
+
+ simd256_q15_t xtmp[2048],ytmp[2048],*tw16384_256p=(simd256_q15_t *)tw16384,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
+ simd256_q15_t *ytmpp = &ytmp[0];
+ int i,j;
+
+ for (i=0,j=0; i<2048; i+=4,j++) {
+ transpose16_ooff_simd256(x256+i,xtmp+j,512);
+ }
+
+
+ dft4096((int16_t*)(xtmp),(int16_t*)(ytmp),1);
+ dft4096((int16_t*)(xtmp+512),(int16_t*)(ytmp+512),1);
+ dft4096((int16_t*)(xtmp+1024),(int16_t*)(ytmp+1024),1);
+ dft4096((int16_t*)(xtmp+1536),(int16_t*)(ytmp+1536),1);
+
+ for (i=0; i<512; i++) {
+ bfly4_256(ytmpp,ytmpp+512,ytmpp+1024,ytmpp+1536,
+ y256p,y256p+512,y256p+1024,y256p+1536,
+ tw16384_256p,tw16384_256p+512,tw16384_256p+1024);
+ tw16384_256p++;
+ y256p++;
+ ytmpp++;
+ }
+
+ if (scale>0) {
+
+ for (i=0; i<128; i++) {
+ y256[0] = shiftright_int16_simd256(y256[0],1);
+ y256[1] = shiftright_int16_simd256(y256[1],1);
+ y256[2] = shiftright_int16_simd256(y256[2],1);
+ y256[3] = shiftright_int16_simd256(y256[3],1);
+ y256[4] = shiftright_int16_simd256(y256[4],1);
+ y256[5] = shiftright_int16_simd256(y256[5],1);
+ y256[6] = shiftright_int16_simd256(y256[6],1);
+ y256[7] = shiftright_int16_simd256(y256[7],1);
+ y256[8] = shiftright_int16_simd256(y256[8],1);
+ y256[9] = shiftright_int16_simd256(y256[9],1);
+ y256[10] = shiftright_int16_simd256(y256[10],1);
+ y256[11] = shiftright_int16_simd256(y256[11],1);
+ y256[12] = shiftright_int16_simd256(y256[12],1);
+ y256[13] = shiftright_int16_simd256(y256[13],1);
+ y256[14] = shiftright_int16_simd256(y256[14],1);
+ y256[15] = shiftright_int16_simd256(y256[15],1);
+
+ y256+=16;
+ }
+
+ }
+
+ _mm_empty();
+ _m_empty();
+
+}
+
+void idft16384(int16_t *x,int16_t *y,unsigned char scale)
+{
+
+ simd256_q15_t xtmp[2048],ytmp[2048],*tw16384_256p=(simd256_q15_t *)tw16384,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
+ simd256_q15_t *ytmpp = &ytmp[0];
+ int i,j;
+
+ for (i=0,j=0; i<2048; i+=4,j++) {
+ transpose16_ooff_simd256(x256+i,xtmp+j,512);
+ }
+
+
+ idft4096((int16_t*)(xtmp),(int16_t*)(ytmp),1);
+ idft4096((int16_t*)(xtmp+512),(int16_t*)(ytmp+512),1);
+ idft4096((int16_t*)(xtmp+1024),(int16_t*)(ytmp+1024),1);
+ idft4096((int16_t*)(xtmp+1536),(int16_t*)(ytmp+1536),1);
+
+ for (i=0; i<512; i++) {
+ ibfly4_256(ytmpp,ytmpp+512,ytmpp+1024,ytmpp+1536,
+ y256p,y256p+512,y256p+1024,y256p+1536,
+ tw16384_256p,tw16384_256p+512,tw16384_256p+1024);
+ tw16384_256p++;
+ y256p++;
+ ytmpp++;
+ }
+
+ if (scale>0) {
+
+ for (i=0; i<128; i++) {
+ y256[0] = shiftright_int16_simd256(y256[0],1);
+ y256[1] = shiftright_int16_simd256(y256[1],1);
+ y256[2] = shiftright_int16_simd256(y256[2],1);
+ y256[3] = shiftright_int16_simd256(y256[3],1);
+ y256[4] = shiftright_int16_simd256(y256[4],1);
+ y256[5] = shiftright_int16_simd256(y256[5],1);
+ y256[6] = shiftright_int16_simd256(y256[6],1);
+ y256[7] = shiftright_int16_simd256(y256[7],1);
+ y256[8] = shiftright_int16_simd256(y256[8],1);
+ y256[9] = shiftright_int16_simd256(y256[9],1);
+ y256[10] = shiftright_int16_simd256(y256[10],1);
+ y256[11] = shiftright_int16_simd256(y256[11],1);
+ y256[12] = shiftright_int16_simd256(y256[12],1);
+ y256[13] = shiftright_int16_simd256(y256[13],1);
+ y256[14] = shiftright_int16_simd256(y256[14],1);
+ y256[15] = shiftright_int16_simd256(y256[15],1);
+
+ y256+=16;
+ }
+
+ }
+
+ _mm_empty();
+ _m_empty();
+
+}
+
+#endif //__AVX2__
+
+int16_t tw32768[2*16384] __attribute__((aligned(32)));
+
+#ifndef __AVX2__
+void dft32768(int16_t *x,int16_t *y,unsigned char scale)
+{
+
+ simdshort_q15_t xtmp[16384],*xtmpp,*x64 = (simdshort_q15_t *)x;
+ simd_q15_t ytmp[8192],*tw32768_128p=(simd_q15_t *)tw32768,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
+ simd_q15_t *ytmpp = &ytmp[0];
+ int i;
+ simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
+
+ xtmpp = xtmp;
+
+ for (i=0; i<256; i++) {
+ transpose4_ooff(x64 ,xtmpp,8192);
+ transpose4_ooff(x64+2,xtmpp+1,8192);
+ transpose4_ooff(x64+4,xtmpp+2,8192);
+ transpose4_ooff(x64+6,xtmpp+3,8192);
+ transpose4_ooff(x64+8,xtmpp+4,8192);
+ transpose4_ooff(x64+10,xtmpp+5,8192);
+ transpose4_ooff(x64+12,xtmpp+6,8192);
+ transpose4_ooff(x64+14,xtmpp+7,8192);
+ transpose4_ooff(x64+16,xtmpp+8,8192);
+ transpose4_ooff(x64+18,xtmpp+9,8192);
+ transpose4_ooff(x64+20,xtmpp+10,8192);
+ transpose4_ooff(x64+22,xtmpp+11,8192);
+ transpose4_ooff(x64+24,xtmpp+12,8192);
+ transpose4_ooff(x64+26,xtmpp+13,8192);
+ transpose4_ooff(x64+28,xtmpp+14,8192);
+ transpose4_ooff(x64+30,xtmpp+15,8192);
+ transpose4_ooff(x64+32,xtmpp+16,8192);
+ transpose4_ooff(x64+34,xtmpp+17,8192);
+ transpose4_ooff(x64+36,xtmpp+18,8192);
+ transpose4_ooff(x64+38,xtmpp+19,8192);
+ transpose4_ooff(x64+40,xtmpp+20,8192);
+ transpose4_ooff(x64+42,xtmpp+21,8192);
+ transpose4_ooff(x64+44,xtmpp+22,8192);
+ transpose4_ooff(x64+46,xtmpp+23,8192);
+ transpose4_ooff(x64+48,xtmpp+24,8192);
+ transpose4_ooff(x64+50,xtmpp+25,8192);
+ transpose4_ooff(x64+52,xtmpp+26,8192);
+ transpose4_ooff(x64+54,xtmpp+27,8192);
+ transpose4_ooff(x64+56,xtmpp+28,8192);
+ transpose4_ooff(x64+58,xtmpp+29,8192);
+ transpose4_ooff(x64+60,xtmpp+30,8192);
+ transpose4_ooff(x64+62,xtmpp+31,8192);
+ x64+=64;
+ xtmpp+=32;
+ }
+
+ dft16384((int16_t*)(xtmp),(int16_t*)ytmp,1);
+ dft16384((int16_t*)(xtmp+8192),(int16_t*)(ytmp+4096),1);
+
+
+ for (i=0; i<4096; i++) {
+ bfly2(ytmpp,ytmpp+4096,
+ y128p,y128p+4096,
+ tw32768_128p);
+ tw32768_128p++;
+ y128p++;
+ ytmpp++;
+ }
+
+ if (scale>0) {
+ y128p = y128;
+
+ for (i=0; i<512; i++) {
+ y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT2_Q15_128);
+ y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT2_Q15_128);
+ y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT2_Q15_128);
+ y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT2_Q15_128);
+ y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT2_Q15_128);
+ y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT2_Q15_128);
+ y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT2_Q15_128);
+ y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT2_Q15_128);
+ y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT2_Q15_128);
+ y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT2_Q15_128);
+ y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT2_Q15_128);
+ y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT2_Q15_128);
+ y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT2_Q15_128);
+ y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT2_Q15_128);
+ y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT2_Q15_128);
+ y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT2_Q15_128);
+ y128p+=16;
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+}
+
+void idft32768(int16_t *x,int16_t *y,unsigned char scale)
+{
+
+ simdshort_q15_t xtmp[16384],*xtmpp,*x64 = (simdshort_q15_t *)x;
+ simd_q15_t ytmp[8192],*tw32768_128p=(simd_q15_t *)tw32768,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
+ simd_q15_t *ytmpp = &ytmp[0];
+ int i;
+ simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
+
+ xtmpp = xtmp;
+
+ for (i=0; i<256; i++) {
+ transpose4_ooff(x64 ,xtmpp,8192);
+ transpose4_ooff(x64+2,xtmpp+1,8192);
+ transpose4_ooff(x64+4,xtmpp+2,8192);
+ transpose4_ooff(x64+6,xtmpp+3,8192);
+ transpose4_ooff(x64+8,xtmpp+4,8192);
+ transpose4_ooff(x64+10,xtmpp+5,8192);
+ transpose4_ooff(x64+12,xtmpp+6,8192);
+ transpose4_ooff(x64+14,xtmpp+7,8192);
+ transpose4_ooff(x64+16,xtmpp+8,8192);
+ transpose4_ooff(x64+18,xtmpp+9,8192);
+ transpose4_ooff(x64+20,xtmpp+10,8192);
+ transpose4_ooff(x64+22,xtmpp+11,8192);
+ transpose4_ooff(x64+24,xtmpp+12,8192);
+ transpose4_ooff(x64+26,xtmpp+13,8192);
+ transpose4_ooff(x64+28,xtmpp+14,8192);
+ transpose4_ooff(x64+30,xtmpp+15,8192);
+ transpose4_ooff(x64+32,xtmpp+16,8192);
+ transpose4_ooff(x64+34,xtmpp+17,8192);
+ transpose4_ooff(x64+36,xtmpp+18,8192);
+ transpose4_ooff(x64+38,xtmpp+19,8192);
+ transpose4_ooff(x64+40,xtmpp+20,8192);
+ transpose4_ooff(x64+42,xtmpp+21,8192);
+ transpose4_ooff(x64+44,xtmpp+22,8192);
+ transpose4_ooff(x64+46,xtmpp+23,8192);
+ transpose4_ooff(x64+48,xtmpp+24,8192);
+ transpose4_ooff(x64+50,xtmpp+25,8192);
+ transpose4_ooff(x64+52,xtmpp+26,8192);
+ transpose4_ooff(x64+54,xtmpp+27,8192);
+ transpose4_ooff(x64+56,xtmpp+28,8192);
+ transpose4_ooff(x64+58,xtmpp+29,8192);
+ transpose4_ooff(x64+60,xtmpp+30,8192);
+ transpose4_ooff(x64+62,xtmpp+31,8192);
+ x64+=64;
+ xtmpp+=32;
+ }
+
+ idft16384((int16_t*)(xtmp),(int16_t*)ytmp,1);
+ idft16384((int16_t*)(xtmp+8192),(int16_t*)(ytmp+4096),1);
+
+
+ for (i=0; i<4096; i++) {
+ ibfly2(ytmpp,ytmpp+4096,
+ y128p,y128p+4096,
+ tw32768_128p);
+ tw32768_128p++;
+ y128p++;
+ ytmpp++;
+ }
+
+ if (scale>0) {
+ y128p = y128;
+
+ for (i=0; i<512; i++) {
+ y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT2_Q15_128);
+ y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT2_Q15_128);
+ y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT2_Q15_128);
+ y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT2_Q15_128);
+ y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT2_Q15_128);
+ y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT2_Q15_128);
+ y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT2_Q15_128);
+ y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT2_Q15_128);
+ y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT2_Q15_128);
+ y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT2_Q15_128);
+ y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT2_Q15_128);
+ y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT2_Q15_128);
+ y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT2_Q15_128);
+ y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT2_Q15_128);
+ y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT2_Q15_128);
+ y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT2_Q15_128);
+ y128p+=16;
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+}
+
+#else // __AVX2__
+void dft32768(int16_t *x,int16_t *y,unsigned char scale)
+{
+
+ simd256_q15_t xtmp[4096],*xtmpp,*x256 = (simd256_q15_t *)x;
+ simd256_q15_t ytmp[4096],*tw32768_256p=(simd256_q15_t *)tw32768,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
+
+ simd256_q15_t *ytmpp = &ytmp[0];
+ int i;
+ simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
+
+ xtmpp = xtmp;
+
+ for (i=0; i<256; i++) {
+ transpose4_ooff_simd256(x256 ,xtmpp,2048);
+ transpose4_ooff_simd256(x256+2,xtmpp+1,2048);
+ transpose4_ooff_simd256(x256+4,xtmpp+2,2048);
+ transpose4_ooff_simd256(x256+6,xtmpp+3,2048);
+ transpose4_ooff_simd256(x256+8,xtmpp+4,2048);
+ transpose4_ooff_simd256(x256+10,xtmpp+5,2048);
+ transpose4_ooff_simd256(x256+12,xtmpp+6,2048);
+ transpose4_ooff_simd256(x256+14,xtmpp+7,2048);
+ transpose4_ooff_simd256(x256+16,xtmpp+8,2048);
+ transpose4_ooff_simd256(x256+18,xtmpp+9,2048);
+ transpose4_ooff_simd256(x256+20,xtmpp+10,2048);
+ transpose4_ooff_simd256(x256+22,xtmpp+11,2048);
+ transpose4_ooff_simd256(x256+24,xtmpp+12,2048);
+ transpose4_ooff_simd256(x256+26,xtmpp+13,2048);
+ transpose4_ooff_simd256(x256+28,xtmpp+14,2048);
+ transpose4_ooff_simd256(x256+30,xtmpp+15,2048);
+ transpose4_ooff_simd256(x256+32,xtmpp+16,2048);
+ transpose4_ooff_simd256(x256+34,xtmpp+17,2048);
+ transpose4_ooff_simd256(x256+36,xtmpp+18,2048);
+ transpose4_ooff_simd256(x256+38,xtmpp+19,2048);
+ transpose4_ooff_simd256(x256+40,xtmpp+20,2048);
+ transpose4_ooff_simd256(x256+42,xtmpp+21,2048);
+ transpose4_ooff_simd256(x256+44,xtmpp+22,2048);
+ transpose4_ooff_simd256(x256+46,xtmpp+23,2048);
+ transpose4_ooff_simd256(x256+48,xtmpp+24,2048);
+ transpose4_ooff_simd256(x256+50,xtmpp+25,2048);
+ transpose4_ooff_simd256(x256+52,xtmpp+26,2048);
+ transpose4_ooff_simd256(x256+54,xtmpp+27,2048);
+ transpose4_ooff_simd256(x256+56,xtmpp+28,2048);
+ transpose4_ooff_simd256(x256+58,xtmpp+29,2048);
+ transpose4_ooff_simd256(x256+60,xtmpp+30,2048);
+ transpose4_ooff_simd256(x256+62,xtmpp+31,2048);
+ x256+=64;
+ xtmpp+=32;
+ }
+
+ dft16384((int16_t*)(xtmp),(int16_t*)ytmp,1);
+ dft16384((int16_t*)(xtmp+2048),(int16_t*)(ytmp+2048),1);
+
+
+ for (i=0; i<2048; i++) {
+ bfly2_256(ytmpp,ytmpp+2048,
+ y256p,y256p+2048,
+ tw32768_256p);
+ tw32768_256p++;
+ y256p++;
+ ytmpp++;
+ }
+
+ if (scale>0) {
+ y256p = y256;
+
+ for (i=0; i<64; i++) {
+ y256p[0] = mulhi_int16_simd256(y256p[0],ONE_OVER_SQRT2_Q15_128);
+ y256p[1] = mulhi_int16_simd256(y256p[1],ONE_OVER_SQRT2_Q15_128);
+ y256p[2] = mulhi_int16_simd256(y256p[2],ONE_OVER_SQRT2_Q15_128);
+ y256p[3] = mulhi_int16_simd256(y256p[3],ONE_OVER_SQRT2_Q15_128);
+ y256p[4] = mulhi_int16_simd256(y256p[4],ONE_OVER_SQRT2_Q15_128);
+ y256p[5] = mulhi_int16_simd256(y256p[5],ONE_OVER_SQRT2_Q15_128);
+ y256p[6] = mulhi_int16_simd256(y256p[6],ONE_OVER_SQRT2_Q15_128);
+ y256p[7] = mulhi_int16_simd256(y256p[7],ONE_OVER_SQRT2_Q15_128);
+ y256p[8] = mulhi_int16_simd256(y256p[8],ONE_OVER_SQRT2_Q15_128);
+ y256p[9] = mulhi_int16_simd256(y256p[9],ONE_OVER_SQRT2_Q15_128);
+ y256p[10] = mulhi_int16_simd256(y256p[10],ONE_OVER_SQRT2_Q15_128);
+ y256p[11] = mulhi_int16_simd256(y256p[11],ONE_OVER_SQRT2_Q15_128);
+ y256p[12] = mulhi_int16_simd256(y256p[12],ONE_OVER_SQRT2_Q15_128);
+ y256p[13] = mulhi_int16_simd256(y256p[13],ONE_OVER_SQRT2_Q15_128);
+ y256p[14] = mulhi_int16_simd256(y256p[14],ONE_OVER_SQRT2_Q15_128);
+ y256p[15] = mulhi_int16_simd256(y256p[15],ONE_OVER_SQRT2_Q15_128);
+ y256p+=16;
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+}
+
+void idft32768(int16_t *x,int16_t *y,unsigned char scale)
+{
+
+ simd256_q15_t xtmp[4096],*xtmpp,*x256 = (simd256_q15_t *)x;
+ simd256_q15_t ytmp[4096],*tw32768_256p=(simd256_q15_t *)tw32768,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
+ simd256_q15_t *ytmpp = &ytmp[0];
+ int i;
+ simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
+
+ xtmpp = xtmp;
+
+ for (i=0; i<64; i++) {
+ transpose4_ooff_simd256(x256 ,xtmpp,2048);
+ transpose4_ooff_simd256(x256+2,xtmpp+1,2048);
+ transpose4_ooff_simd256(x256+4,xtmpp+2,2048);
+ transpose4_ooff_simd256(x256+6,xtmpp+3,2048);
+ transpose4_ooff_simd256(x256+8,xtmpp+4,2048);
+ transpose4_ooff_simd256(x256+10,xtmpp+5,2048);
+ transpose4_ooff_simd256(x256+12,xtmpp+6,2048);
+ transpose4_ooff_simd256(x256+14,xtmpp+7,2048);
+ transpose4_ooff_simd256(x256+16,xtmpp+8,2048);
+ transpose4_ooff_simd256(x256+18,xtmpp+9,2048);
+ transpose4_ooff_simd256(x256+20,xtmpp+10,2048);
+ transpose4_ooff_simd256(x256+22,xtmpp+11,2048);
+ transpose4_ooff_simd256(x256+24,xtmpp+12,2048);
+ transpose4_ooff_simd256(x256+26,xtmpp+13,2048);
+ transpose4_ooff_simd256(x256+28,xtmpp+14,2048);
+ transpose4_ooff_simd256(x256+30,xtmpp+15,2048);
+ transpose4_ooff_simd256(x256+32,xtmpp+16,2048);
+ transpose4_ooff_simd256(x256+34,xtmpp+17,2048);
+ transpose4_ooff_simd256(x256+36,xtmpp+18,2048);
+ transpose4_ooff_simd256(x256+38,xtmpp+19,2048);
+ transpose4_ooff_simd256(x256+40,xtmpp+20,2048);
+ transpose4_ooff_simd256(x256+42,xtmpp+21,2048);
+ transpose4_ooff_simd256(x256+44,xtmpp+22,2048);
+ transpose4_ooff_simd256(x256+46,xtmpp+23,2048);
+ transpose4_ooff_simd256(x256+48,xtmpp+24,2048);
+ transpose4_ooff_simd256(x256+50,xtmpp+25,2048);
+ transpose4_ooff_simd256(x256+52,xtmpp+26,2048);
+ transpose4_ooff_simd256(x256+54,xtmpp+27,2048);
+ transpose4_ooff_simd256(x256+56,xtmpp+28,2048);
+ transpose4_ooff_simd256(x256+58,xtmpp+29,2048);
+ transpose4_ooff_simd256(x256+60,xtmpp+30,2048);
+ transpose4_ooff_simd256(x256+62,xtmpp+31,2048);
+ x256+=64;
+ xtmpp+=32;
+ }
+
+ idft16384((int16_t*)(xtmp),(int16_t*)ytmp,1);
+ idft16384((int16_t*)(xtmp+2048),(int16_t*)(ytmp+2048),1);
+
+
+ for (i=0; i<2048; i++) {
+ ibfly2_256(ytmpp,ytmpp+2048,
+ y256p,y256p+2048,
+ tw32768_256p);
+ tw32768_256p++;
+ y256p++;
+ ytmpp++;
+ }
+
+ if (scale>0) {
+ y256p = y256;
+
+ for (i=0; i<256; i++) {
+ y256p[0] = mulhi_int16_simd256(y256p[0],ONE_OVER_SQRT2_Q15_128);
+ y256p[1] = mulhi_int16_simd256(y256p[1],ONE_OVER_SQRT2_Q15_128);
+ y256p[2] = mulhi_int16_simd256(y256p[2],ONE_OVER_SQRT2_Q15_128);
+ y256p[3] = mulhi_int16_simd256(y256p[3],ONE_OVER_SQRT2_Q15_128);
+ y256p[4] = mulhi_int16_simd256(y256p[4],ONE_OVER_SQRT2_Q15_128);
+ y256p[5] = mulhi_int16_simd256(y256p[5],ONE_OVER_SQRT2_Q15_128);
+ y256p[6] = mulhi_int16_simd256(y256p[6],ONE_OVER_SQRT2_Q15_128);
+ y256p[7] = mulhi_int16_simd256(y256p[7],ONE_OVER_SQRT2_Q15_128);
+ y256p[8] = mulhi_int16_simd256(y256p[8],ONE_OVER_SQRT2_Q15_128);
+ y256p[9] = mulhi_int16_simd256(y256p[9],ONE_OVER_SQRT2_Q15_128);
+ y256p[10] = mulhi_int16_simd256(y256p[10],ONE_OVER_SQRT2_Q15_128);
+ y256p[11] = mulhi_int16_simd256(y256p[11],ONE_OVER_SQRT2_Q15_128);
+ y256p[12] = mulhi_int16_simd256(y256p[12],ONE_OVER_SQRT2_Q15_128);
+ y256p[13] = mulhi_int16_simd256(y256p[13],ONE_OVER_SQRT2_Q15_128);
+ y256p[14] = mulhi_int16_simd256(y256p[14],ONE_OVER_SQRT2_Q15_128);
+ y256p[15] = mulhi_int16_simd256(y256p[15],ONE_OVER_SQRT2_Q15_128);
+ y256p+=16;
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+}
+
+
+#endif
+
+
int16_t twa1536[1024],twb1536[1024];
// 512 x 3
@@ -6061,28 +6662,214 @@ void idft24576(int16_t *input, int16_t *output,unsigned char scale)
}
int16_t twa36864[24576] __attribute__((aligned(32)));
-int16_t twb36884[24576] __attribute__((aligned(32)));
+int16_t twb36864[24576] __attribute__((aligned(32)));
+
// 12288 x 3
void dft36864(int16_t *input, int16_t *output,uint8_t scale) {
- AssertFatal(1==0,"Need to do this ..\n");
+ int i,i2,j;
+ uint32_t tmp[3][12288] __attribute__((aligned(32)));
+ uint32_t tmpo[3][12288] __attribute__((aligned(32)));
+ simd_q15_t *y128p=(simd_q15_t*)output;
+ simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
+
+ for (i=0,j=0; i<12288; i++) {
+ tmp[0][i] = ((uint32_t *)input)[j++];
+ tmp[1][i] = ((uint32_t *)input)[j++];
+ tmp[2][i] = ((uint32_t *)input)[j++];
+ }
+
+ dft12288((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
+ dft12288((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
+ dft12288((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
+
+ if (LOG_DUMPFLAG(DEBUG_DFT)) {
+ LOG_M("dft36864out0.m","o0",tmpo[0],12288,1,1);
+ LOG_M("dft36864out1.m","o1",tmpo[1],12288,1,1);
+ LOG_M("dft36864out2.m","o2",tmpo[2],12288,1,1);
+ }
+
+ for (i=0,i2=0; i<24576; i+=8,i2+=4) {
+ bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
+ (simd_q15_t*)(output+i),(simd_q15_t*)(output+24576+i),(simd_q15_t*)(output+49152+i),
+ (simd_q15_t*)(twa36864+i),(simd_q15_t*)(twb36864+i));
+ }
+
+ if (scale==1) {
+ for (i=0; i<576; i++) {
+ y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
+ y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
+ y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
+ y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
+ y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
+ y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
+ y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
+ y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
+ y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
+ y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
+ y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
+ y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
+ y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
+ y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
+ y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
+ y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
+ y128p+=16;
+ }
+ }
+ _mm_empty();
+ _m_empty();
+ if (LOG_DUMPFLAG(DEBUG_DFT)) {
+ LOG_M("out.m","out",output,36864,1,1);
+ }
}
+
void idft36864(int16_t *input, int16_t *output,uint8_t scale) {
- AssertFatal(1==0,"Need to do this ..\n");
+ int i,i2,j;
+ uint32_t tmp[3][12288] __attribute__((aligned(32)));
+ uint32_t tmpo[3][12288] __attribute__((aligned(32)));
+ simd_q15_t *y128p=(simd_q15_t*)output;
+ simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
+
+ for (i=0,j=0; i<12288; i++) {
+ tmp[0][i] = ((uint32_t *)input)[j++];
+ tmp[1][i] = ((uint32_t *)input)[j++];
+ tmp[2][i] = ((uint32_t *)input)[j++];
+ }
+
+ idft12288((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
+ idft12288((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
+ idft12288((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
+
+ for (i=0,i2=0; i<24576; i+=8,i2+=4) {
+ ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
+ (simd_q15_t*)(output+i),(simd_q15_t*)(output+24576+i),(simd_q15_t*)(output+49152+i),
+ (simd_q15_t*)(twa36864+i),(simd_q15_t*)(twb36864+i));
+ }
+ if (scale==1) {
+ for (i=0; i<576; i++) {
+ y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
+ y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
+ y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
+ y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
+ y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
+ y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
+ y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
+ y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
+ y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
+ y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
+ y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
+ y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
+ y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
+ y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
+ y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
+ y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
+ y128p+=16;
+ }
+ }
+ _mm_empty();
+ _m_empty();
}
int16_t twa49152[32768] __attribute__((aligned(32)));
int16_t twb49152[32768] __attribute__((aligned(32)));
+
// 16384 x 3
void dft49152(int16_t *input, int16_t *output,uint8_t scale) {
- AssertFatal(1==0,"Need to do this ..\n");
+ int i,i2,j;
+ uint32_t tmp[3][16384] __attribute__((aligned(32)));
+ uint32_t tmpo[3][16384] __attribute__((aligned(32)));
+ simd_q15_t *y128p=(simd_q15_t*)output;
+ simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
+
+ for (i=0,j=0; i<16384; i++) {
+ tmp[0][i] = ((uint32_t *)input)[j++];
+ tmp[1][i] = ((uint32_t *)input)[j++];
+ tmp[2][i] = ((uint32_t *)input)[j++];
+ }
+
+ dft16384((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
+ dft16384((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
+ dft16384((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
+
+ for (i=0,i2=0; i<32768; i+=8,i2+=4) {
+ bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
+ (simd_q15_t*)(output+i),(simd_q15_t*)(output+32768+i),(simd_q15_t*)(output+65536+i),
+ (simd_q15_t*)(twa49152+i),(simd_q15_t*)(twb49152+i));
+ }
+ if (scale==1) {
+ for (i=0; i<768; i++) {
+ y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
+ y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
+ y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
+ y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
+ y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
+ y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
+ y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
+ y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
+ y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
+ y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
+ y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
+ y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
+ y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
+ y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
+ y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
+ y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
+ y128p+=16;
+ }
+ }
+ _mm_empty();
+ _m_empty();
+
}
void idft49152(int16_t *input, int16_t *output,uint8_t scale) {
- AssertFatal(1==0,"Need to do this ..\n");
+ int i,i2,j;
+ uint32_t tmp[3][16384] __attribute__((aligned(32)));
+ uint32_t tmpo[3][16384] __attribute__((aligned(32)));
+ simd_q15_t *y128p=(simd_q15_t*)output;
+ simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
+
+ for (i=0,j=0; i<16384; i++) {
+ tmp[0][i] = ((uint32_t *)input)[j++];
+ tmp[1][i] = ((uint32_t *)input)[j++];
+ tmp[2][i] = ((uint32_t *)input)[j++];
+ }
+
+ idft16384((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
+ idft16384((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
+ idft16384((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
+
+ for (i=0,i2=0; i<32768; i+=8,i2+=4) {
+ ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
+ (simd_q15_t*)(output+i),(simd_q15_t*)(output+32768+i),(simd_q15_t*)(output+65536+i),
+ (simd_q15_t*)(twa49152+i),(simd_q15_t*)(twb49152+i));
+ }
+ if (scale==1) {
+ for (i=0; i<768; i++) {
+ y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
+ y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
+ y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
+ y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
+ y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
+ y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
+ y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
+ y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
+ y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
+ y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
+ y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
+ y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
+ y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
+ y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
+ y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
+ y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
+ y128p+=16;
+ }
+ }
+ _mm_empty();
+ _m_empty();
}
int16_t twa73728[49152] __attribute__((aligned(32)));
@@ -6099,17 +6886,104 @@ void idft73728(int16_t *input, int16_t *output,uint8_t scale) {
}
-int16_t twa98304[49152] __attribute__((aligned(32)));
-int16_t twb98304[49152] __attribute__((aligned(32)));
+int16_t twa98304[65536] __attribute__((aligned(32)));
+int16_t twb98304[65536] __attribute__((aligned(32)));
// 32768 x 3
void dft98304(int16_t *input, int16_t *output,uint8_t scale) {
- AssertFatal(1==0,"Need to do this ..\n");
+ int i,i2,j;
+ uint32_t tmp[3][32768] __attribute__((aligned(32)));
+ uint32_t tmpo[3][32768] __attribute__((aligned(32)));
+ simd_q15_t *y128p=(simd_q15_t*)output;
+ simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
+
+ for (i=0,j=0; i<32768; i++) {
+ tmp[0][i] = ((uint32_t *)input)[j++];
+ tmp[1][i] = ((uint32_t *)input)[j++];
+ tmp[2][i] = ((uint32_t *)input)[j++];
+ }
+
+ dft32768((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
+ dft32768((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
+ dft32768((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
+
+ for (i=0,i2=0; i<65536; i+=8,i2+=4) {
+ bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
+ (simd_q15_t*)(output+i),(simd_q15_t*)(output+65536+i),(simd_q15_t*)(output+131072+i),
+ (simd_q15_t*)(twa98304+i),(simd_q15_t*)(twb98304+i));
+ }
+ if (scale==1) {
+ for (i=0; i<1536; i++) {
+ y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
+ y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
+ y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
+ y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
+ y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
+ y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
+ y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
+ y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
+ y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
+ y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
+ y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
+ y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
+ y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
+ y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
+ y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
+ y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
+ y128p+=16;
+ }
+ }
+ _mm_empty();
+ _m_empty();
+
}
void idft98304(int16_t *input, int16_t *output,uint8_t scale) {
- AssertFatal(1==0,"Need to do this ..\n");
+ int i,i2,j;
+ uint32_t tmp[3][32768] __attribute__((aligned(32)));
+ uint32_t tmpo[3][32768] __attribute__((aligned(32)));
+ simd_q15_t *y128p=(simd_q15_t*)output;
+ simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
+
+ for (i=0,j=0; i<32768; i++) {
+ tmp[0][i] = ((uint32_t *)input)[j++];
+ tmp[1][i] = ((uint32_t *)input)[j++];
+ tmp[2][i] = ((uint32_t *)input)[j++];
+ }
+
+ idft32768((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
+ idft32768((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
+ idft32768((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
+
+ for (i=0,i2=0; i<65536; i+=8,i2+=4) {
+ ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
+ (simd_q15_t*)(output+i),(simd_q15_t*)(output+65536+i),(simd_q15_t*)(output+131072+i),
+ (simd_q15_t*)(twa98304+i),(simd_q15_t*)(twb98304+i));
+ }
+ if (scale==1) {
+ for (i=0; i<1536; i++) {
+ y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
+ y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
+ y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
+ y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
+ y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
+ y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
+ y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
+ y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
+ y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
+ y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
+ y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
+ y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
+ y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
+ y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
+ y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
+ y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
+ y128p+=16;
+ }
+ }
+ _mm_empty();
+ _m_empty();
}
@@ -8724,6 +9598,8 @@ int dfts_autoinit(void)
init_rad2(2048,tw2048);
init_rad4(4096,tw4096);
init_rad2(8192,tw8192);
+ init_rad4(16384,tw16384);
+ init_rad2(32768,tw32768);
init_rad3(1536,twa1536,twb1536);
init_rad3(3072,twa3072,twb3072);
@@ -8731,6 +9607,10 @@ int dfts_autoinit(void)
init_rad3(12288,twa12288,twb12288);
init_rad3(18432,twa18432,twb18432);
init_rad3(24576,twa24576,twb24576);
+ init_rad3(36864,twa36864,twb36864);
+ init_rad3(49152,twa49152,twb49152);
+ init_rad3(98304,twa98304,twb98304);
+
init_rad2_rep(24,tw24);
init_rad3_rep(36,twa36,twb36);
@@ -8770,6 +9650,7 @@ int dfts_autoinit(void)
+#ifndef MR_MAIN
void dft(uint8_t sizeidx, int16_t *sigF,int16_t *sig,unsigned char scale_flag){
AssertFatal((sizeidx>=0 && sizeidx<(int)DFT_SIZE_IDXTABLESIZE),"Invalid dft size index %i\n",sizeidx);
@@ -8780,6 +9661,7 @@ void idft(uint8_t sizeidx, int16_t *sigF,int16_t *sig,unsigned char scale_flag){
AssertFatal((sizeidx>=0 && sizeidx<(int)IDFT_SIZE_IDXTABLESIZE),"Invalid idft size index %i\n",sizeidx);
idft_ftab[sizeidx](sigF,sig,scale_flag);
};
+#endif
/*---------------------------------------------------------------------------------------*/
@@ -8950,9 +9832,9 @@ int main(int argc, char**argv)
time_stats_t ts;
#ifdef __AVX2__
- simd256_q15_t x[4096],x2[4096],y[4096],tw0,tw1,tw2,tw3;
+ simd256_q15_t x[16384],x2[16384],y[16384],tw0,tw1,tw2,tw3;
#else
- simd_q15_t x[8192],y[8192],tw0,tw1,tw2,tw3;
+ simd_q15_t x[32768],y[32768],tw0,tw1,tw2,tw3;
#endif
int i;
simd_q15_t *x128=(simd_q15_t*)x,*y128=(simd_q15_t*)y;
@@ -9514,10 +10396,34 @@ int main(int argc, char**argv)
stop_meas(&ts);
}
- printf("\n\n1536-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
+ printf("\n\n8192-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
LOG_M("y8192.m","y8192",y,8192,1,1);
LOG_M("x8192.m","x8192",x,8192,1,1);
+ memset((void*)x,0,16384*sizeof(int32_t));
+ for (i=2;i<9602;i++) {
+ if ((taus() & 1)==0)
+ ((int16_t*)x)[i] = 364;
+ else
+ ((int16_t*)x)[i] = -364;
+ }
+ for (i=2*(16384-4800);i<32768;i++) {
+ if ((taus() & 1)==0)
+ ((int16_t*)x)[i] = 364;
+ else
+ ((int16_t*)x)[i] = -364;
+ }
+ reset_meas(&ts);
+ for (i=0; i<10000; i++) {
+ start_meas(&ts);
+ dft16384((int16_t *)x,(int16_t *)y,1);
+ stop_meas(&ts);
+ }
+
+ printf("\n\n16384-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
+ LOG_M("y16384.m","y16384",y,16384,1,1);
+ LOG_M("x16384.m","x16384",x,16384,1,1);
+
memset((void*)x,0,1536*sizeof(int32_t));
for (i=2;i<1202;i++) {
if ((taus() & 1)==0)
@@ -9666,6 +10572,56 @@ int main(int argc, char**argv)
LOG_M("y24576.m","y24576",y,24576,1,1);
LOG_M("x24576.m","x24576",x,24576,1,1);
+
+ memset((void*)x,0,2*18432*sizeof(int32_t));
+ for (i=2;i<(2*14402);i++) {
+ if ((taus() & 1)==0)
+ ((int16_t*)x)[i] = 364;
+ else
+ ((int16_t*)x)[i] = -364;
+ }
+ for (i=2*(36864-14400);i<(36864*2);i++) {
+ if ((taus() & 1)==0)
+ ((int16_t*)x)[i] = 364;
+ else
+ ((int16_t*)x)[i] = -364;
+ }
+ reset_meas(&ts);
+ for (i=0; i<10000; i++) {
+ start_meas(&ts);
+ dft36864((int16_t *)x,(int16_t *)y,1);
+ stop_meas(&ts);
+ }
+
+ printf("\n\n36864-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
+ LOG_M("y36864.m","y36864",y,36864,1,1);
+ LOG_M("x36864.m","x36864",x,36864,1,1);
+
+
+ memset((void*)x,0,49152*sizeof(int32_t));
+ for (i=2;i<28402;i++) {
+ if ((taus() & 1)==0)
+ ((int16_t*)x)[i] = 364;
+ else
+ ((int16_t*)x)[i] = -364;
+ }
+ for (i=2*(49152-14400);i<98304;i++) {
+ if ((taus() & 1)==0)
+ ((int16_t*)x)[i] = 364;
+ else
+ ((int16_t*)x)[i] = -364;
+ }
+ reset_meas(&ts);
+ for (i=0; i<10000; i++) {
+ start_meas(&ts);
+ idft49152((int16_t *)x,(int16_t *)y,1);
+ stop_meas(&ts);
+ }
+
+ printf("\n\n49152-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
+ LOG_M("y49152.m","y49152",y,49152,1,1);
+ LOG_M("x49152.m","x49152",x,49152,1,1);
+ /*
int dftsizes[33]={24,36,48,60,72,96,108,120,144,180,192,216,240,288,300,324,360,384,432,480,540,576,600,648,720,768,864,900,960,972,1080,1152,1200};
void (*dft)(int16_t *x,int16_t *y,uint8_t scale)[33] = {dft24,dft36,dft48,dft60,dft72,dft96,dft108,dft120,dft144,dft180,dft192,dft216,dft240,dft288,dft300,dft324,dft360,dft384,dft432,dft480,dft540,dft576,dft600,dft648,dft720,dft768,dft864,dft900,dft960,dft972,dft1080,dft1152,dft1200};
for (int n=0;n<33;n++) {
@@ -9698,7 +10654,7 @@ int main(int argc, char**argv)
LOG_M(ystr,ystr2,y,dftsizes[n]*4,1,1);
LOG_M(xstr,xstr2,x,dftsizes[n]*4,1,1);
}
-
+ */
return(0);
}
diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h
index 61ea785db8..9c9b8aa821 100644
--- a/openair1/PHY/TOOLS/tools_defs.h
+++ b/openair1/PHY/TOOLS/tools_defs.h
@@ -183,10 +183,6 @@ This function performs optimized fixed-point radix-2 FFT/IFFT.
-
-
-
-
#ifdef OAIDFTS_MAIN
typedef void(*adftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);
typedef void(*aidftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);
diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h
index ce808eddf9..b8083b5ecf 100644
--- a/openair1/PHY/defs_RU.h
+++ b/openair1/PHY/defs_RU.h
@@ -38,8 +38,7 @@
#include "openairinterface5g_limits.h"
#include "PHY/TOOLS/time_meas.h"
#include "defs_common.h"
-#include
-
+#include "nfapi_nr_interface_scf.h"
#define MAX_BANDS_PER_RRU 4
#define MAX_RRU_CONFIG_SIZE 1024
@@ -186,6 +185,16 @@ typedef struct RU_feptx_t_s{
int index;
}RU_feptx_t;
+typedef struct {
+ int frame;
+ int slot;
+ int fmt;
+ int numRA;
+ int prachStartSymbol;
+} RU_PRACH_list_t;
+
+#define NUMBER_OF_NR_RU_PRACH_MAX 8
+
typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor
struct RU_t_s *ru;
@@ -477,6 +486,8 @@ typedef struct RU_t_s {
int att_tx;
/// flag to indicate precoding operation in RU
int do_precoding;
+ /// FAPI confiuration
+ nfapi_nr_config_request_scf_t config;
/// Frame parameters
struct LTE_DL_FRAME_PARMS *frame_parms;
struct NR_DL_FRAME_PARMS *nr_frame_parms;
@@ -579,6 +590,10 @@ typedef struct RU_t_s {
int32_t *bw_list[NUMBER_OF_eNB_MAX+1];
/// beamforming weight vectors
int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15];
+ /// prach commands
+ RU_PRACH_list_t prach_list[NUMBER_OF_NR_RU_PRACH_MAX];
+ /// mutex for prach_list access
+ pthread_mutex_t prach_list_mutex;
/// received frequency-domain signal for PRACH (IF4p5 RRU)
int16_t **prach_rxsigF;
/// received frequency-domain signal for PRACH BR (IF4p5 RRU)
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index aa794da818..e2cdebff3a 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -43,6 +43,8 @@
#include "PHY/CODING/nrLDPC_extern.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
+#include "nfapi_nr_interface_scf.h"
+
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
#define MAX_PUCCH0_NID 8
@@ -52,6 +54,7 @@ typedef struct {
int lut[MAX_PUCCH0_NID][160][14];
} NR_gNB_PUCCH0_LUT_t;
+
typedef struct {
uint32_t pbch_a;
uint32_t pbch_a_interleaved;
@@ -155,6 +158,14 @@ typedef struct {
int16_t sqrt_rho_b;
} NR_gNB_DLSCH_t;
+typedef struct {
+ int frame;
+ int slot;
+ nfapi_nr_prach_pdu_t pdu;
+} gNB_PRACH_list_t;
+
+#define NUMBER_OF_NR_PRACH_MAX 8
+
typedef struct {
/// \brief ?.
/// first index: ? [0..1023] (hard coded)
@@ -165,6 +176,7 @@ typedef struct {
int16_t **rxsigF;
/// \brief local buffer to compute prach_ifft
int32_t *prach_ifft;
+ gNB_PRACH_list_t list[NUMBER_OF_NR_PRACH_MAX];
} NR_gNB_PRACH;
typedef struct {
@@ -172,8 +184,8 @@ typedef struct {
nfapi_nr_pusch_pdu_t ulsch_pdu;
/// Frame where current HARQ round was sent
uint32_t frame;
- /// Subframe where current HARQ round was sent
- uint32_t subframe;
+ /// Slot where current HARQ round was sent
+ uint32_t slot;
/// Index of current HARQ round for this DLSCH
uint8_t round;
/// Last TPC command
@@ -328,6 +340,15 @@ typedef struct {
uint16_t cba_rnti[NUM_MAX_CBA_GROUP];
} NR_gNB_ULSCH_t;
+typedef struct {
+ uint8_t active;
+ /// Frame where current PUCCH pdu was sent
+ uint32_t frame;
+ /// Slot where current PUCCH pdu was sent
+ uint32_t slot;
+ /// ULSCH PDU
+ nfapi_nr_pucch_pdu_t pucch_pdu;
+} NR_gNB_PUCCH_t;
typedef struct {
/// \brief Pointers (dynamic) to the received data in the time domain.
@@ -607,9 +628,9 @@ typedef struct {
#define MAX_NUM_NR_RX_RACH_PDUS 4
#define MAX_NUM_NR_RX_PRACH_PREAMBLES 4
-#define MAX_UL_PDUS_PER_SLOT 100
-#define MAX_NUM_NR_SRS_PDUS 100
-#define MAX_NUM_NR_UCI_PDUS 100
+#define MAX_UL_PDUS_PER_SLOT 8
+#define MAX_NUM_NR_SRS_PDUS 8
+#define MAX_NUM_NR_UCI_PDUS 8
/// Top-level PHY Data Structure for gNB
typedef struct PHY_VARS_gNB_s {
@@ -663,10 +684,13 @@ typedef struct PHY_VARS_gNB_s {
NR_gNB_COMMON common_vars;
NR_gNB_PRACH prach_vars;
NR_gNB_PUSCH *pusch_vars[NUMBER_OF_NR_ULSCH_MAX];
+ NR_gNB_PUCCH_t *pucch[NUMBER_OF_NR_PUCCH_MAX];
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX][2]; // [Nusers times][2 codewords]
NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
NR_gNB_DLSCH_t *dlsch_PCH;
+ t_nrPolar_params *uci_polarParams;
+
uint8_t pbch_configured;
char gNB_generate_rar;
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index b2d6a75265..9bdf892ceb 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -782,6 +782,8 @@ typedef struct {
int16_t amp;
int16_t *prachF;
int16_t *prach;
+ fapi_nr_ul_config_prach_pdu prach_pdu;
+ uint8_t prach_Config_enabled;
} NR_UE_PRACH;
// structure used for multiple SSB detection
@@ -882,8 +884,6 @@ typedef struct {
fapi_nr_config_request_t nrUE_config;
- uint16_t frame_gap;
-
// the following structures are not part of PHY_vars_UE anymore as it is not thread safe. They are now on the stack of the functions that actually need them
//nr_downlink_indication_t dl_indication;
@@ -930,7 +930,7 @@ typedef struct {
uint8_t pucch_sel[10];
uint8_t pucch_payload[22];
- UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX];
+ UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_gNB_MAX];
/// cell-specific reference symbols
uint32_t lte_gold_table[7][20][2][14];
@@ -965,12 +965,13 @@ typedef struct {
char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX];
+ unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_gNB_MAX];
+ uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_gNB_MAX];
+ unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_gNB_MAX];
+ uint8_t Msg3_startSymbol[NUMBER_OF_CONNECTED_gNB_MAX];
+ uint8_t Msg3_Length[NUMBER_OF_CONNECTED_gNB_MAX];
-
- unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX];
- uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX];
- unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX];
- PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX];
+ NR_PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_gNB_MAX];
int turbo_iterations, turbo_cntl_iterations;
/// \brief ?.
/// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
@@ -1005,8 +1006,6 @@ typedef struct {
int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX];
unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX];
- uint8_t generate_prach;
- uint8_t generate_nr_prach;
uint8_t prach_cnt;
uint8_t prach_PreambleIndex;
// uint8_t prach_timer;
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index ccc79b7d47..584962c55c 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -198,30 +198,34 @@ typedef struct {
nr_reg_t reg_list[NR_NB_REG_PER_CCE];
} nr_cce_t;
-
-/// PRACH-ConfigInfo from 38.331 RRC spec
typedef struct {
- /// Parameter: prach-ConfigurationIndex, see TS 38.211 (6.3.3.2).
- uint8_t prach_ConfigIndex;
- /// Parameter: High-speed-flag, see TS 38.211 (6.3.3.1). 1 corresponds to Restricted set and 0 to Unrestricted set.
- uint8_t highSpeedFlag;
- /// Restricted Set Config (type A=0 , type B=1) TS 38.211 (6.3.3.1)
- uint8_t restrictedSetConfig;
- /// 38.211 (NCS 38.211 6.3.3.1).
- uint8_t zeroCorrelationZoneConfig;
- /// see TS 38.211 (6.3.3.2).
- uint8_t msg1_frequencystart;
-} NR_PRACH_CONFIG_INFO;
-
-/// PRACH-ConfigSIB or PRACH-Config
-typedef struct {
- /// Parameter: prach-rootSequenceIndex, see TS 38.211 (6.3.3.2).
- uint16_t rootSequenceIndex;
- /// prach_Config_enabled=1 means enabled.}
- uint8_t prach_Config_enabled;
- /// PRACH Configuration Information
- NR_PRACH_CONFIG_INFO prach_ConfigInfo;
-} NR_PRACH_CONFIG_COMMON;
+ /// PRACH format retrieved from prach_ConfigIndex
+ uint16_t prach_format;
+ /// Preamble index for PRACH (0-63)
+ uint8_t ra_PreambleIndex;
+ /// RACH MaskIndex
+ uint8_t ra_RACH_MaskIndex;
+ /// Target received power at gNB. Baseline is range -202..-60 dBm. Depends on delta preamble, power ramping counter and step.
+ int ra_PREAMBLE_RECEIVED_TARGET_POWER;
+ /// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex
+ uint8_t ra_TDD_map_index;
+ /// RA Preamble Power Ramping Step in dB
+ uint32_t RA_PREAMBLE_POWER_RAMPING_STEP;
+ ///
+ uint8_t RA_PREAMBLE_BACKOFF;
+ ///
+ uint8_t RA_SCALING_FACTOR_BI;
+ ///
+ uint8_t RA_PCMAX;
+ /// Corresponding RA-RNTI for UL-grant
+ uint16_t ra_RNTI;
+ /// Pointer to Msg3 payload for UL-grant
+ uint8_t *Msg3;
+ /// Frame of last completed synch
+ uint8_t sync_frame;
+ /// Flag to indicate that prach is ready to start: it is enabled with an initial delay after the sync
+ uint8_t init_msg1;
+} NR_PRACH_RESOURCES_t;
typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
@@ -313,8 +317,6 @@ struct NR_DL_FRAME_PARMS {
uint8_t nb_antennas_rx;
/// Number of common transmit antenna ports in eNodeB (1 or 2)
uint8_t nb_antenna_ports_gNB;
- /// PRACH_CONFIG
- NR_PRACH_CONFIG_COMMON prach_config_common;
/// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP)
lte_prefix_type_t Ncp;
/// shift of pilot position in one RB
@@ -350,9 +352,10 @@ struct NR_DL_FRAME_PARMS {
uint8_t ssb_index;
/// PBCH polar encoder params
t_nrPolar_params pbch_polar_params;
-
};
+
+
#define KHz (1000UL)
#define MHz (1000*KHz)
diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h
index 44f2e314ea..3e09f3f593 100644
--- a/openair1/PHY/impl_defs_nr.h
+++ b/openair1/PHY/impl_defs_nr.h
@@ -757,11 +757,11 @@ typedef struct {
#define MAX_NR_OF_SPATIAL_RELATION_INFOS (8)
typedef enum {
- pucch_format0_nr = 0,
- pucch_format1_nr = 1,
- pucch_format2_nr = 2,
- pucch_format3_nr = 3,
- pucch_format4_nr = 4,
+ pucch_format0_nr = 1,
+ pucch_format1_nr = 2,
+ pucch_format2_nr = 3,
+ pucch_format3_nr = 4,
+ pucch_format4_nr = 5
} pucch_format_nr_t;
typedef enum {
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index ba03e79e62..558fa8d4eb 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -1211,6 +1211,8 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
}
if (!decodeSucess) {
+ T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(rdata->frame), T_INT(rdata->subframe), T_INT(ulsch->rnti),
+ T_INT(rdata->harq_pid));
fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,1); // indicate NAK to MAC
fill_rx_indication(eNB,i,rdata->frame,rdata->subframe); // indicate SDU to MAC
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
@@ -1239,6 +1241,8 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
fill_rx_indication(eNB,i,rdata->frame,rdata->subframe); // indicate SDU to MAC
ulsch_harq->status = SCH_IDLE;
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
+ T (T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(rdata->frame), T_INT(rdata->subframe), T_INT(ulsch->rnti),
+ T_INT(rdata->harq_pid));
} // ulsch not in error
if (ulsch_harq->O_ACK>0)
@@ -1419,7 +1423,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation
pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->decodedBytes;
// estimate timing advance for MAC
- sync_pos = lte_est_timing_advance_pusch(eNB,UE_id);
+ sync_pos = lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[UE_id]->drs_ch_estimates_time);
timing_advance_update = sync_pos; // - eNB->frame_parms.nb_prefix_samples/4; //to check
// if (timing_advance_update > 10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);}
diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c
index 8846b77af9..cb03821388 100644
--- a/openair1/SCHED/ru_procedures.c
+++ b/openair1/SCHED/ru_procedures.c
@@ -693,12 +693,6 @@ void ru_fep_full_2thread(RU_t *ru,
3/(fp->symbols_per_tti/2),// Ns = slot number
fp);
- /*lte_ul_channel_estimation((PHY_VARS_eNB *)NULL,
- proc,
- ru->idx,
- 3%(fp->symbols_per_tti/2),
- 3/(fp->symbols_per_tti/2));
- */
lte_ul_channel_estimation_RRU(fp,
calibration->drs_ch_estimates,
calibration->drs_ch_estimates_time,
@@ -713,7 +707,7 @@ void ru_fep_full_2thread(RU_t *ru,
0,//interpolate,
0 /*eNB->ulsch[ru->idx]->rnti rnti or ru->ulsch[eNB_id]->rnti*/);
- check_sync_pos = lte_est_timing_advance_pusch((PHY_VARS_eNB *)NULL, ru->idx);
+ check_sync_pos = lte_est_timing_advance_pusch(ru->frame_parms, ru->calibration.drs_ch_estimates_time);
if (ru->state == RU_CHECK_SYNC) {
if ((check_sync_pos >= 0 && check_sync_pos<8) || (check_sync_pos < 0 && check_sync_pos>-8)) {
LOG_I(PHY,"~~~~~~~~~~~ check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check);
diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c
index 5c145a3230..2870f1d42e 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.c
+++ b/openair1/SCHED_NR/fapi_nr_l1.c
@@ -44,7 +44,7 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n",
dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag);
- LOG_I(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
+ LOG_D(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
}
@@ -113,8 +113,6 @@ void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
nr_fill_ul_dci(gNB,frame,slot);
-
-
}
void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
@@ -144,20 +142,25 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
gNB = RC.gNB[Mod_id];
- uint8_t number_dl_pdu = DL_req->dl_tti_request_body.nPDUs;
- // uint8_t number_ul_pdu = 0;
+ uint8_t number_dl_pdu = (DL_req==NULL) ? 0 : DL_req->dl_tti_request_body.nPDUs;
uint8_t number_ul_dci_pdu = (UL_dci_req==NULL) ? 0 : UL_dci_req->numPdus;
+ uint8_t number_ul_tti_pdu = (UL_tti_req==NULL) ? 0 : UL_tti_req->n_pdus;
- // if (UL_tti_req != NULL) number_ul_pdu = UL_tti_req->n_pdus;
-
- LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d%d DL_req:SFN/SLO:%04d%d:dl_pdu:%d tx_req:SFN/SLOT:%04d%d:pdus:%d;\n",
- frame,slot,
- DL_req->SFN,DL_req->Slot,number_dl_pdu,
- TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs);
+ if (DL_req != NULL && TX_req!=NULL)
+ LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d/%d DL_req:SFN/SLO:%04d/%d:dl_pdu:%d tx_req:SFN/SLOT:%04d/%d:pdus:%d;ul_dci %d ul_tti %d\n",
+ frame,slot,
+ DL_req->SFN,DL_req->Slot,number_dl_pdu,
+ TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs,
+ number_ul_dci_pdu,number_ul_tti_pdu);
int pdcch_received=0;
gNB->num_pdsch_rnti=0;
+ for (int i=0; idlsch[i][0]->rnti=0;
+ gNB->dlsch[i][0]->harq_mask=0;
+ }
gNB->pdcch_pdu = NULL;
+ gNB->ul_dci_pdu = NULL;
gNB->pbch_configured=0;
for (int i=0;iSFN,DL_req->Slot);
handle_nfapi_nr_pdcch_pdu(gNB,
frame, slot,
&dl_tti_pdu->pdcch_pdu);
@@ -184,6 +188,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
{
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15;
uint16_t pduIndex = pdsch_pdu_rel15->pduIndex;
AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n",
@@ -194,13 +199,28 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
}
}
- if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t));
+ // if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t));
for (int i=0;iul_dci_pdu_list[i]);
+ handle_nfapi_nr_ul_dci_pdu(gNB, frame, slot, &UL_dci_req->ul_dci_pdu_list[i]);
}
-
+ for (int i = 0; i < number_ul_tti_pdu; i++) {
+ switch (UL_tti_req->pdus_list[i].pdu_type) {
+ case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
+ nr_fill_ulsch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu);
+ break;
+ case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
+ nr_fill_pucch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu);
+ break;
+ case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
+ nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
+ nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
+ nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
+ break;
+ }
+ }
}
diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c
index 9054ddbae5..a5d459a7c6 100644
--- a/openair1/SCHED_NR/nr_prach_procedures.c
+++ b/openair1/SCHED_NR/nr_prach_procedures.c
@@ -32,7 +32,7 @@
#include "PHY/defs_gNB.h"
#include "PHY/phy_extern.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "nfapi_nr_interface_scf.h"
#include "fapi_nr_l1.h"
#include "nfapi_pnf.h"
@@ -77,15 +77,14 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,
}
}
-
- /* rx_nr_prach(gNB,
+ rx_nr_prach(gNB,
prach_pdu,
frame,
slot,
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0]
- );*/
+ );
LOG_D(PHY,"[RAPROC] Frame %d, slot %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
frame,slot,
diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c
index aefeec43e2..560f47059a 100644
--- a/openair1/SCHED_NR/nr_ru_procedures.c
+++ b/openair1/SCHED_NR/nr_ru_procedures.c
@@ -520,7 +520,7 @@ void nr_fep0(RU_t *ru, int first_half) {
ru->common.rxdataF[aa],
l,
proc->tti_rx,
- 0,
+ ru->N_TA_offset,
0);
}
}
@@ -642,6 +642,8 @@ void nr_fep_full(RU_t *ru, int slot) {
// if ((fp->frame_type == TDD) &&
// (subframe_select(fp,proc->tti_rx) != NR_UPLINK_SLOT)) return;
+ LOG_D(PHY,"In fep_full for slot = %d\n", proc->tti_rx);
+
start_meas(&ru->ofdm_demod_stats);
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
@@ -655,7 +657,7 @@ void nr_fep_full(RU_t *ru, int slot) {
ru->common.rxdataF[aa],
l,
proc->tti_rx,
- 0,
+ ru->N_TA_offset,
0);
}
}
diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c
index a36cebd6ae..0ccb13fc7c 100644
--- a/openair1/SCHED_NR/phy_frame_config_nr.c
+++ b/openair1/SCHED_NR/phy_frame_config_nr.c
@@ -369,6 +369,73 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti)
}
}
+/*******************************************************************
+*
+* NAME : nr_ue_slot_select
+*
+* DESCRIPTION : function for the UE equivalent to nr_slot_select
+*
+*********************************************************************/
+
+int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) {
+ /* for FFD all slot can be considered as an uplink */
+ int mu = cfg->ssb_config.scs_common, check_slot = 0;
+
+ if (cfg->cell_config.frame_duplex_type == FDD) {
+ return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT);
+ }
+
+ if (nr_frame%2 == 0) {
+ for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
+ check_slot++;
+ }
+ }
+
+ if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
+ return (NR_UPLINK_SLOT);
+ }
+
+ check_slot = 0;
+
+ for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
+ check_slot++;
+ }
+ }
+
+ if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
+ return (NR_DOWNLINK_SLOT);
+ } else {
+ return (NR_MIXED_SLOT);
+ }
+ } else {
+ for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<
/************** DEFINE ********************************************/
#define TDD_CONFIG_NB_FRAMES (2)
@@ -79,6 +80,7 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
@returns nr_slot_t : downlink or uplink */
nr_slot_t nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti);
+int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti);
/** \brief This function frees tdd configuration for nr
* @param frame_parms NR DL Frame parameters
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 60f9d4747a..992c908c5d 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -23,7 +23,6 @@
#include "PHY/defs_gNB.h"
#include "sched_nr.h"
#include "PHY/NR_REFSIG/dmrs_nr.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
@@ -50,6 +49,8 @@
#include "intertask_interface.h"
+//#define DEBUG_RXDATA
+
uint8_t SSB_Table[38]={0,2,4,6,8,10,12,14,254,254,16,18,20,22,24,26,28,30,254,254,32,34,36,38,40,42,44,46,254,254,48,50,52,54,56,58,60,62};
extern uint8_t nfapi_mode;
@@ -143,7 +144,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
if ((cfg->cell_config.frame_duplex_type.value == TDD) &&
(nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return;
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,1);
if (do_meas==1) start_meas(&gNB->phy_proc_tx);
@@ -152,12 +153,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
memset(&gNB->common_vars.txdataF[aa][txdataF_offset],0,fp->samples_per_slot_wCP*sizeof(int32_t));
}
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,1);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
if (nfapi_mode == 0 || nfapi_mode == 1) {
if ((!(frame%ssb_frame_periodicity))) // generate SSB only for given frames according to SSB periodicity
nr_common_signal_procedures(gNB,frame, slot);
}
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,0);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
if (gNB->pdcch_pdu || gNB->ul_dci_pdu) {
@@ -166,7 +167,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
gNB->ul_dci_pdu==NULL?0:gNB->ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15.numDlDci,
gNB->pdcch_pdu==NULL?0:gNB->pdcch_pdu->pdcch_pdu_rel15.numDlDci);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1);
nr_generate_dci_top(gNB->pdcch_pdu,
gNB->ul_dci_pdu,
@@ -174,12 +175,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
&gNB->common_vars.txdataF[0][txdataF_offset],
AMP, *fp);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,0);
}
- LOG_D(PHY, "PDSCH generation started (%d)\n", gNB->num_pdsch_rnti);
for (int i=0; inum_pdsch_rnti; i++) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
+ LOG_D(PHY, "PDSCH generation started (%d)\n", gNB->num_pdsch_rnti);
nr_generate_pdsch(gNB->dlsch[i][0],
gNB->nr_gold_pdsch_dmrs[slot],
gNB->common_vars.txdataF,
@@ -197,7 +198,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
}
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0);
}
@@ -209,8 +210,6 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,1);
-
- if (do_prach_rx(fp,frame,slot)) L1_nr_prach_procedures(gNB,frame,slot/fp->slots_per_subframe);
*/
void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
@@ -227,9 +226,12 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
number_symbols = pusch_pdu->nr_of_symbols;
for (l = start_symbol; l < start_symbol + number_symbols; l++)
- number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01;
+ number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01;
- nb_re_dmrs = ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1)?6:4);
+ if (pusch_pdu->dmrs_config_type==pusch_dmrs_type1)
+ nb_re_dmrs = 6*pusch_pdu->num_dmrs_cdm_grps_no_data;
+ else
+ nb_re_dmrs = 4*pusch_pdu->num_dmrs_cdm_grps_no_data;
G = nr_get_G(pusch_pdu->rb_size,
number_symbols,
@@ -238,11 +240,9 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
pusch_pdu->qam_mod_order,
pusch_pdu->nrOfLayers);
-
//----------------------------------------------------------
//------------------- ULSCH unscrambling -------------------
//----------------------------------------------------------
-
start_meas(&gNB->ulsch_unscrambling_stats);
nr_ulsch_unscrambling(gNB->pusch_vars[ULSCH_id]->llr,
G,
@@ -266,6 +266,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
G);
stop_meas(&gNB->ulsch_decoding_stats);
+
if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations){
LOG_I(PHY, "ULSCH %d in error\n",ULSCH_id);
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
@@ -365,6 +366,7 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) {
// nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0);
+
for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
nr_slot_fep_ul(&gNB->frame_parms,
gNB->common_vars.rxdata[aa],
@@ -380,68 +382,91 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
- nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req;
- int num_pdus = UL_tti_req->n_pdus;
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1);
+ LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
- nfapi_nr_uci_indication_t *uci_indication = &gNB->uci_indication;
- uci_indication->sfn = frame_rx;
- uci_indication->slot = slot_rx;
- uci_indication->num_ucis = 0;
+ for (int i=0;ipucch[i];
+ if (pucch) {
+ if ((pucch->active == 1) &&
+ (pucch->frame == frame_rx) &&
+ (pucch->slot == slot_rx) ) {
+ nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch[i].pucch_pdu;
+ uint16_t num_ucis;
- LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pdus %d\n",frame_rx,slot_rx,num_pdus);
+ switch (pucch_pdu->format_type) {
+ case 0:
- gNB->UL_INFO.rx_ind.number_of_pdus = 0;
- gNB->UL_INFO.crc_ind.number_crcs = 0;
+ num_ucis = gNB->UL_INFO.uci_ind.num_ucis;
+ gNB->UL_INFO.uci_ind.uci_list = &gNB->uci_pdu_list[0];
+ gNB->UL_INFO.uci_ind.sfn = frame_rx;
+ gNB->UL_INFO.uci_ind.slot = slot_rx;
+ gNB->uci_pdu_list[num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE;
+ gNB->uci_pdu_list[num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
+ nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_0_1;
- for (int i = 0; i < num_pdus; i++) {
- switch (UL_tti_req->pdus_list[i].pdu_type) {
- case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
- {
- LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx);
-
- nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;
- nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu);
-
- uint8_t ULSCH_id = find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST);
- uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id;
- uint8_t symbol_start = pusch_pdu->start_symbol_index;
- uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols;
-
- for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
- nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
- }
- //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
- //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
- nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
- }
- break;
- case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
- {
- LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE\n",frame_rx,slot_rx);
-
- nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[i].pucch_pdu;
- switch (pucch_pdu->format_type) {
- case 0:
- uci_indication->uci_list[uci_indication->num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE;
- uci_indication->uci_list[uci_indication->num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
- nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &uci_indication->uci_list[uci_indication->num_ucis].pucch_pdu_format_0_1;
-
- nr_decode_pucch0(gNB,
- slot_rx,
- uci_pdu_format0,
- pucch_pdu);
-
- uci_indication->num_ucis += 1;
+ nr_decode_pucch0(gNB,
+ slot_rx,
+ uci_pdu_format0,
+ pucch_pdu);
+
+ gNB->UL_INFO.uci_ind.num_ucis += 1;
+ pucch->active = 0;
break;
- case 1:
- break;
- case 2:
- break;
- default:
- AssertFatal(1==0,"Only PUCCH format 0,1 and 2 are currently supported\n");
- }
+ default:
+ AssertFatal(1==0,"Only PUCCH format 0 is currently supported\n");
+ }
}
}
}
+
+ for (int ULSCH_id=0;ULSCH_idulsch[ULSCH_id][0];
+ int harq_pid;
+ int no_sig;
+ NR_UL_gNB_HARQ_t *ulsch_harq;
+
+ if ((ulsch) &&
+ (ulsch->rnti > 0)) {
+ // for for an active HARQ process
+ for (harq_pid=0;harq_pidharq_processes[harq_pid];
+ AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid);
+ if ((ulsch_harq->status == NR_ACTIVE) &&
+ (ulsch_harq->frame == frame_rx) &&
+ (ulsch_harq->slot == slot_rx) &&
+ (ulsch_harq->handled == 0)){
+
+#ifdef DEBUG_RXDATA
+ NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
+ RU_t *ru = gNB->RU_list[0];
+ int slot_offset = frame_parms->get_samples_slot_timestamp(slot_rx,frame_parms,0);
+ slot_offset -= ru->N_TA_offset;
+ char name[128];
+ FILE *f;
+ sprintf(name, "rxdata.%d.%d.raw", frame_rx,slot_rx);
+ f = fopen(name, "w"); if (f == NULL) exit(1);
+ fwrite(&ru->common.rxdata[0][slot_offset],2,frame_parms->get_samples_per_slot(slot_rx,frame_parms)*2, f);
+ fclose(f);
+#endif
+
+ uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
+ uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1);
+ for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
+ nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
+ }
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,0);
+ //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
+ //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,1);
+ nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,0);
+ break;
+ }
+ }
+ }
+ }
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
}
diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h
index 5f54539b71..b393e9566e 100644
--- a/openair1/SCHED_NR/sched_nr.h
+++ b/openair1/SCHED_NR/sched_nr.h
@@ -39,6 +39,7 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
+void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_prach_pdu_t *prach_pdu);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index e34ce2b6de..c6aea2ec08 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -218,6 +218,15 @@ void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
*/
void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+/*! \brief UE PRACH procedures.
+ @param
+ @param
+ @param
+ */
+void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t mode);
+
+int is_nr_prach_subframe(NR_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint8_t subframe);
+
#if 0
/*! \brief Compute ACK/NACK information for PUSCH/PUCCH for UE transmission in subframe n. This function implements table 10.1-1 of 36.213, p. 69.
@param frame_parms Pointer to DL frame parameter descriptor
@@ -322,13 +331,14 @@ uint16_t nr_get_n1_pucch(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t SR);
#endif
+
/*! \brief This function retrieves the PHY UE mode. It is used as a helper function for the UE MAC.
@param Mod_id Local UE index on which to act
@param CC_id Component Carrier Index
- @param eNB_index ID of eNB
+ @param gNB_index ID of gNB
@returns UE mode
*/
-UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
/*! \brief This function implements the power control mechanism for PUCCH from 36.213.
@param phy_vars_ue PHY variables
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 7439c26eb7..f852ae4ae1 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -34,30 +34,30 @@
#include "fapi_nr_ue_interface.h"
#include "fapi_nr_ue_l1.h"
+#include "harq_nr.h"
//#include "PHY/phy_vars_nr_ue.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/impl_defs_nr.h"
+
extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
-int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
-{
-
+int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
if(scheduled_response != NULL){
- /// module id
- module_id_t module_id = scheduled_response->module_id;
- /// component carrier id
- uint8_t cc_id = scheduled_response->CC_id;
+
+ module_id_t module_id = scheduled_response->module_id;
+ uint8_t cc_id = scheduled_response->CC_id, thread_id;
uint32_t i;
- int slot = scheduled_response->slot;
+ int slot = scheduled_response->slot;
+
// Note: we have to handle the thread IDs for this. To be revisited completely.
- uint8_t thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot];
+ thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot];
+ NR_UE_DLSCH_t *dlsch0 = NULL;
NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0];
- NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0];
- //NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms;
- PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0];
+ NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms;
+ //PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0];
// PUCCH_ConfigCommon_nr_t *pucch_config_common = PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0];
// PUCCH_Config_t *pucch_config_dedicated = PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0];
@@ -67,118 +67,155 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
LOG_D(PHY,"Received %d DL pdus\n",dl_config->number_pdus);
pdcch_vars->nb_search_space = 0;
- for(i=0; inumber_pdus; ++i){
- if(dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI){
- fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
- memcpy((void*)&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config));
- pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1;
- LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space);
- }else{ //FAPI_NR_DL_CONFIG_TYPE_DLSCH
- // dlsch config pdu
- fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
- uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
- dlsch0->current_harq_pid = current_harq_pid;
- dlsch0->active = 1;
- dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
-
- //dlsch0->harq_processes[0]->mcs = &dlsch_config_pdu->mcs;
-
- NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
+ for (i = 0; i < dl_config->number_pdus; ++i){
- dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
- dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
- dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
- dlsch0_harq->start_rb = dlsch_config_pdu->start_rb;
- dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols;
- dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol;
- dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos;
- dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType;
- dlsch0_harq->mcs = dlsch_config_pdu->mcs;
- dlsch0_harq->DCINdi = dlsch_config_pdu->ndi;
- dlsch0_harq->rvidx = dlsch_config_pdu->rv;
- dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
- dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
- dlsch0_harq->harq_ack.slot_for_feedback_ack = dlsch_config_pdu->pdsch_to_harq_feedback_time_ind;
- dlsch0_harq->Nl=1;
- dlsch0_harq->mcs_table=0;
- dlsch0_harq->status = ACTIVE;
- LOG_D(MAC,">>>> \tdlsch0->g_pucch=%d\tdlsch0_harq.mcs=%d\n",dlsch0->g_pucch,dlsch0_harq->mcs);
+ if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI) {
- }
+ fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
+ memcpy((void*)&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config));
+ pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1;
+ LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space);
+
+ } else {
+
+ if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DLSCH){
+ dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
+ }
+ else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){
+ dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0];
+ }
+
+ fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
+ uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
+ NR_DL_UE_HARQ_t *dlsch0_harq;
+
+ dlsch0->current_harq_pid = current_harq_pid;
+ dlsch0->active = 1;
+ dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
+ //dlsch0->harq_processes[0]->mcs = &dlsch_config_pdu->mcs;
+ dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
+
+ if (dlsch0_harq){
+
+ dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
+ dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
+ dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
+ dlsch0_harq->start_rb = dlsch_config_pdu->start_rb;
+ dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols;
+ dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol;
+ dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos;
+ dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType;
+ dlsch0_harq->mcs = dlsch_config_pdu->mcs;
+ dlsch0_harq->rvidx = dlsch_config_pdu->rv;
+ dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
+ dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
+ dlsch0_harq->harq_ack.slot_for_feedback_ack = (slot+dlsch_config_pdu->pdsch_to_harq_feedback_time_ind)%frame_parms.slots_per_frame;
+ dlsch0_harq->Nl=1;
+ dlsch0_harq->mcs_table=0;
+ dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type);
+ dlsch0_harq->harq_ack.vDAI_DL = dlsch_config_pdu->dai;
+ LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs);
+ }
+ }
}
- }else{
+ } else {
pdcch_vars->nb_search_space = 0;
}
- if(scheduled_response->ul_config != NULL){
+ if (scheduled_response->ul_config != NULL){
+
fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config;
- for(i=0; inumber_pdus; ++i){
- if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH){
- // pusch config pdu
- nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu;
- uint8_t current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id;
- nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch0->harq_processes[current_harq_pid]->pusch_pdu;
- memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t));
+ for (i = 0; i < ul_config->number_pdus; ++i){
- ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
- }
- if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUCCH){
- // pucch config pdu
- fapi_nr_ul_config_pucch_pdu *pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu;
- uint8_t pucch_resource_id = 0; //FIXME!!!
- uint8_t format = 1; // FIXME!!!
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].hoppingId = pucch_config_pdu->hoppingId;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].p0_nominal = pucch_config_pdu->p0_nominal;
- /* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
- pucch_config_dedicated->formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
- pucch_config_dedicated->formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
- pucch_config_common->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
- pucch_config_common->hoppingId = pucch_config_pdu->hoppingId;
- pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/
- }
- if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PRACH){
- // prach config pdu
- fapi_nr_ul_config_prach_pdu *prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu;
- /*frame_parms.prach_config_common.rootSequenceIndex = prach_config_pdu->root_sequence_index;
- frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex = prach_config_pdu->prach_configuration_index;
- frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = prach_config_pdu->zero_correlation_zone_config;
- frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag = prach_config_pdu->restrictedset_config;
- frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = prach_config_pdu->prach_freq_offset;*/
- prach_resources->ra_PreambleIndex = prach_config_pdu->preamble_index;
- }
+ uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, pucch_resource_id, current_harq_pid, format, gNB_id = 0;
+ /* PRACH */
+ //NR_PRACH_RESOURCES_t *prach_resources;
+ fapi_nr_ul_config_prach_pdu *prach_config_pdu;
+ /* PUSCH */
+ nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu;
+ /* PUCCH */
+ fapi_nr_ul_config_pucch_pdu *pucch_config_pdu;
+ PUCCH_ConfigCommon_nr_t *pucch_config_common_nr;
+ PUCCH_Config_t *pucch_config_dedicated_nr;
+ PUCCH_format_t *format_params;
+
+ switch (pdu_type){
+
+ case (FAPI_NR_UL_CONFIG_TYPE_PUSCH):
+ // pusch config pdu
+ pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu;
+ current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id;
+ nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch0->harq_processes[current_harq_pid]->pusch_pdu;
+
+ memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t));
+
+ ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
+ ulsch0->harq_processes[current_harq_pid]->status = ACTIVE;
+ break;
+
+ case (FAPI_NR_UL_CONFIG_TYPE_PUCCH):
+ // pucch config pdu
+ pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu;
+ pucch_resource_id = 0; //FIXME!!!
+ format = 1; // FIXME!!!
+ pucch_config_common_nr = &PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0];
+ pucch_config_dedicated_nr = &PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0];
+ format_params = &pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->format_parameters;
+
+ format_params->initialCyclicShift = pucch_config_pdu->initialCyclicShift;
+ format_params->nrofSymbols = pucch_config_pdu->nrofSymbols;
+ format_params->startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
+ format_params->nrofPRBs = pucch_config_pdu->nrofPRBs;
+ format_params->timeDomainOCC = pucch_config_pdu->timeDomainOCC;
+ format_params->occ_length = pucch_config_pdu->occ_length;
+ format_params->occ_Index = pucch_config_pdu->occ_Index;
+
+ pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
+ pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
+ pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
+ pucch_config_dedicated_nr->formatConfig[format - 1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
+ pucch_config_dedicated_nr->formatConfig[format - 1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
+
+ pucch_config_common_nr->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
+ pucch_config_common_nr->hoppingId = pucch_config_pdu->hoppingId;
+ pucch_config_common_nr->p0_nominal = pucch_config_pdu->p0_nominal;
+
+ /* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
+ pucch_config_dedicated->formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
+ pucch_config_dedicated->formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
+ pucch_config_common->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
+ pucch_config_common->hoppingId = pucch_config_pdu->hoppingId;
+ pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/
+ break;
+
+ case (FAPI_NR_UL_CONFIG_TYPE_PRACH):
+ // prach config pdu
+ //prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[gNB_id];
+ prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu;
+ memcpy((void*)&(PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_pdu), (void*)prach_config_pdu, sizeof(fapi_nr_ul_config_prach_pdu));
+ PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_Config_enabled = 1;
+ break;
+
+ default:
+ break;
+ }
}
- }else{
-
+ } else {
}
- if(scheduled_response->tx_request != NULL){
-
- }else{
-
+ if (scheduled_response->tx_request != NULL){
+ } else {
}
}
@@ -186,13 +223,15 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
}
+
+
int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){
fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config;
-
+
if(phy_config != NULL)
memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t));
-
+
return 0;
}
diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr.h b/openair1/SCHED_NR_UE/phy_frame_config_nr.h
index 81b6d373df..a7e78397fe 100644
--- a/openair1/SCHED_NR_UE/phy_frame_config_nr.h
+++ b/openair1/SCHED_NR_UE/phy_frame_config_nr.h
@@ -78,6 +78,5 @@ void free_tdd_configuration_nr(NR_DL_FRAME_PARMS *frame_parms);
void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
-void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mod);
#endif /* PHY_FRAME_CONFIG_NR_H */
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index e5e48ee0ed..e902977721 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -44,6 +44,7 @@
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
//#include "PHY/extern.h"
#include "SCHED_NR_UE/defs.h"
+#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
#include "SCHED_NR/extern.h"
#include "SCHED_NR_UE/phy_sch_processing_time.h"
//#include
@@ -53,7 +54,7 @@
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif
-
+#include "executables/softmodem-common.h"
//#define DEBUG_PHY_PROC
#define NR_PDCCH_SCHED
@@ -66,6 +67,7 @@
#endif
#include "LAYER2/NR_MAC_UE/mac_defs.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "common/utils/LOG/log.h"
#ifdef EMOS
@@ -190,14 +192,13 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
exit(-1);
}
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
-//unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
-/*
- unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL)
- {
+#endif
- int gain_dB = power_dBm - power_max_dBm;
- int amp_x_100;
+unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
+
+int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL){
+
+ int gain_dB = power_dBm - power_max_dBm, amp_x_100 = -1;
switch (N_RB_UL) {
case 6:
@@ -219,37 +220,21 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
amp_x_100 = 408*AMP; // 408 = 100*sqrt(100/6)
break;
default:
- LOG_E(PHY,"Unknown PRB size %d\n",N_RB_UL);
- //mac_xface->macphy_exit("");
+ LOG_E(PHY, "Unknown PRB size %d\n", N_RB_UL);
+ return (amp_x_100);
break;
}
if (gain_dB < -30) {
- return(amp_x_100/3162);
- } else if (gain_dB>0)
- return(amp_x_100);
+ return (amp_x_100/3162);
+ } else if (gain_dB > 0)
+ return (amp_x_100);
else
- return(amp_x_100/gain_table[-gain_dB]); // 245 corresponds to the factor sqrt(25/6)
- }
-*/
+ return (amp_x_100/gain_table[-gain_dB]); // 245 corresponds to the factor sqrt(25/6)
-unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
-{
-
- int gain_dB = power_dBm - power_max_dBm;
- double gain_lin;
-
- gain_lin = pow(10,.1*gain_dB);
- if ((nb_rb >0) && (nb_rb <= N_RB_UL)) {
- return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)));
- }
- else {
- LOG_E(PHY,"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL);
- //mac_xface->macphy_exit("");
- }
- return(0);
+ return (amp_x_100);
}
-#endif
+#if 0
void nr_dump_dlsch_ra(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t nr_tti_rx)
{
@@ -289,107 +274,6 @@ void nr_dump_dlsch_ra(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1);
}
-void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
- // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later
- // for more flexibility
-
- uint8_t i,j,k,s;
- PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-
- //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2];
- for(int l=0; ldlsch[l][i][j]) {
- for(k=0; kdlsch[l][i][j]->harq_processes[k]; k++) {
- ue->dlsch[l][i][j]->harq_processes[k]->status = SCH_IDLE;
- for (s=0; s<10; s++) {
- // reset ACK/NACK bit to DTX for all nr_tti_rxs s = 0..9
- ue->dlsch[l][i][j]->harq_ack[s].ack = 2;
- ue->dlsch[l][i][j]->harq_ack[s].send_harq_status = 0;
- ue->dlsch[l][i][j]->harq_ack[s].vDAI_UL = 0xff;
- ue->dlsch[l][i][j]->harq_ack[s].vDAI_DL = 0xff;
- }
- }
- }
- }
-
- //UL HARQ
- if(ue->ulsch[i]) {
- for(k=0; kulsch[i]->harq_processes[k]; k++) {
- ue->ulsch[i]->harq_processes[k]->status = SCH_IDLE;
- //Set NDIs for all UL HARQs to 0
- // ue->ulsch[i]->harq_processes[k]->Ndi = 0;
-
- }
- }
-
- // flush Msg3 buffer
- ue->ulsch_Msg3_active[i] = 0;
-
- }
- }
-}
-
-void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
- // if contention resolution fails, go back to PRACH
- PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH;
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti = 0;
- LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0, discard temporary C-RNTI and State RRC_IDLE\n",Mod_id);
- //mac_xface->macphy_exit("");
-}
-
-void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
- int i;
-
- LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded. Set C-RNTI = Temporary C-RNTI\n",Mod_id);
-
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH;
-
- for (i=0; i<8; i++) {
- if (PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]) {
- PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=IDLE;
- PHY_vars_UE_g[Mod_id][CC_id]->dlsch[0][eNB_index][0]->harq_processes[i]->round=0;
- PHY_vars_UE_g[Mod_id][CC_id]->dlsch[1][eNB_index][0]->harq_processes[i]->round=0;
- PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->subframe_scheduling_flag=0;
- }
- }
-
-
-}
-
-UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
- return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
-
-}
-void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance) {
-
- ue->timing_advance = timing_advance*4;
-
-
-#ifdef DEBUG_PHY_PROC
- /* TODO: fix this log, what is 'HW timing advance'? */
- /*LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx_rx, ue->timing_advance);*/
- LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx, ue->timing_advance);
-#endif
-
-}
-
uint8_t nr_is_SR_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id)
{
@@ -1380,14 +1264,12 @@ void ulsch_common_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_
#endif
+UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){
+ return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[gNB_id]);
+}
-void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB){
-
- // 3GPP TS 38.213 p4.2
- // scale by the scs numerology
- int factor_mu = 1 << mu;
+uint16_t get_bw_scaling(uint16_t bwp_ul_NB_RB){
uint16_t bw_scaling;
-
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
switch (bwp_ul_NB_RB) {
case 32: bw_scaling = 4; break;
@@ -1398,13 +1280,37 @@ void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_com
case 273: bw_scaling = 32; break;
default: abort();
}
+ return bw_scaling;
+}
+
+void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB){
+
+ // 3GPP TS 38.213 p4.2
+ // scale by the scs numerology
+ int factor_mu = 1 << mu;
+ uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB);
PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (ta_command - 31) * bw_scaling / factor_mu;
- LOG_D(PHY, "[UE %d] Got timing advance command %u from MAC, new value is %u\n", Mod_id, ta_command, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
+ LOG_D(PHY, "[UE %d] Got timing advance command %u from MAC, new value is %d\n", Mod_id, ta_command, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
+}
+
+// WIP
+// - todo: handle TA application as per ch 4.2 TS 38.213
+void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint16_t ta_command) {
+
+ int factor_mu = 1 << ue->frame_parms.numerology_index;
+ uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL;
+ uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB);
+
+ // Transmission timing adjustment (TS 38.213 p4.2)
+ ue->timing_advance = bw_scaling / factor_mu;
+
+ LOG_D(PHY, "[UE %d] Frame %d Slot %d, Received (RAR) timing advance command %d new value is %u \n", ue->Mod_id, proc->frame_rx, proc->nr_tti_rx, ta_command, ue->timing_advance);
}
#if 0
+
void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t eNB_id,
@@ -2312,28 +2218,26 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t gNB_id,
- uint8_t thread_id)
-{
+ uint8_t thread_id){
//int32_t ulsch_start=0;
int slot_tx = proc->nr_tti_tx;
int frame_tx = proc->frame_tx;
+ uint8_t harq_pid = 0;
+ runmode_t mode = normal_txrx;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
+ memset(ue->common_vars.txdataF[0], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size);
+
LOG_I(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
#if UE_TIMING_TRACE
start_meas(&ue->phy_proc_tx);
#endif
- uint8_t harq_pid = 0; //temporary implementation
-
- nr_ue_ulsch_procedures(ue,
- harq_pid,
- frame_tx,
- slot_tx,
- thread_id,
- gNB_id);
+ if (ue->UE_mode[gNB_id] == PUSCH || get_softmodem_params()->phy_test == 1){
+ if (ue->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->status == ACTIVE)
+ nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, thread_id, gNB_id);
/*
@@ -2345,33 +2249,30 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
} // UE_mode==PUSCH
*/
- LOG_D(PHY, "Sending data \n");
- nr_ue_pusch_common_procedures(ue,
- harq_pid,
- slot_tx,
- thread_id,
- gNB_id,
- &ue->frame_parms);
+ if (get_softmodem_params()->usim_test==0) {
+ LOG_D(PHY, "Sending PUCCH\n");
+ pucch_procedures_ue_nr(ue,
+ gNB_id,
+ proc,
+ TRUE);
+ }
+ LOG_D(PHY, "Sending data \n");
+ nr_ue_pusch_common_procedures(ue,
+ harq_pid,
+ slot_tx,
+ thread_id,
+ gNB_id,
+ &ue->frame_parms);
+ }
//LOG_M("txdata.m","txs",ue->common_vars.txdata[0],1228800,1,1);
-
-/*
- if ((ue->UE_mode[eNB_id] == PRACH) &&
- (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
-
- // check if we have PRACH opportunity
-
- if (is_prach_subframe(&ue->frame_parms,frame_tx,nr_tti_tx)) {
-
- ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+ /* RACH */
+ if (get_softmodem_params()->do_ra==1) {
+ if ((ue->UE_mode[gNB_id] == PRACH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) {
+ nr_ue_prach_procedures(ue, proc, gNB_id, mode);
}
- } // mode is PRACH
- else {
- ue->generate_prach=0;
}
-*/
-
LOG_I(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
@@ -2381,137 +2282,6 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
}
-
-void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) {
-
- int frame_tx = proc->frame_tx;
- int nr_tti_tx = proc->nr_tti_tx;
- int prach_power;
- uint16_t preamble_tx=50;
- PRACH_RESOURCES_t prach_resources;
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
-
- ue->generate_nr_prach=0;
- if (ue->mac_enabled==0){
- ue->prach_resources[eNB_id] = &prach_resources;
- ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
- ue->prach_resources[eNB_id]->ra_TDD_map_index = 0;
- }
-
- if (ue->mac_enabled==1){
-
- // ask L2 for RACH transport
- if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
- LOG_D(PHY,"Getting PRACH resources\n");
- //ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,ue->CC_id,frame_tx,eNB_id,nr_tti_tx);
- // LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon);
- // LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
- }
-}
-
-if (ue->prach_resources[eNB_id]!=NULL) {
-
- ue->generate_nr_prach=1;
- ue->prach_cnt=0;
-#ifdef SMBV
-ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
-#endif
-
-#ifdef OAI_EMU
- ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex;
-#endif
-
- if (abstraction_flag == 0) {
-
- LOG_I(PHY,"mode %d\n",mode);
-
- if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
-
- ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id);
- }
- else {
- ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm;
- ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
- }
-
- LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
- ue->Mod_id,
- frame_tx,
- nr_tti_tx,
- ue->prach_resources[eNB_id]->ra_PreambleIndex,
- get_nr_PL(ue,eNB_id),
- ue->tx_power_dBm[nr_tti_tx],
- ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
- ue->prach_resources[eNB_id]->ra_TDD_map_index,
- ue->prach_resources[eNB_id]->ra_RNTI);
-
- ue->tx_total_RE[nr_tti_tx] = 96;
-
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
- ue->prach_vars[eNB_id]->amp = nr_get_tx_amp(ue->tx_power_dBm[nr_tti_tx],
- ue->tx_power_max_dBm,
- ue->frame_parms.N_RB_UL,
- 6);
-#else
- ue->prach_vars[eNB_id]->amp = AMP;
-#endif
- if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
- LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n",
- ue->Mod_id,
- proc->frame_rx,
- proc->nr_tti_tx,
- ue->tx_power_dBm[nr_tti_tx],
- ue->prach_vars[eNB_id]->amp);
-
-
- // start_meas(&ue->tx_prach);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
-
-// prach_power = generate_nr_prach(ue,eNB_id,nr_tti_tx,frame_tx);
-prach_power = generate_nr_prach(ue,0,9,0); //subframe number hardcoded according to the simulator
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
- // stop_meas(&ue->tx_prach);
- LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
- ue->Mod_id,
- get_nr_PL(ue,eNB_id),
- ue->tx_power_dBm[nr_tti_tx],
- dB_fixed(prach_power),
- ue->prach_vars[eNB_id]->amp);
- }/* else {
- UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
- UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
- }*/ // commented for compiling as abstraction flag is 0
-
- if (ue->mac_enabled==1){
- //mac_xface->Msg1_transmitted(ue->Mod_id,ue->CC_id,frame_tx,eNB_id);
- }
-
-LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
- ue->Mod_id,frame_tx,nr_tti_tx,eNB_id,
- ue->prach_resources[eNB_id]->ra_PreambleIndex,
- ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id),
- get_nr_PL(ue,eNB_id));
-
-}
-
-
-// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
-if (mode == calib_prach_tx)
- ue->prach_resources[eNB_id]=NULL;
-
-LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n",
- ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_nr_prach,ue->prach_cnt);
-
-ue->prach_cnt++;
-
-if (ue->prach_cnt==3)
- ue->generate_nr_prach=0;
-
-VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
-}
-
/*
void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type)
{
@@ -2678,7 +2448,7 @@ void restart_phy(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc, uint8_t eNB_id,uint
}
#endif //(0)
-void nr_ue_pbch_procedures(uint8_t eNB_id,
+void nr_ue_pbch_procedures(uint8_t gNB_id,
PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t abstraction_flag)
@@ -2697,20 +2467,26 @@ void nr_ue_pbch_procedures(uint8_t eNB_id,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
- //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id);
+ //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,gNB_id);
ret = nr_rx_pbch(ue, proc,
- ue->pbch_vars[eNB_id],
+ ue->pbch_vars[gNB_id],
&ue->frame_parms,
- eNB_id,
+ gNB_id,
(ue->frame_parms.ssb_index)&7,
SISO,
ue->high_speed_flag);
if (ret==0) {
- ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0;
+ ue->pbch_vars[gNB_id]->pdu_errors_conseq = 0;
+ // Switch to PRACH state if it is first PBCH after initial synch and no timing correction is performed
+ if (ue->UE_mode[gNB_id] == NOT_SYNCHED && ue->no_timing_correction == 1){
+ ue->UE_mode[gNB_id] = PRACH;
+ ue->prach_resources[gNB_id]->sync_frame = frame_rx;
+ ue->prach_resources[gNB_id]->init_msg1 = 0;
+ }
#ifdef DEBUG_PHY_PROC
uint16_t frame_tx;
@@ -2740,25 +2516,25 @@ void nr_ue_pbch_procedures(uint8_t eNB_id,
exit(-1);
*/
- ue->pbch_vars[eNB_id]->pdu_errors_conseq++;
- ue->pbch_vars[eNB_id]->pdu_errors++;
+ ue->pbch_vars[gNB_id]->pdu_errors_conseq++;
+ ue->pbch_vars[gNB_id]->pdu_errors++;
- if (ue->pbch_vars[eNB_id]->pdu_errors_conseq>=100) {
+ if (ue->pbch_vars[gNB_id]->pdu_errors_conseq>=100) {
LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
exit_fun("More that 100 consecutive PBCH errors! Exiting!\n");
}
}
if (frame_rx % 100 == 0) {
- ue->pbch_vars[eNB_id]->pdu_fer = ue->pbch_vars[eNB_id]->pdu_errors - ue->pbch_vars[eNB_id]->pdu_errors_last;
- ue->pbch_vars[eNB_id]->pdu_errors_last = ue->pbch_vars[eNB_id]->pdu_errors;
+ ue->pbch_vars[gNB_id]->pdu_fer = ue->pbch_vars[gNB_id]->pdu_errors - ue->pbch_vars[gNB_id]->pdu_errors_last;
+ ue->pbch_vars[gNB_id]->pdu_errors_last = ue->pbch_vars[gNB_id]->pdu_errors;
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
ue->Mod_id,frame_rx, nr_tti_rx,
- ue->pbch_vars[eNB_id]->pdu_errors,
- ue->pbch_vars[eNB_id]->pdu_errors_conseq);
+ ue->pbch_vars[gNB_id]->pdu_errors,
+ ue->pbch_vars[gNB_id]->pdu_errors_conseq);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
}
@@ -2989,10 +2765,8 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
pdcch_vars->nb_search_space);
#endif
- fapi_nr_dci_indication_t dci_ind;
- nr_downlink_indication_t dl_indication;
- memset((void*)&dci_ind,0,sizeof(dci_ind));
- memset((void*)&dl_indication,0,sizeof(dl_indication));
+ fapi_nr_dci_indication_t dci_ind={0};
+ nr_downlink_indication_t dl_indication={0};
dci_cnt = nr_dci_decoding_procedure(ue,
proc->frame_rx,
nr_tti_rx,
@@ -3006,11 +2780,12 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
//LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_tti_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_tti_rx);
for (int i=0; i rnti %x : format %d\n",
- ue->Mod_id,frame_rx%1024,nr_tti_rx,nr_mode_string[ue->UE_mode[gNB_id]],
- i,
- dci_ind.dci_list[i].rnti,
- dci_ind.dci_list[i].dci_format);
+ LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI %i of %d total DCIs found --> rnti %x : format %d\n",
+ ue->Mod_id,frame_rx%1024,nr_tti_rx,nr_mode_string[ue->UE_mode[gNB_id]],
+ i + 1,
+ dci_cnt,
+ dci_ind.dci_list[i].rnti,
+ dci_ind.dci_list[i].dci_format);
}
ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->dci_received += dci_cnt;
@@ -3259,7 +3034,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
int first_symbol_flag=0;
if (!dlsch0)
- return;
+ return;
if (dlsch0->active == 0)
return;
@@ -3268,9 +3043,9 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
uint16_t BWPStart = dlsch0->harq_processes[harq_pid]->BWPStart;
// uint16_t BWPSize = dlsch0->harq_processes[harq_pid]->BWPSize;
uint16_t pdsch_start_rb = dlsch0->harq_processes[harq_pid]->start_rb;
- uint16_t pdsch_nb_rb = dlsch0->harq_processes[harq_pid]->nb_rb;
- uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol;
- uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols;
+ uint16_t pdsch_nb_rb = dlsch0->harq_processes[harq_pid]->nb_rb;
+ uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol;
+ uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols;
LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
@@ -3305,17 +3080,35 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]);
#endif
// process DLSCH received in first slot
- nr_rx_pdsch(ue,
- pdsch,
- eNB_id,
- eNB_id_i,
- proc->frame_rx,
- nr_tti_rx, // nr_tti_rx,
- m,
- first_symbol_flag,
- dual_stream_UE,
- i_mod,
- dlsch0->current_harq_pid);
+ // skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed
+ if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) == 0)
+ nr_rx_pdsch(ue,
+ pdsch,
+ eNB_id,
+ eNB_id_i,
+ proc->frame_rx,
+ nr_tti_rx, // nr_tti_rx,
+ m,
+ first_symbol_flag,
+ dual_stream_UE,
+ i_mod,
+ dlsch0->current_harq_pid);
+ else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS)
+ if (pdsch == RA_PDSCH) ue->pdsch_vars_ra[eNB_id]->llr_offset[m]=ue->pdsch_vars_ra[eNB_id]->llr_offset[m-1];
+ else if (pdsch == PDSCH) nr_rx_pdsch(ue,
+ pdsch,
+ eNB_id,
+ eNB_id_i,
+ proc->frame_rx,
+ nr_tti_rx, // nr_tti_rx,
+ m,
+ first_symbol_flag,
+ dual_stream_UE,
+ i_mod,
+ dlsch0->current_harq_pid);
+ else AssertFatal(1==0,"not RA_PDSCH or PDSCH\n");
+ }
+ if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]);
#if DISABLE_LOG_X
@@ -3332,103 +3125,153 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
} // CRNTI active
}
}
-#if 0
-void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
- int frame_rx = proc->frame_rx;
- int nr_tti_rx = proc->nr_tti_rx;
- int timing_advance;
- NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[eNB_id];
- int harq_pid = 0;
- uint8_t *rar;
- /*
- uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
- uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
- */
+// WIP fix:
+// - time domain indication hardcoded to 0 for k2 offset
+// - extend TS 38.213 ch 8.3 Msg3 PUSCH
+// - b buffer
+// - ulsch power offset
+// - UE_mode == PUSCH case (should be handled by TA updates)
+// - harq
+// - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures
+void nr_process_rar(nr_downlink_indication_t *dl_info) {
- LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Received RAR mode %d\n",
- ue->Mod_id,
- frame_rx,
- nr_tti_rx, ue->UE_mode[eNB_id]);
+ module_id_t module_id = dl_info->module_id;
+ int cc_id = dl_info->cc_id, frame_rx = dl_info->proc->frame_rx, nr_tti_rx = dl_info->proc->nr_tti_rx, ta_command, k2, delta;
+ uint8_t gNB_index = dl_info->gNB_index; // *rar;
+ //fapi_nr_dci_indication_t *dci_ind = dl_info->dci_ind;
+ PHY_VARS_NR_UE *ue = PHY_vars_UE_g[module_id][cc_id];
+ NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[gNB_index];
+ UE_MODE_t UE_mode = ue->UE_mode[gNB_index];
+ NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_index];
+ uint16_t slots_per_frame = ue->frame_parms.slots_per_frame;
+ uint8_t mu_pusch = 1, sliv_S, sliv_L;
+ // definition table j Table 6.1.2.1.1-4
+ uint8_t j = (mu_pusch==3)?3:(mu_pusch==2)?2:1;
+ uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PUSCH from TS 38.214 subclause 6.1.2.1.1
+ {j, 0,14}, // row index 1
+ {j, 0,12}, // row index 2
+ {j, 0,10}, // row index 3
+ {j, 2,10}, // row index 4
+ {j, 4,10}, // row index 5
+ {j, 4,8}, // row index 6
+ {j, 4,6}, // row index 7
+ {j+1,0,14}, // row index 8
+ {j+1,0,12}, // row index 9
+ {j+1,0,10}, // row index 10
+ {j+2,0,14}, // row index 11
+ {j+2,0,12}, // row index 12
+ {j+2,0,10}, // row index 13
+ {j, 8,6}, // row index 14
+ {j+3,0,14}, // row index 15
+ {j+3,0,10} // row index 16
+ };
+
+ LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Received RAR mode %d\n", module_id, frame_rx, nr_tti_rx, UE_mode);
if (ue->mac_enabled == 1) {
- if ((ue->UE_mode[eNB_id] != PUSCH) &&
- (ue->prach_resources[eNB_id]->Msg3!=NULL)) {
- LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Invoking MAC for RAR (current preamble %d)\n",
- ue->Mod_id,frame_rx,
- nr_tti_rx,
- ue->prach_resources[eNB_id]->ra_PreambleIndex);
-
- /* timing_advance = mac_xface->ue_process_rar(ue->Mod_id,
- ue->CC_id,
- frame_rx,
- ue->prach_resources[eNB_id]->ra_RNTI,
- dlsch0->harq_processes[0]->b,
- &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
- ue->prach_resources[eNB_id]->ra_PreambleIndex,
- dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
- */
- /*
- ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
- ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
- */
+ if ((UE_mode != PUSCH) && (prach_resources->Msg3 != NULL)) {
- if (timing_advance!=0xffff) {
+ LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n", module_id, frame_rx, nr_tti_rx, prach_resources->ra_PreambleIndex);
- LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Got rnti %x and timing advance %d from RAR\n",
- ue->Mod_id,
- frame_rx,
- nr_tti_rx,
- ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
- timing_advance);
+ ta_command = nr_ue_process_rar(ue->Mod_id,
+ cc_id,
+ frame_rx,
+ dlsch0->harq_processes[0]->b,
+ &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti,
+ prach_resources->ra_PreambleIndex,
+ dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
- // remember this c-rnti is still a tc-rnti
+ if (ta_command != 0xffff) {
+ LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got Temporary C-RNTI %x and timing advance %d from RAR\n",
+ ue->Mod_id,
+ frame_rx,
+ nr_tti_rx,
+ ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti,
+ ta_command);
- ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti_is_temporary = 1;
-
- //timing_advance = 0;
- nr_process_timing_advance_rar(ue,proc,timing_advance);
-
- if (mode!=debug_prach) {
- ue->ulsch_Msg3_active[eNB_id]=1;
- nr_get_Msg3_alloc(&ue->frame_parms,
- nr_tti_rx,
- frame_rx,
- &ue->ulsch_Msg3_frame[eNB_id],
- &ue->ulsch_Msg3_subframe[eNB_id]);
-
- LOG_D(PHY,"[UE %d][RAPROC] Got Msg3_alloc Frame %d nr_tti_rx %d: Msg3_frame %d, Msg3_subframe %d\n",
- ue->Mod_id,
- frame_rx,
- nr_tti_rx,
- ue->ulsch_Msg3_frame[eNB_id],
- ue->ulsch_Msg3_subframe[eNB_id]);
- harq_pid = nr_subframe2harq_pid(&ue->frame_parms,
- ue->ulsch_Msg3_frame[eNB_id],
- ue->ulsch_Msg3_subframe[eNB_id]);
- ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
-
- ue->UE_mode[eNB_id] = RA_RESPONSE;
- // ue->Msg3_timer[eNB_id] = 10;
- ue->ulsch[eNB_id]->power_offset = 6;
- ue->ulsch_no_allocation_counter[eNB_id] = 0;
- }
- } else { // PRACH preamble doesn't match RAR
- LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n",
- ue->Mod_id,
- ue->prach_resources[eNB_id]->ra_PreambleIndex);
+ nr_process_timing_advance_rar(ue, dl_info->proc, ta_command);
+
+ if (ue->mode != debug_prach) {
+ ue->ulsch_Msg3_active[gNB_index] = 1;
+ // TS 38.213 ch 8.3 Msg3 PUSCH
+ // PUSCH time domain resource allocation A for normal CP
+ // TS 38.214 ch 6.1.2.1.1
+ k2 = table_6_1_2_1_1_2_time_dom_res_alloc_A[0][0];
+ sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[0][1];
+ sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[0][2];
+
+ switch (mu_pusch) {
+ case 0:
+ delta = 2;
+ break;
+ case 1:
+ delta = 3;
+ break;
+ case 2:
+ delta = 4;
+ break;
+ case 3:
+ delta = 6;
+ break;
+ }
+
+ ue->Msg3_startSymbol[gNB_index] = sliv_S;
+ ue->Msg3_Length[gNB_index] = sliv_L;
+ ue->ulsch_Msg3_subframe[gNB_index] = (nr_tti_rx + k2 + delta) % slots_per_frame;
+ if (nr_tti_rx + k2 + delta > slots_per_frame){
+ ue->ulsch_Msg3_frame[gNB_index] = (frame_rx + 1) % 1024;
+ } else {
+ ue->ulsch_Msg3_frame[gNB_index] = frame_rx;
+ }
+
+ LOG_D(PHY,"[UE %d][RAPROC] Got Msg3_alloc Frame %d subframe %d: Msg3_frame %d, Msg3_subframe %d\n",
+ ue->Mod_id,
+ frame_rx,
+ nr_tti_rx,
+ ue->ulsch_Msg3_frame[gNB_index],
+ ue->ulsch_Msg3_subframe[gNB_index]);
+ // harq_pid = subframe2harq_pid(&ue->frame_parms,
+ // ue->ulsch_Msg3_frame[gNB_index],
+ // ue->ulsch_Msg3_subframe[gNB_index]);
+ // ue->ulsch[gNB_index]->harq_processes[harq_pid]->round = 0;
+ // ue->Msg3_timer[gNB_index] = 10;
+ // ue->ulsch[gNB_index].power_offset = 6;
+ // ue->ulsch_no_allocation_counter[gNB_index] = 0;
+ ue->UE_mode[gNB_index] = RA_RESPONSE;
+ }
+ } else {
+ LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n", ue->Mod_id, prach_resources->ra_PreambleIndex);
}
- } // mode != PUSCH
+ }
+ } else {
+ // rar = dlsch0->harq_processes[0]->b+1;
+ // ta_command = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
+ // nr_process_timing_advance_rar(ue, dl_info->proc, ta_command);
}
- else {
- rar = dlsch0->harq_processes[0]->b+1;
- timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
- nr_process_timing_advance_rar(ue,proc,timing_advance);
- }
-
}
-#endif
+
+// if contention resolution fails, go back to UE mode PRACH
+void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index) {
+
+ PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
+ ue->UE_mode[gNB_index] = PRACH;
+
+ for (int i=0; i pdcch_vars[i][gNB_index]->pdcch_config[0].rnti = 0;
+ }
+ LOG_E(PHY,"[UE %d] [RAPROC] Random-access procedure fails, going back to PRACH\n", Mod_id);
+}
+
+void nr_ra_succeeded(uint8_t Mod_id,
+ uint8_t CC_id,
+ uint8_t gNB_index){
+ LOG_I(PHY,"[UE %d][RAPROC] RA procedure succeeded. UE set to PUSCH mode\n", Mod_id);
+ PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
+ ue->ulsch_Msg3_active[gNB_index] = 0;
+ ue->UE_mode[gNB_index] = PUSCH;
+}
void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
@@ -3439,16 +3282,15 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
int *dlsch_errors,
runmode_t mode) {
- int harq_pid;
+ int harq_pid = dlsch0->current_harq_pid;
int frame_rx = proc->frame_rx;
int nr_tti_rx = proc->nr_tti_rx;
int ret=0, ret1=0;
NR_UE_PDSCH *pdsch_vars;
uint8_t is_cw0_active = 0;
uint8_t is_cw1_active = 0;
- //nfapi_nr_config_request_t *cfg = &ue->nrUE_config;
- //uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;
- uint8_t nb_re_dmrs = 6; //(dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4;
+ uint8_t dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
+ uint8_t nb_re_dmrs = (dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; // TODO: should changed my mac
uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value;
uint16_t nb_symb_sch = 9;
nr_downlink_indication_t dl_indication;
@@ -3471,14 +3313,10 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
if (dlsch0==NULL)
AssertFatal(0,"dlsch0 should be defined at this level \n");
-
- harq_pid = dlsch0->current_harq_pid;
is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
-
-
if(dlsch1)
is_cw1_active = dlsch1->harq_processes[harq_pid]->status;
@@ -3523,32 +3361,32 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
if (frame_rx < *dlsch_errors)
*dlsch_errors=0;
- if (pdsch==RA_PDSCH) {
+ if (pdsch == RA_PDSCH) {
if (ue->prach_resources[eNB_id]!=NULL)
- dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+ dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
else {
- LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,nr_tti_rx);
- //mac_xface->macphy_exit("prach_resources is NULL");
- return;
+ LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_tti_rx);
+ //mac_xface->macphy_exit("prach_resources is NULL");
+ return;
}
}
- // start ldpc decode for CW 0
- dlsch0->harq_processes[harq_pid]->G = nr_get_G(dlsch0->harq_processes[harq_pid]->nb_rb,
- nb_symb_sch,
- nb_re_dmrs,
- length_dmrs,
- dlsch0->harq_processes[harq_pid]->Qm,
- dlsch0->harq_processes[harq_pid]->Nl);
+ // start ldpc decode for CW 0
+ dlsch0->harq_processes[harq_pid]->G = nr_get_G(dlsch0->harq_processes[harq_pid]->nb_rb,
+ nb_symb_sch,
+ nb_re_dmrs,
+ length_dmrs,
+ dlsch0->harq_processes[harq_pid]->Qm,
+ dlsch0->harq_processes[harq_pid]->Nl);
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_unscrambling_stats);
#endif
nr_dlsch_unscrambling(pdsch_vars->llr[0],
- dlsch0->harq_processes[harq_pid]->G,
- 0,
- ue->frame_parms.Nid_cell,
- dlsch0->rnti);
+ dlsch0->harq_processes[harq_pid]->G,
+ 0,
+ ue->frame_parms.Nid_cell,
+ dlsch0->rnti);
#if UE_TIMING_TRACE
@@ -3629,10 +3467,10 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
start_meas(&ue->dlsch_unscrambling_stats);
#endif
nr_dlsch_unscrambling(pdsch_vars->llr[1],
- dlsch1->harq_processes[harq_pid]->G,
- 0,
- ue->frame_parms.Nid_cell,
- dlsch1->rnti);
+ dlsch1->harq_processes[harq_pid]->G,
+ 0,
+ ue->frame_parms.Nid_cell,
+ dlsch1->rnti);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_unscrambling_stats);
#endif
@@ -3653,31 +3491,31 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
#ifdef UE_DLSCH_PARALLELISATION
ret1 = nr_dlsch_decoding_mthread(ue,
- proc,
- eNB_id,
- pdsch_vars->llr[1],
- &ue->frame_parms,
- dlsch1,
- dlsch1->harq_processes[harq_pid],
- frame_rx,
- nb_symb_sch,
- nr_tti_rx,
- harq_pid,
- pdsch==PDSCH?1:0,
- dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+ proc,
+ eNB_id,
+ pdsch_vars->llr[1],
+ &ue->frame_parms,
+ dlsch1,
+ dlsch1->harq_processes[harq_pid],
+ frame_rx,
+ nb_symb_sch,
+ nr_tti_rx,
+ harq_pid,
+ pdsch==PDSCH?1:0,
+ dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret1 = %d\n", ret1);
#else
ret1 = nr_dlsch_decoding(ue,
- pdsch_vars->llr[1],
- &ue->frame_parms,
- dlsch1,
- dlsch1->harq_processes[harq_pid],
- frame_rx,
- nb_symb_sch,
- nr_tti_rx,
- harq_pid,
- pdsch==PDSCH?1:0,//proc->decoder_switch,
- dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+ pdsch_vars->llr[1],
+ &ue->frame_parms,
+ dlsch1,
+ dlsch1->harq_processes[harq_pid],
+ frame_rx,
+ nb_symb_sch,
+ nr_tti_rx,
+ harq_pid,
+ pdsch==PDSCH?1:0,//proc->decoder_switch,
+ dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
LOG_T(PHY,"UE_DLSCH_PARALLELISATION is NOT defined, ret1 = %d\n", ret1);
printf("start cw1 dlsch decoding\n");
#endif
@@ -3699,35 +3537,46 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
#endif
LOG_I(PHY,"AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
+
+ LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS);
}
LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ \n", frame_rx, nr_tti_rx);
-
- LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d, TBS expected dlsch1: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS, dlsch1->harq_processes[harq_pid]->TBS);
+ LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS);
if(retmax_ldpc_iterations+1){
- // fill dl_indication message
- dl_indication.module_id = ue->Mod_id;
- dl_indication.cc_id = ue->CC_id;
- dl_indication.gNB_index = eNB_id;
- dl_indication.frame = frame_rx;
- dl_indication.slot = nr_tti_rx;
- dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance
- dl_indication.proc=proc;
+ // fill dl_indication message
+ dl_indication.module_id = ue->Mod_id;
+ dl_indication.cc_id = ue->CC_id;
+ dl_indication.gNB_index = eNB_id;
+ dl_indication.frame = frame_rx;
+ dl_indication.slot = nr_tti_rx;
+ dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance
+ dl_indication.proc=proc;
- //dl_indication.rx_ind->number_pdus
- rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
- rx_ind.rx_indication_body[0].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b;
- rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS>>3;
- LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length);
- rx_ind.number_pdus = 1;
+ //dl_indication.rx_ind->number_pdus
+ switch (pdsch) {
+ case RA_PDSCH:
+ rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_RAR;
+ break;
+ case PDSCH:
+ rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
+ break;
+ default:
+ break;
+ }
- //ue->dl_indication.rx_ind = &dlsch1->harq_processes[harq_pid]->b; //no data, only dci for now
- dl_indication.dci_ind = NULL; //&ue->dci_ind;
- // send to mac
- if (ue->if_inst && ue->if_inst->dl_indication)
- ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
+ rx_ind.rx_indication_body[0].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b;
+ rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS>>3;
+ LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length);
+ rx_ind.number_pdus = 1;
+
+ //ue->dl_indication.rx_ind = &dlsch1->harq_processes[harq_pid]->b; //no data, only dci for now
+ dl_indication.dci_ind = NULL; //&ue->dci_ind;
+ // send to mac
+ if (ue->if_inst && ue->if_inst->dl_indication)
+ ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
}
// TODO CRC check for CW0
@@ -4045,7 +3894,6 @@ void *UE_thread_slot1_dl_processing(void *arg) {
}
//printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,nr_tti_rx,wait);
-
/**** Pdsch Procedure Slot1 ****/
// start slot1 thread for Pdsch Procedure (slot1)
// do procedures for C-RNTI
@@ -4133,7 +3981,6 @@ void *UE_thread_slot1_dl_processing(void *arg) {
#endif
#endif
-
if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("noting to add");
@@ -4182,18 +4029,14 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
int nr_tti_rx = proc->nr_tti_rx;
int slot_pbch;
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0];
- NR_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id];
fapi_nr_config_request_t *cfg = &ue->nrUE_config;
- uint8_t harq_pid = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid;
- NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
- uint16_t start_symb_sch = dlsch0_harq->start_symbol;
+
uint8_t nb_symb_pdcch = pdcch_vars->nb_search_space > 0 ? pdcch_vars->pdcch_config[0].coreset.duration : 0;
uint8_t dci_cnt = 0;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
-
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
-
+
LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx);
/*
@@ -4201,7 +4044,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
*/
-
int coreset_nb_rb=0;
int coreset_start_rb=0;
if (pdcch_vars->nb_search_space > 0)
@@ -4236,11 +4078,12 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if (ue->no_timing_correction==0) {
LOG_I(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction);
nr_adjust_synch_ue(fp,
- ue,
- eNB_id,
- nr_tti_rx,
- 0,
- 16384);
+ ue,
+ eNB_id,
+ frame_rx,
+ nr_tti_rx,
+ 0,
+ 16384);
}
}
@@ -4255,10 +4098,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
nr_slot_fep(ue,
- l,
- nr_tti_rx,
- 0,
- 0);
+ l,
+ nr_tti_rx,
+ 0,
+ 0);
// note: this only works if RBs for PDCCH are contigous!
LOG_D(PHY,"pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d\n",
@@ -4285,40 +4128,41 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if (dci_cnt > 0) {
- LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: found %d DCIs\n",ue->Mod_id,frame_rx,nr_tti_rx,dci_cnt);
+ LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_tti_rx, dci_cnt);
- } else {
- LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n",ue->Mod_id,frame_rx,nr_tti_rx);
- }
-#endif //NR_PDCCH_SCHED
+ NR_UE_DLSCH_t *dlsch = NULL;
+ if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1){
+ dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0];
+ } else if (ue->dlsch_ra[0]->active == 1){
+ dlsch = ue->dlsch_ra[0];
+ }
+ AssertFatal(dlsch != NULL, "Unsupported mode\n");
+ uint8_t harq_pid = dlsch->current_harq_pid;
+ NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid];
+ uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
+ uint16_t start_symb_sch = dlsch0_harq->start_symbol;
+ int symb_dmrs = -1;
-
- if (dci_cnt > 0){
LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
//to update from pdsch config
- start_symb_sch = dlsch0_harq->start_symbol;
- int symb_dmrs=-1;
+
for (int i=0;i<4;i++) if (((1<dlDmrsSymbPos) > 0) {symb_dmrs=i;break;}
AssertFatal(symb_dmrs>=0,"no dmrs in 0..3\n");
LOG_D(PHY,"Initializing dmrs for symb %d DMRS mask %x\n",symb_dmrs,dlsch0_harq->dlDmrsSymbPos);
nr_gold_pdsch(ue,symb_dmrs,0, 1);
-
- nb_symb_sch = dlsch0_harq->nb_symbols;
for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
nr_slot_fep(ue,
- m, //to be updated from higher layer
- nr_tti_rx,
- 0,
- 0);
-
-
+ m, //to be updated from higher layer
+ nr_tti_rx,
+ 0,
+ 0);
}
- //set active for testing, to be removed
- ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 1;
+ } else {
+ LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_tti_rx);
}
- else
- ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
+
+#endif //NR_PDCCH_SCHED
#if UE_TIMING_TRACE
start_meas(&ue->generic_stat);
@@ -4332,7 +4176,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
PDSCH,
ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0],
NULL);
-
+
//printf("phy procedure pdsch start measurement\n");
nr_ue_measurement_procedures(2,ue,proc,eNB_id,nr_tti_rx,mode);
@@ -4344,7 +4188,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
write_output("rxF_comp.m","rxFc",&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_comp0[0][0],fp->N_RB_DL*12*14,1,1);
write_output("rxF_llr.m","rxFllr",ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr[0],(nb_symb_sch-1)*50*12+50*6,1,0);
*/
-
+
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
}
@@ -4352,11 +4196,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
nr_ue_pdsch_procedures(ue,
- proc,
- eNB_id,
- SI_PDSCH,
- ue->dlsch_SI[eNB_id],
- NULL);
+ proc,
+ eNB_id,
+ SI_PDSCH,
+ ue->dlsch_SI[eNB_id],
+ NULL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
}
@@ -4365,11 +4209,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
nr_ue_pdsch_procedures(ue,
- proc,
- eNB_id,
- P_PDSCH,
- ue->dlsch_p[eNB_id],
- NULL);
+ proc,
+ eNB_id,
+ P_PDSCH,
+ ue->dlsch_p[eNB_id],
+ NULL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
}
@@ -4378,18 +4222,42 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
nr_ue_pdsch_procedures(ue,
- proc,
- eNB_id,
- RA_PDSCH,
- ue->dlsch_ra[eNB_id],
- NULL);
+ proc,
+ eNB_id,
+ RA_PDSCH,
+ ue->dlsch_ra[eNB_id],
+ NULL);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
+ // #if UE_TIMING_TRACE
+ // start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+ // #endif
+
+ nr_ue_dlsch_procedures(ue,
+ proc,
+ eNB_id,
+ RA_PDSCH,
+ ue->dlsch_ra[eNB_id],
+ NULL,
+ &ue->dlsch_ra_errors[eNB_id],
+ mode);
+
+ // #if UE_TIMING_TRACE
+ // stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+ #if DISABLE_LOG_X
+ printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+ printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
+ #else
+ LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
+ LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
+ #endif
+ // #endif
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
}
// do procedures for C-RNTI
if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
-
+
LOG_D(PHY, "DLSCH data reception at nr_tti_rx: %d \n \n", nr_tti_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
@@ -4419,6 +4287,9 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
#endif
+ // deactivate dlsch once dlsch proc is done
+ ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
}
@@ -4624,3 +4495,119 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,
return(0);
}
+// WIP
+// todo:
+// - set tx_total_RE
+// - power control as per 38.213 ch 7.4
+void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t runmode) {
+
+ int frame_tx = proc->frame_tx, nr_tti_tx = proc->nr_tti_tx, prach_power; // tx_amp
+ uint16_t /*preamble_tx = 50,*/ pathloss;
+ uint8_t mod_id = ue->Mod_id;
+ UE_MODE_t UE_mode = get_nrUE_mode(mod_id, ue->CC_id, gNB_id);
+ NR_PRACH_RESOURCES_t * prach_resources = ue->prach_resources[gNB_id];
+ uint8_t nr_prach = 0;
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
+
+ if (ue->mac_enabled == 0){
+ // prach_resources->ra_PreambleIndex = preamble_tx;
+ prach_resources->ra_TDD_map_index = 0;
+ prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10;
+ prach_resources->ra_RNTI = 0x1234;
+ nr_prach = 1;
+ } else {
+ // ask L2 for RACH transport
+ if ((runmode != rx_calib_ue) && (runmode != rx_calib_ue_med) && (runmode != rx_calib_ue_byp) && (runmode != no_L2_connect) ) {
+ LOG_D(PHY, "Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_tti_tx);
+ // flush Msg3 Buffer
+ if (prach_resources->Msg3 == NULL){
+ for(int i = 0; iulsch_Msg3_active[i] = 0;
+ }
+ }
+ nr_prach = nr_ue_get_rach(ue->prach_resources[gNB_id], mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_tti_tx);
+ }
+ }
+
+ if (!prach_resources->init_msg1 && (frame_tx > ue->prach_resources[gNB_id]->sync_frame + 150)){
+ ue->prach_cnt = 0;
+ prach_resources->init_msg1 = 1;
+ }
+
+ if (ue->prach_resources[gNB_id] != NULL && nr_prach == 1 && prach_resources->init_msg1) {
+
+ pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id);
+ LOG_D(PHY,"runmode %d\n",runmode);
+
+ if ((ue->mac_enabled == 1) && (runmode != calib_prach_tx)) {
+ ue->tx_power_dBm[nr_tti_tx] = prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss;
+ }
+
+ LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d : Generating PRACH, preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x\n",
+ ue->Mod_id,
+ frame_tx,
+ nr_tti_tx,
+ prach_resources->ra_PreambleIndex,
+ pathloss,
+ ue->tx_power_dBm[nr_tti_tx],
+ prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER,
+ prach_resources->ra_RNTI);
+
+ //ue->tx_total_RE[nr_tti_tx] = 96; // todo
+ ue->prach_vars[gNB_id]->amp = AMP;
+
+ /* #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+ tx_amp = get_tx_amp_prach(ue->tx_power_dBm[nr_tti_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL);
+ if (tx_amp != -1)
+ ue->prach_vars[gNB_id]->amp = tx_amp;
+ #else
+ ue->prach_vars[gNB_id]->amp = AMP;
+ #endif */
+
+ if ((runmode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
+ LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d : PRACH TX power %d dBm, amp %d\n", ue->Mod_id,
+ proc->frame_rx,
+ proc->nr_tti_tx,
+ ue->tx_power_dBm[nr_tti_tx],
+ ue->prach_vars[gNB_id]->amp);
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
+
+ prach_power = generate_nr_prach(ue, gNB_id, nr_tti_tx);
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
+
+ LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
+ ue->Mod_id,
+ pathloss,
+ ue->tx_power_dBm[nr_tti_tx],
+ dB_fixed(prach_power),
+ ue->prach_vars[gNB_id]->amp);
+
+ if (ue->mac_enabled == 1)
+ nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id);
+
+ LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d: Generated PRACH Msg1 (gNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB) \n",
+ ue->Mod_id,
+ frame_tx,
+ nr_tti_tx,
+ gNB_id,
+ prach_resources->ra_PreambleIndex,
+ ue->tx_power_dBm[nr_tti_tx],
+ pathloss);
+
+ LOG_D(PHY,"[UE %d] frame %d nr_tti_tx %d : prach_cnt %d\n", ue->Mod_id, frame_tx, nr_tti_tx, ue->prach_cnt);
+
+ ue->prach_cnt++;
+
+ if (ue->prach_cnt == 3)
+ ue->prach_cnt = 0;
+ }
+
+ // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
+ if (runmode == calib_prach_tx)
+ ue->prach_resources[gNB_id] = NULL;
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
+}
diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
index 9632291e67..b51c8afbb0 100644
--- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
@@ -104,7 +104,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue,
int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH;
- int16_t PL = get_nr_PL(ue, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */
+ int16_t PL = get_nr_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */
int16_t delta_F_PUCCH = power_config->deltaF_PUCCH_f[pucch_format];
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
index 1b62ff81bf..ccbe502194 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
@@ -37,7 +37,6 @@
#include "PHY/defs_nr_UE.h"
#include
#include
-#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#ifndef NO_RAT_NR
@@ -162,6 +161,8 @@ void nr_generate_pucch3_4(int32_t **txdataF,
*
*********************************************************************/
+static int bwp_id = 1;
+
bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, bool reset_harq)
{
uint8_t sr_payload = 0;
@@ -186,12 +187,18 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
int pucch_resource_id = MAX_NB_OF_PUCCH_RESOURCES;
int pucch_resource_indicator = MAX_PUCCH_RESOURCE_INDICATOR;
int n_HARQ_ACK;
+
uint16_t crnti=0x1234;
int dmrs_scrambling_id=0,data_scrambling_id=0;
+
+ NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+ NR_PUCCH_Resource_t *pucch_resource;
+ //NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+
/* update current context */
- int subframe_number = (proc->nr_tti_rx)/(ue->frame_parms.ttis_per_subframe);
+ int subframe_number = (proc->nr_tti_rx)/(ue->frame_parms.slots_per_subframe);//ttis_per_subframe);
nb_pucch_format_4_in_subframes[subframe_number] = 0; /* reset pucch format 4 counter at current rx position */
int dl_harq_pid = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid;
@@ -214,11 +221,11 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
/* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */
sr_payload = nr_ue_get_SR(Mod_id,
- CC_id,
- frame_tx,
- gNB_id,
- 0,//ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti,
- nr_tti_tx); // nr_tti_rx used for meas gap
+ CC_id,
+ frame_tx,
+ gNB_id,
+ 0,//ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti,
+ nr_tti_tx); // nr_tti_rx used for meas gap
}
else {
sr_payload = 1;
@@ -250,10 +257,10 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
}
else {
/* a resource set and a resource should be find according to payload size */
- pucch_resource_set = find_pucch_resource_set( ue, gNB_id, N_UCI);
+ pucch_resource_set = find_pucch_resource_set( mac, gNB_id, N_UCI);
if (pucch_resource_set != MAX_NB_OF_PUCCH_RESOURCE_SETS) {
pucch_resource_indicator = 0;
- pucch_resource_id = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_ResourceSet[pucch_resource_set]->pucch_resource_id[pucch_resource_indicator]; /* get the first resource of the set */
+ pucch_resource_id = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set]->resourceList.list.array[pucch_resource_indicator][0]; /* get the first resource of the set */
}
else {
LOG_W(PHY,"PUCCH no resource set found for CSI at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
@@ -299,7 +306,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack;
- if (select_pucch_resource(ue, gNB_id, N_UCI, pucch_resource_indicator, &initial_pucch_id, &pucch_resource_set,
+ if (select_pucch_resource(ue, mac, gNB_id, N_UCI, pucch_resource_indicator, &initial_pucch_id, &pucch_resource_set,
&pucch_resource_id, harq_status) == TRUE) {
/* use of initial pucch configuration provided by system information 1 */
/***********************************************************************/
@@ -340,33 +347,43 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
/**********************************************/
else if ((pucch_resource_set != MAX_NB_OF_PUCCH_RESOURCE_SETS) && (pucch_resource_id != MAX_NB_OF_PUCCH_RESOURCES)) {
/* check that current configuration is supported */
- if ((ue->cell_group_config.physicalCellGroupConfig.harq_ACK_SpatialBundlingPUCCH != FALSE)
- || (ue->cell_group_config.physicalCellGroupConfig.pdsch_HARQ_ACK_Codebook != dynamic)) {
+ if ((mac->scg->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH != NULL)
+ || (mac->scg->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook != 1)) {
LOG_E(PHY,"PUCCH Unsupported cell group configuration : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
return(FALSE);
}
- else if (ue->PDSCH_ServingCellConfig.codeBlockGroupTransmission != NULL) {
+ else if (mac->scg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) {
LOG_E(PHY,"PUCCH Unsupported code block group for serving cell config : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
return(FALSE);
}
- format = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->format_parameters.format;
- nb_symbols_total = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols;
- starting_symbol_index = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex;
- starting_prb = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->startingPRB;
+ pucch_resource = select_resource_by_id(pucch_resource_id, mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup);
+ format = pucch_resource->format.present;
+ nb_symbols_total = get_nb_symbols_pucch(pucch_resource, format);
+ starting_symbol_index = get_starting_symb_idx(pucch_resource, format);
+ starting_prb = pucch_resource->startingPRB;
second_hop = starting_prb;
- time_domain_occ = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC; /* format 1 only */
- occ_length = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length; /* format 4 only */
- occ_Index = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index; /* format 4 only */
-
- if ((format == pucch_format0_nr) || (format == pucch_format1_nr)) {
- m_0 = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift;
+ if (format==pucch_format1_nr)
+ time_domain_occ = pucch_resource->format.choice.format1->timeDomainOCC;
+ if (format==pucch_format4_nr) {
+ occ_length = pucch_resource->format.choice.format4->occ_Length;
+ occ_Index = pucch_resource->format.choice.format4->occ_Index;
}
- else if ((format == pucch_format3_nr) || (format == pucch_format4_nr)) {
- if (ue->pucch_config_dedicated_nr[gNB_id].formatConfig[format-1]->additionalDMRS == enable_feature) {
+
+ m_0 = get_ics_pucch(pucch_resource, format);
+ AssertFatal(m_0 >= 0, "Invalid m_0\n");
+ if (format == pucch_format3_nr) {
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3->choice.setup->additionalDMRS[0] == 1) {
index_additional_dmrs = I_PUCCH_ADDITIONAL_DMRS;
}
+ }
+ else if (format == pucch_format4_nr) {
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4->choice.setup->additionalDMRS[0] == 1) {
+ index_additional_dmrs = I_PUCCH_ADDITIONAL_DMRS;
+ }
+ }
- if (ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping == feature_enabled) {
+ if ((format == pucch_format3_nr) || (format == pucch_format4_nr)) {
+ if (pucch_resource->intraSlotFrequencyHopping[0] == 1) {
index_hopping = I_PUCCH_HOPING;
}
}
@@ -385,6 +402,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
int O_CRC = 0;
nb_symbols = nb_symbols_total; /* by default, it can be reduced due to symbols reserved for dmrs */
+ pucch_resource = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList->list.array[pucch_resource_id];
switch(format) {
case pucch_format0_nr:
@@ -401,14 +419,14 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
}
case pucch_format2_nr:
{
- nb_of_prbs = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs;
+ nb_of_prbs = pucch_resource->format.choice.format2->nrofPRBs;
N_sc_ctrl_RB = N_SC_RB - 4;
break;
}
case pucch_format3_nr:
{
- nb_of_prbs = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs;
- if (ue->pucch_config_dedicated_nr[gNB_id].formatConfig[format-1]->pi2PBSK == feature_enabled) {
+ nb_of_prbs = pucch_resource->format.choice.format3->nrofPRBs;
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3->choice.setup->pi2BPSK[0] == 1) {
Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */
}
N_sc_ctrl_RB = N_SC_RB;
@@ -417,12 +435,12 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
}
case pucch_format4_nr:
{
- if (ue->pucch_config_dedicated_nr[gNB_id].formatConfig[format-1]->pi2PBSK == feature_enabled) {
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4->choice.setup->pi2BPSK[0] == 1) {
Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */
}
nb_symbols = nb_symbols_excluding_dmrs[nb_symbols_total-4][index_additional_dmrs][index_hopping];
nb_of_prbs = 1;
- subframe_number = nr_tti_tx/(ue->frame_parms.ttis_per_subframe);
+ subframe_number = nr_tti_tx/(ue->frame_parms.slots_per_subframe);//ttis_per_subframe);
nb_pucch_format_4_in_subframes[subframe_number]++; /* increment number of transmit pucch 4 in current subframe */
NR_TST_PHY_PRINTF("PUCCH Number of pucch format 4 in subframe %d is %d \n", subframe_number, nb_pucch_format_4_in_subframes[subframe_number]);
N_sc_ctrl_RB = N_SC_RB/(nb_pucch_format_4_in_subframes[subframe_number]);
@@ -434,10 +452,10 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
/* drop CSI report if simultaneous HARQ-ACK/SR and periodic/semi-periodic CSI cannot be transmitted at the same time */
if (format != pucch_format0_nr) {
- if (ue->pucch_config_dedicated_nr[gNB_id].formatConfig[format-1] != NULL) {
- max_code_rate = code_rate_r_time_100[ue->pucch_config_dedicated_nr[gNB_id].formatConfig[format-1]->maxCodeRate]; /* it is code rate * 10 */
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1 != NULL) {
+ max_code_rate = code_rate_r_time_100[mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1->choice.setup->maxCodeRate[0]]; /* it is code rate * 10 */
- if ((O_ACK != 0) && (ue->pucch_config_dedicated_nr[gNB_id].formatConfig[format-1]->simultaneousHARQ_ACK_CSI == disable_feature)) {
+ if ((O_ACK != 0) && (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1->choice.setup->simultaneousHARQ_ACK_CSI[0] == 0)) {
N_UCI = N_UCI - O_CSI;
O_CSI = cqi_status = ri_status = 0;
csi_payload = 0; /* csi should be dropped in this case */
@@ -563,7 +581,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
{
nr_generate_pucch0(ue,ue->common_vars.txdataF,
&ue->frame_parms,
- &ue->pucch_config_dedicated[gNB_id],
+ mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping,
+ mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId[0],
tx_amp,
nr_tti_tx,
(uint8_t)m_0,
@@ -679,8 +698,11 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t
int U_DAI_c = 0;
int N_m_c_rx = 0;
int V_DAI_m_DL = 0;
+ NR_UE_MAC_INST_t *mac = get_mac_inst(0);
- if (ue->PDSCH_Config.maxNrofCodeWordsScheduledByDCI == nb_code_n2) {
+ if (mac->DLbwp[0] == NULL) return 0;
+
+ if (mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0] == 2) {
two_transport_blocks = TRUE;
number_of_code_word = 2;
}
@@ -698,46 +720,49 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t
for (int dl_harq_pid = 0; dl_harq_pid < number_pid_dl; dl_harq_pid++) {
- harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid]->harq_ack;
+ for (int thread_idx = 0; thread_idx < RX_NB_TH; thread_idx++) {
- /* check if current tx slot should transmit downlink acknowlegment */
- if (harq_status->slot_for_feedback_ack == proc->nr_tti_tx) {
+ harq_status = &ue->dlsch[thread_idx][gNB_id][code_word]->harq_processes[dl_harq_pid]->harq_ack;
- if (harq_status->ack == DL_ACKNACK_NO_SET) {
- LOG_E(PHY,"PUCCH Downlink acknowledgment has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
- return (0);
- }
- else if (harq_status->vDAI_DL == DL_DAI_NO_SET) {
- LOG_E(PHY,"PUCCH Downlink DAI has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
- return (0);
- }
- else if (harq_status->vDAI_DL > NR_DL_MAX_DAI) {
- LOG_E(PHY,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
- return (0);
- }
- else if (harq_status->send_harq_status == 0) {
- LOG_E(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
- return(0);
- }
- else {
+ /* check if current tx slot should transmit downlink acknowlegment */
+ if (harq_status->slot_for_feedback_ack == proc->nr_tti_tx) {
- dai_current = harq_status->vDAI_DL;
-
- if (dai_current == 0) {
- LOG_E(PHY,"PUCCH Downlink dai is invalid : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
- return(0);
- } else if (dai_current > dai_max) {
- dai_max = dai_current;
+ if (harq_status->ack == DL_ACKNACK_NO_SET) {
+ LOG_E(PHY,"PUCCH Downlink acknowledgment has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+ return (0);
}
+ else if (harq_status->vDAI_DL == DL_DAI_NO_SET) {
+ LOG_E(PHY,"PUCCH Downlink DAI has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+ return (0);
+ }
+ else if (harq_status->vDAI_DL > NR_DL_MAX_DAI) {
+ LOG_E(PHY,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+ return (0);
+ }
+ else if (harq_status->send_harq_status == 0) {
+ LOG_E(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+ return(0);
+ }
+ else {
- number_harq_feedback++;
- ack_data[code_word][dai_current - 1] = harq_status->ack;
- dai[code_word][dai_current - 1] = dai_current;
+ dai_current = harq_status->vDAI_DL+1; // DCI DAI to counter DAI conversion
+
+ if (dai_current == 0) {
+ LOG_E(PHY,"PUCCH Downlink dai is invalid : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+ return(0);
+ } else if (dai_current > dai_max) {
+ dai_max = dai_current;
+ }
+
+ number_harq_feedback++;
+ ack_data[code_word][dai_current - 1] = harq_status->ack;
+ dai[code_word][dai_current - 1] = dai_current;
+ }
+ if (do_reset == TRUE) {
+ init_downlink_harq_status(ue->dlsch[thread_idx][gNB_id][code_word]->harq_processes[dl_harq_pid]);
+ }
}
}
- if (do_reset == TRUE) {
- init_downlink_harq_status(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid]);
- }
}
}
@@ -756,8 +781,8 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t
U_DAI_c = number_harq_feedback/number_of_code_word;
N_m_c_rx = number_harq_feedback;
int N_SPS_c = 0; /* FFS TODO_NR multicells and SPS are not supported at the moment */
- if (ue->cell_group_config.physicalCellGroupConfig.harq_ACK_SpatialBundlingPUCCH == FALSE) {
- int N_TB_max_DL = ue->PDSCH_Config.maxNrofCodeWordsScheduledByDCI;
+ if (mac->scg->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH == NULL) {
+ int N_TB_max_DL = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0];
*n_HARQ_ACK = (((V_DAI_m_DL - U_DAI_c)%4) * N_TB_max_DL) + N_m_c_rx + N_SPS_c;
NR_TST_PHY_PRINTF("PUCCH power n(%d) = ( V(%d) - U(%d) )mod4 * N_TB(%d) + N(%d) \n", *n_HARQ_ACK, V_DAI_m_DL, U_DAI_c, N_TB_max_DL, N_m_c_rx);
}
@@ -853,7 +878,7 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t
*
*********************************************************************/
-boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size, int pucch_resource_indicator,
+boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size, int pucch_resource_indicator,
int *initial_pucch_id, int *resource_set_id, int *resource_id, NR_UE_HARQ_STATUS_t *harq_status)
{
boolean_t resource_set_found = FALSE;
@@ -861,18 +886,19 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size
int current_resource_id = MAX_NB_OF_PUCCH_RESOURCES;
pucch_format_nr_t format_pucch;
int ready_pucch_resource_id = FALSE; /* in the case that it is already given */
+ NR_PUCCH_Resource_t *pucch_resource;
/* ini values to unset */
*initial_pucch_id = NB_INITIAL_PUCCH_RESOURCE;
//*resource_set_id = MAX_NB_OF_PUCCH_RESOURCE_SETS;
//*resource_id = MAX_NB_OF_PUCCH_RESOURCES;
- if (ue->pucch_config_dedicated_nr[gNB_id].PUCCH_ResourceSet[0] == NULL) {
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[0] == NULL) {
/* No resource set has been already configured so pucch_configCommon from Sib1 should be used in this case */
if (ue->UE_mode[gNB_id] != PUSCH) {
- *initial_pucch_id = ue->pucch_config_common_nr[gNB_id].pucch_ResourceCommon;
+ *initial_pucch_id = mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon[0];
if (*initial_pucch_id >= NB_INITIAL_PUCCH_RESOURCE) {
LOG_E(PHY,"PUCCH Invalid initial resource index : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
*initial_pucch_id = NB_INITIAL_PUCCH_RESOURCE;
@@ -897,7 +923,7 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size
}
nb_symbols_for_tx = initial_pucch_resource[*initial_pucch_id].nrofSymbols;
format_pucch = initial_pucch_resource[*initial_pucch_id].format;
- if (check_pucch_format(ue, gNB_id, format_pucch, nb_symbols_for_tx, uci_size) == TRUE) {
+ if (check_pucch_format(mac, gNB_id, format_pucch, nb_symbols_for_tx, uci_size) == TRUE) {
return (TRUE);
}
else {
@@ -917,7 +943,7 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size
-- This field can take integer values that are multiples of 4. Corresponds to L1 parameter 'N_2' or 'N_3' (see 38.213, section 9.2)
*/
/* look for the first resource set which supports uci_size number of bits for payload */
- pucch_resource_set_id = find_pucch_resource_set( ue, gNB_id, uci_size);
+ pucch_resource_set_id = find_pucch_resource_set(mac, gNB_id, uci_size);
if (pucch_resource_set_id != MAX_NB_OF_PUCCH_RESOURCE_SETS) {
resource_set_found = TRUE;
}
@@ -932,13 +958,13 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size
if (resource_set_found == TRUE) {
if (pucch_resource_indicator < MAX_PUCCH_RESOURCE_INDICATOR) {
/* check if resource indexing by pucch_resource_indicator of this set is compatible */
- if ((ready_pucch_resource_id == TRUE) || (ue->pucch_config_dedicated_nr[gNB_id].PUCCH_ResourceSet[pucch_resource_set_id]->pucch_resource_id[pucch_resource_indicator] != MAX_NB_OF_PUCCH_RESOURCES)) {
+ if ((ready_pucch_resource_id == TRUE) || (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.array[pucch_resource_indicator][0] != MAX_NB_OF_PUCCH_RESOURCES)) {
if (ready_pucch_resource_id == TRUE) {
current_resource_id = *resource_id;
}
else {
- int R_PUCCH = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_ResourceSet[pucch_resource_set_id]->first_resources_set_R_PUCCH;
+ int R_PUCCH = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.count;
/* is it the first resource and its size exceeds 8 */
if ((pucch_resource_set_id == 0)
&& (R_PUCCH > MAX_NB_OF_PUCCH_RESOURCES_PER_SET_NOT_0)) {
@@ -960,15 +986,22 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size
current_resource_id = r_PUCCH;
}
else {
- current_resource_id = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_ResourceSet[pucch_resource_set_id]->pucch_resource_id[pucch_resource_indicator];
+ current_resource_id = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.array[pucch_resource_indicator][0];
}
}
- if (ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[current_resource_id] != NULL) {
- nb_symbols_for_tx = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[current_resource_id]->format_parameters.nrofSymbols;
- format_pucch = ue->pucch_config_dedicated_nr[gNB_id].PUCCH_Resource[current_resource_id]->format_parameters.format;
+ /*uint8_t pucch_resource_count = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList.list.count;
+ for (uint8_t i=0; iULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList.list.array[i]->pucch_ResourceId == current_resource_id)
+ pucch_resource = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList.list.array[i];
+ }*/
- if (check_pucch_format(ue, gNB_id, format_pucch, nb_symbols_for_tx, uci_size) == TRUE) {
+ pucch_resource = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList->list.array[current_resource_id];
+ if (pucch_resource != NULL) {
+ format_pucch = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList->list.array[current_resource_id]->format.present;
+ nb_symbols_for_tx = get_nb_symbols_pucch(pucch_resource, format_pucch);
+
+ if (check_pucch_format(mac, gNB_id, format_pucch, nb_symbols_for_tx, uci_size) == TRUE) {
*resource_set_id = pucch_resource_set_id;
*resource_id = current_resource_id;
return (TRUE);
@@ -1014,9 +1047,10 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size
*
*********************************************************************/
-int find_pucch_resource_set(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size)
+int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size)
{
int pucch_resource_set_id = 0;
+ long *pucch_max_pl_bits = NULL;
/* from TS 38.331 field maxPayloadMinus1
-- Maximum number of payload bits minus 1 that the UE may transmit using this PUCCH resource set. In a PUCCH occurrence, the UE
@@ -1027,8 +1061,9 @@ int find_pucch_resource_set(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size)
*/
/* look for the first resource set which supports uci_size number of bits for payload */
while (pucch_resource_set_id < MAX_NB_OF_PUCCH_RESOURCE_SETS) {
- if (ue->pucch_config_dedicated_nr[gNB_id].PUCCH_ResourceSet[pucch_resource_set_id] != NULL) {
- if (uci_size <= ue->pucch_config_dedicated_nr[gNB_id].PUCCH_ResourceSet[pucch_resource_set_id]->maxPayloadMinus1 + 1) {
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id] != NULL) {
+ pucch_max_pl_bits = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->maxPayloadMinus1;
+ if (uci_size <= (((pucch_max_pl_bits != NULL) ? *pucch_max_pl_bits : 1706) + 1)) {
NR_TST_PHY_PRINTF("PUCCH found resource set %d \n", pucch_resource_set_id);
return (pucch_resource_set_id);
break;
@@ -1057,18 +1092,40 @@ int find_pucch_resource_set(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size)
*
*********************************************************************/
-boolean_t check_pucch_format(PHY_VARS_NR_UE *ue, uint8_t gNB_id, pucch_format_nr_t format_pucch, int nb_symbols_for_tx, int uci_size)
+boolean_t check_pucch_format(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, pucch_format_nr_t format_pucch, int nb_symbols_for_tx, int uci_size)
{
pucch_format_nr_t selected_pucch_format;
pucch_format_nr_t selected_pucch_format_second;
+ NR_SetupRelease_PUCCH_FormatConfig_t *identified_format = NULL;
- if (format_pucch != pucch_format0_nr) {
- if (ue->pucch_config_dedicated_nr[gNB_id].formatConfig[format_pucch-1] != NULL) {
- if (ue->pucch_config_dedicated_nr[gNB_id].formatConfig[format_pucch-1]->nrofSlots != 1) {
- LOG_E(PHY,"PUCCH not implemented multislots transmission : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
- return (FALSE);
- }
- }
+ switch (format_pucch) {
+ case pucch_format1_nr:
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1 != NULL)
+ identified_format = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1;
+ break;
+
+ case pucch_format2_nr:
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format2 != NULL)
+ identified_format = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format2;
+ break;
+
+ case pucch_format3_nr:
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3 != NULL)
+ identified_format = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3;
+ break;
+
+ case pucch_format4_nr:
+ if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4 != NULL)
+ identified_format = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4;
+ break;
+
+ default:
+ break;
+ }
+
+ if ((identified_format != NULL) && (identified_format->choice.setup->nrofSlots[0] != 1)) {
+ LOG_E(PHY,"PUCCH not implemented multislots transmission : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+ return (FALSE);
}
if (nb_symbols_for_tx <= 2) {
@@ -1160,7 +1217,7 @@ int trigger_periodic_scheduling_request(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_n
return (1); /* period is slot */
}
- int16_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * ue->frame_parms.ttis_per_subframe;
+ int16_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * ue->frame_parms.slots_per_subframe;//ttis_per_subframe;
if (((proc->frame_tx * N_slot_frame) + proc->nr_tti_tx - SR_offset)%SR_periodicity == 0) {
return (1);
}
@@ -1219,4 +1276,74 @@ void set_csi_nr(int csi_status, uint32_t csi_payload)
}
}
+uint8_t get_nb_symbols_pucch(NR_PUCCH_Resource_t *pucch_resource, pucch_format_nr_t format_type)
+{
+ switch (format_type) {
+ case pucch_format0_nr:
+ return pucch_resource->format.choice.format0->nrofSymbols;
+
+ case pucch_format1_nr:
+ return pucch_resource->format.choice.format1->nrofSymbols;
+
+ case pucch_format2_nr:
+ return pucch_resource->format.choice.format2->nrofSymbols;
+
+ case pucch_format3_nr:
+ return pucch_resource->format.choice.format3->nrofSymbols;
+
+ case pucch_format4_nr:
+ return pucch_resource->format.choice.format4->nrofSymbols;
+ }
+ return 0;
+}
+
+uint16_t get_starting_symb_idx(NR_PUCCH_Resource_t *pucch_resource, pucch_format_nr_t format_type)
+{
+ switch (format_type) {
+ case pucch_format0_nr:
+ return pucch_resource->format.choice.format0->startingSymbolIndex;
+
+ case pucch_format1_nr:
+ return pucch_resource->format.choice.format1->startingSymbolIndex;
+
+ case pucch_format2_nr:
+ return pucch_resource->format.choice.format2->startingSymbolIndex;
+
+ case pucch_format3_nr:
+ return pucch_resource->format.choice.format3->startingSymbolIndex;
+
+ case pucch_format4_nr:
+ return pucch_resource->format.choice.format4->startingSymbolIndex;
+ }
+ return 0;
+}
+
+int get_ics_pucch(NR_PUCCH_Resource_t *pucch_resource, pucch_format_nr_t format_type)
+{
+ switch (format_type) {
+ case pucch_format0_nr:
+ return pucch_resource->format.choice.format0->initialCyclicShift;
+
+ case pucch_format1_nr:
+ return pucch_resource->format.choice.format1->initialCyclicShift;
+
+ default:
+ return -1;
+ }
+ return -1;
+}
+
+NR_PUCCH_Resource_t *select_resource_by_id(int resource_id, NR_PUCCH_Config_t *pucch_config)
+{
+ int n_list = pucch_config->resourceToAddModList->list.count;
+ NR_PUCCH_Resource_t *pucchres;
+ AssertFatal(n_list>0,"PUCCH resourceToAddModList is empty\n");
+
+ for (int i=0; iresourceToAddModList->list.array[i];
+ if (pucchres->pucch_ResourceId == resource_id)
+ return pucchres;
+ }
+ return NULL;
+}
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
index 85cd969e26..089fae9f55 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
@@ -41,6 +41,9 @@
/************** INCLUDE *******************************************/
#include "PHY/defs_nr_UE.h"
+#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
+#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h"
+#include "RRC/NR_UE/rrc_proto.h"
#ifdef DEFINE_VARIABLES_PUCCH_UE_NR_H
#define EXTERN
@@ -187,7 +190,7 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t
@param resource_id pucch resource id if any
@returns TRUE a pucch resource has been found FALSE no valid pucch resource */
-boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size, int pucch_resource_indicator,
+boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size, int pucch_resource_indicator,
int *initial_pucch_id, int *resource_set_id, int *resource_id, NR_UE_HARQ_STATUS_t *harq_status);
/** \brief This function select a pucch resource set
@@ -196,7 +199,7 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size
@param uci size number of uci bits
@returns number of the pucch resource set */
-int find_pucch_resource_set(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size);
+int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size);
/** \brief This function check pucch format
@param ue context
@@ -206,7 +209,7 @@ int find_pucch_resource_set(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size);
@param uci size number of uci bits
@returns TRUE pucch format matched uci size and constraints, FALSE invalid pucch format */
-boolean_t check_pucch_format(PHY_VARS_NR_UE *ue, uint8_t gNB_id, pucch_format_nr_t format_pucch, int nb_symbols_for_tx,
+boolean_t check_pucch_format(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, pucch_format_nr_t format_pucch, int nb_symbols_for_tx,
int uci_size);
/** \brief This function selects a pucch resource
@@ -232,4 +235,11 @@ int get_csi_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint32_t *csi_payload);
void set_csi_nr(int csi_status, uint32_t csi_payload);
+uint8_t get_nb_symbols_pucch(NR_PUCCH_Resource_t *pucch_resource, pucch_format_nr_t format_type);
+
+uint16_t get_starting_symb_idx(NR_PUCCH_Resource_t *pucch_resource, pucch_format_nr_t format_type);
+
+int get_ics_pucch(NR_PUCCH_Resource_t *pucch_resource, pucch_format_nr_t format_type);
+
+NR_PUCCH_Resource_t *select_resource_by_id(int resource_id, NR_PUCCH_Config_t *pucch_config);
#endif /* PUCCH_UCI_UE_NR_H */
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index 80b26c0bbd..9374050e58 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -40,7 +40,7 @@
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "SCHED_NR/sched_nr.h"
#include "openair1/SIMULATION/TOOLS/sim.h"
@@ -66,6 +66,8 @@ PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
+void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
+
int main(int argc, char **argv)
{
char c;
@@ -428,7 +430,7 @@ int main(int argc, char **argv)
uint8_t is_crnti = 0, llr8_flag = 0;
unsigned int TBS = 8424;
unsigned int available_bits;
- uint8_t nb_re_dmrs = 6;
+ uint8_t nb_re_dmrs = 6; // No data in dmrs symbol
uint16_t length_dmrs = 1;
unsigned char mod_order;
uint16_t rate;
@@ -442,7 +444,7 @@ int main(int argc, char **argv)
mod_order = nr_get_Qm_dl(Imcs, mcs_table);
rate = nr_get_code_rate_dl(Imcs, mcs_table);
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
- TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl);
+ TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl);
printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
//dlsch->harq_ids[subframe]= 0;
rel15->rbSize = nb_rb;
@@ -455,6 +457,7 @@ int main(int argc, char **argv)
rel15->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
rel15->dlDmrsSymbPos = 4;
rel15->mcsIndex[0] = Imcs;
+ rel15->numDmrsCdmGrpsNoData = 1;
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384);
short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384);
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 0b51901b05..137c358d7f 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -28,11 +28,9 @@
#include "common/ran_context.h"
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
-#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
-#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
-#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h"
-#include "openair2/LAYER2/NR_MAC_UE/mac_extern.h"
-#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
+#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
+#include "LAYER2/NR_MAC_UE/mac_defs.h"
+#include "LAYER2/NR_MAC_UE/mac_extern.h"
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
@@ -43,7 +41,7 @@
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "SCHED_NR/sched_nr.h"
@@ -55,7 +53,7 @@
#include "LAYER2/NR_MAC_UE/mac_proto.h"
//#include "LAYER2/NR_MAC_gNB/mac_proto.h"
//#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
-#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_asn_constant.h"
#include "RRC/NR/MESSAGES/asn1_msg.h"
#include "openair1/SIMULATION/RF/rf.h"
@@ -139,6 +137,12 @@ int main(int argc, char **argv)
int i,aa;//,l;
double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0;
uint8_t snr1set=0;
+ float roundStats[50];
+ float effRate;
+ //float psnr;
+ float eff_tp_check = 0.7;
+ uint8_t snrRun;
+ uint32_t TBS;
int **txdata;
double **s_re,**s_im,**r_re,**r_im;
//double iqim = 0.0;
@@ -154,6 +158,8 @@ int main(int argc, char **argv)
int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
//int n_errors2, n_alamouti;
uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
+ uint8_t round;
+ uint8_t num_rounds = 4;
channel_desc_t *gNB2UE;
//uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0;
@@ -205,7 +211,7 @@ int main(int argc, char **argv)
FILE *scg_fd=NULL;
- while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:e:m:")) != -1) {
+ while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:e:m:w")) != -1) {
switch (c) {
case 'f':
scg_fd = fopen(optarg,"r");
@@ -384,6 +390,14 @@ int main(int argc, char **argv)
mu = atoi(optarg);
break;
+ case 't':
+ eff_tp_check = (float)atoi(optarg)/100;
+ break;
+
+ case 'w':
+ output_fd = fopen("txdata.dat", "w+");
+ break;
+
default:
case 'h':
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n",
@@ -413,7 +427,9 @@ int main(int argc, char **argv)
printf("-c Start symbol for PDSCH (fixed for now)\n");
printf("-j Number of symbols for PDSCH (fixed for now)\n");
printf("-e MSC index\n");
+ printf("-t Acceptable effective throughput (in percentage)\n");
printf("-P Print DLSCH performances\n");
+ printf("-w Write txdata to binary file (one frame)\n");
exit (-1);
break;
}
@@ -658,7 +674,7 @@ int main(int argc, char **argv)
rrc.carrier.MIB = (uint8_t*) malloc(4);
rrc.carrier.sizeof_MIB = do_MIB_NR(&rrc,0);
- nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup->spCellConfig);
+ nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup);
nr_dcireq_t dcireq;
@@ -679,6 +695,9 @@ int main(int argc, char **argv)
nr_ue_phy_config_request(&UE_mac->phy_config);
+ NR_UE_list_t *UE_list = &RC.nrmac[0]->UE_list;
+ //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
+ snrRun = 0;
for (SNR = snr0; SNR < snr1; SNR += .2) {
@@ -696,6 +715,7 @@ int main(int argc, char **argv)
reset_meas(&gNB->toutput);
n_errors = 0;
+ effRate = 0;
//n_errors2 = 0;
//n_alamouti = 0;
errors_scrambling=0;
@@ -706,94 +726,6 @@ int main(int argc, char **argv)
//multipath channel
//multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0);
- memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
- clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
- if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&pucch_sched,&dlsch_config);
- else nr_schedule_css_dlsch_phytest(0,frame,slot);
-
-
- Sched_INFO.module_id = 0;
- Sched_INFO.CC_id = 0;
- Sched_INFO.frame = frame;
- Sched_INFO.slot = slot;
- Sched_INFO.DL_req = &gNB_mac->DL_req[0];
- Sched_INFO.UL_tti_req = &gNB_mac->UL_tti_req[0];
- Sched_INFO.UL_dci_req = NULL;
- Sched_INFO.TX_req = &gNB_mac->TX_req[0];
- nr_schedule_response(&Sched_INFO);
-
- if (run_initial_sync)
- nr_common_signal_procedures(gNB,frame,slot);
- else
- phy_procedures_gNB_TX(gNB,frame,slot,0);
-
- int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP;
-
- if (n_trials==1) {
- LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
- if (gNB->frame_parms.nb_antennas_tx>1)
- LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
- }
- int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
- if (n_trials==1) printf("samples_per_slot_wCP = %d\n", frame_parms->samples_per_slot_wCP);
-
- //TODO: loop over slots
- for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
-
- if (cyclic_prefix_type == 1) {
- PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
- &txdata[aa][tx_offset],
- frame_parms->ofdm_symbol_size,
- 12,
- frame_parms->nb_prefix_samples,
- CYCLIC_PREFIX);
- } else {
- nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
- &txdata[aa][tx_offset],
- 14,
- frame_parms);
- }
- }
-
- if (n_trials==1) {
- LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1);
- if (gNB->frame_parms.nb_antennas_tx>1)
- LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1);
- }
- if (output_fd)
- fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd);
-
- int txlev = signal_energy(&txdata[0][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
- frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
-
- // if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev));
-
- for (i=(frame_parms->get_samples_slot_timestamp(slot,frame_parms,0));
- i<(frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0));
- i++) {
- for (aa=0; aanb_antennas_tx; aa++) {
- r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
- r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
- }
- }
-
- NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0];
- nfapi_nr_dl_tti_pdsch_pdu_rel15_t rel15 = gNB_dlsch->harq_processes[0]->pdsch_pdu.pdsch_pdu_rel15;
-
- //AWGN
- sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15.rbSize))) - SNR;
- sigma2 = pow(10, sigma2_dB/10);
- if (n_trials==1) printf("sigma2 %f (%f dB), txlev %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15.rbSize));
-
- for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
- iget_samples_slot_timestamp(slot+1,frame_parms,0);
- i++) {
- for (aa=0; aanb_antennas_rx; aa++) {
- ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
- ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
- }
- }
-
UE->rx_offset=0;
UE_proc.frame_rx = frame;
UE_proc.nr_tti_rx= slot;
@@ -801,43 +733,147 @@ int main(int argc, char **argv)
dcireq.frame = frame;
dcireq.slot = slot;
+
+ NR_UE_DLSCH_t *dlsch0 = UE->dlsch[UE->current_thread_id[UE_proc.nr_tti_rx]][0][0];
+
+ int harq_pid = slot;
+ NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid];
+
+ NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0];
+ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_processes[slot]->pdsch_pdu.pdsch_pdu_rel15;
- nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
- nr_ue_scheduled_response(&scheduled_response);
+ UE_harq_process->harq_ack.ack = 0;
+ round = 0;
+ UE_harq_process->round = round;
+ UE_harq_process->first_tx = 1;
+
+ while ((roundharq_ack.ack==0)) {
+ memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
+ memset(RC.nrmac[0]->cce_list[1][1],0,MAX_NUM_CCE*sizeof(int));
+ clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
+
+ UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
+
+ UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
+ UE_list->UE_sched_ctrl[0].current_harq_pid = harq_pid;
+ gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round;
- phy_procedures_nrUE_RX(UE,
- &UE_proc,
- 0,
- do_pdcch_flag,
- normal_txrx);
-
- if (UE->dlsch[UE->current_thread_id[slot]][0][0]->last_iteration_cnt >=
- UE->dlsch[UE->current_thread_id[slot]][0][0]->max_ldpc_iterations+1)
- n_errors++;
+ if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&pucch_sched,&dlsch_config);
+ else nr_schedule_css_dlsch_phytest(0,frame,slot);
+ Sched_INFO.module_id = 0;
+ Sched_INFO.CC_id = 0;
+ Sched_INFO.frame = frame;
+ Sched_INFO.slot = slot;
+ Sched_INFO.DL_req = &gNB_mac->DL_req[0];
+ Sched_INFO.UL_tti_req = &gNB_mac->UL_tti_req[0];
+ Sched_INFO.UL_dci_req = NULL;
+ Sched_INFO.TX_req = &gNB_mac->TX_req[0];
+ nr_schedule_response(&Sched_INFO);
+
+ if (run_initial_sync)
+ nr_common_signal_procedures(gNB,frame,slot);
+ else
+ phy_procedures_gNB_TX(gNB,frame,slot,0);
+
+ int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP;
+
+ if (n_trials==1) {
+ LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
+ if (gNB->frame_parms.nb_antennas_tx>1)
+ LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
+ }
+ int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
+ if (n_trials==1) printf("samples_per_slot_wCP = %d\n", frame_parms->samples_per_slot_wCP);
+
+ //TODO: loop over slots
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
+
+ if (cyclic_prefix_type == 1) {
+ PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
+ &txdata[aa][tx_offset],
+ frame_parms->ofdm_symbol_size,
+ 12,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
+ } else {
+ nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
+ &txdata[aa][tx_offset],
+ 14,
+ frame_parms);
+ }
+ }
+
+ if (n_trials==1) {
+ LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1);
+ if (gNB->frame_parms.nb_antennas_tx>1)
+ LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1);
+ }
+ if (output_fd) {
+ printf("writing txdata to binary file\n");
+ fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd);
+ }
+
+ int txlev = signal_energy(&txdata[0][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
+
+ // if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev));
+
+ for (i=(frame_parms->get_samples_slot_timestamp(slot,frame_parms,0));
+ i<(frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0));
+ i++) {
+
+ for (aa=0; aanb_antennas_tx; aa++) {
+ r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
+ r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
+ }
+ }
+
+ //AWGN
+ sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR;
+ sigma2 = pow(10, sigma2_dB/10);
+ if (n_trials==1) printf("sigma2 %f (%f dB), txlev %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize));
+
+ for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
+ iget_samples_slot_timestamp(slot+1,frame_parms,0);
+ i++) {
+
+ for (aa=0; aanb_antennas_rx; aa++) {
+ ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
+ ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
+ }
+ }
+
+ nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
+ nr_ue_scheduled_response(&scheduled_response);
+
+ phy_procedures_nrUE_RX(UE,
+ &UE_proc,
+ 0,
+ do_pdcch_flag,
+ normal_txrx);
+
+ //printf("dlsim round %d ends\n",round);
+ round++;
+ } // round
//----------------------------------------------------------
//---------------------- count errors ----------------------
//----------------------------------------------------------
-
-
- NR_UE_DLSCH_t *dlsch0 = UE->dlsch[UE->current_thread_id[UE_proc.nr_tti_rx]][0][0];
-
- int harq_pid = dlsch0->current_harq_pid;
- NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid];
-
+ if (UE->dlsch[UE->current_thread_id[slot]][0][0]->last_iteration_cnt >=
+ UE->dlsch[UE->current_thread_id[slot]][0][0]->max_ldpc_iterations+1)
+ n_errors++;
+
NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]];
int16_t *UE_llr = pdsch_vars[0]->llr[0];
-
- uint32_t TBS = rel15.TBSize[0];
+ TBS = UE_harq_process->TBS;//rel15->TBSize[0];
uint16_t length_dmrs = 1;
- uint16_t nb_rb = rel15.rbSize;
- uint8_t nb_re_dmrs = rel15.dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
- uint8_t mod_order = rel15.qamModOrder[0];
- uint8_t nb_symb_sch = rel15.NrOfSymbols;
+ uint16_t nb_rb = rel15->rbSize;
+ uint8_t nb_re_dmrs = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
+ uint8_t mod_order = rel15->qamModOrder[0];
+ uint8_t nb_symb_sch = rel15->NrOfSymbols;
- available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15.nrOfLayers);
+ available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers);
for (i = 0; i < available_bits; i++) {
@@ -877,15 +913,18 @@ int main(int argc, char **argv)
if (n_trials == 1)
printf("errors_bit = %u (trial %d)\n", errors_bit, trial);
}
-
+ roundStats[snrRun]+=((float)round);
+ if (UE_harq_process->harq_ack.ack==1) effRate += ((float)TBS)/round;
} // noise trials
+ roundStats[snrRun]/=((float)n_trials);
+ effRate /= n_trials;
printf("*****************************************\n");
printf("SNR %f, (false positive %f)\n", SNR,
(float) n_errors / (float) n_trials);
printf("*****************************************\n");
printf("\n");
- printf("SNR %f : n_errors (negative CRC) = %d/%d, Channel BER %e\n", SNR, n_errors, n_trials,(double)errors_scrambling/available_bits/n_trials);
+ printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %d bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS);
printf("\n");
if (n_trials == 1) {
@@ -898,7 +937,8 @@ int main(int argc, char **argv)
break;
}
- if ((float)n_errors/(float)n_trials <= target_error_rate) {
+ //if ((float)n_errors/(float)n_trials <= target_error_rate) {
+ if (effRate >= (eff_tp_check*TBS)) {
printf("PDSCH test OK\n");
break;
}
@@ -953,8 +993,18 @@ int main(int argc, char **argv)
printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC");
*/
}
+ snrRun++;
} // NSR
+ /*if (n_trials>1) {
+ printf("HARQ stats:\nSNR\tRounds\n");
+ psnr = snr0;
+ for (uint8_t i=0; iphysCellId=0; \
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 9d14391f71..2144652f86 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -37,7 +37,7 @@
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include "PHY/phy_vars.h"
@@ -62,6 +62,8 @@ uint16_t NB_UE_INST = 1;
openair0_config_t openair0_cfg[MAX_CARDS];
uint64_t get_softmodem_optmask(void) {return 0;}
+void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
+
void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
int N_RB_DL,
int N_RB_UL,
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index 2ad89ce897..2db5bc905c 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
@@ -35,115 +36,91 @@
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR_UE/phy_frame_config_nr.h"
#include "PHY/phy_vars_nr_ue.h"
-
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
+#include "nr_unitary_defs.h"
#include "OCG_vars.h"
-#include
+#define NR_PRACH_DEBUG 1
+#define PRACH_WRITE_OUTPUT_DEBUG 1
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
RU_t *ru;
-
double cpuf;
-
extern uint16_t prach_root_sequence_map0_3[838];
-
-void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
-
uint16_t NB_UE_INST=1;
-volatile int oai_exit=0;
-
-void exit_function(const char* file, const char* function, const int line,const char *s) {
- const char * msg= s==NULL ? "no comment": s;
- printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
- exit(-1);
-}
-
-
-int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe) {
- AssertFatal(1==0,"Shouldn't be here ...\n");
- return 0;
-}
-
-uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
- sub_frame_t subframe, uint8_t eNB_index,
- uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) {return(0);}
-
-int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);}
-
openair0_config_t openair0_cfg[MAX_CARDS];
uint8_t nfapi_mode=0;
-NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);}
-int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
+int sl_ahead = 0;
-uint64_t get_softmodem_optmask(void) {
- return 0;
-}
+//void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
-int main(int argc, char **argv)
-{
+/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
+uint64_t get_softmodem_optmask(void) {return 0;}
+softmodem_params_t *get_softmodem_params(void) {return 0;}
+
+void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
+
+boolean_t pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
+ const srb_flag_t srb_flagP,
+ const MBMS_flag_t MBMS_flagP,
+ const rb_id_t rb_idP,
+ const sdu_size_t sdu_buffer_sizeP,
+ mem_block_t *const sdu_buffer_pP) {return(false);}
+
+void nr_ip_over_LTE_DRB_preconfiguration(void){}
+void pdcp_layer_init(void) {}
+int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
+
+int main(int argc, char **argv){
char c;
- int i,aa,aarx;
- double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1=0.0,ue_speed0=0.0,ue_speed1=0.0;
- uint8_t snr1set=0;
- uint8_t ue_speed1set=0;
- int **txdata;
- double **s_re,**s_im,**r_re,**r_im;
- double iqim=0.0;
- int trial; //, ntrials=1;
- uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
- uint16_t Nid_cell=0;
+ double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0;
+ double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs, bw;
+ int i, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1;
+ int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0;
+ uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0;
+ uint8_t frame = 1, subframe = 9, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, num_root_sequences = 16, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol;
+ uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1;
+ uint32_t tx_lev = 10000, prach_errors = 0, samp_count; //,tx_lev_dB;
+ uint64_t SSB_positions = 0x01, absoluteFrequencyPointA = 640000;
- uint8_t awgn_flag=0;
- uint8_t hs_flag=0;
- int n_frames=1;
- channel_desc_t *UE2gNB;
- uint32_t tx_lev=0; //,tx_lev_dB;
// int8_t interf1=-19,interf2=-19;
- NR_DL_FRAME_PARMS *frame_parms;
-
- SCM_t channel_model=Rayleigh1;
-
// uint8_t abstraction_flag=0,calibration_flag=0;
// double prach_sinr;
- int N_RB_UL=273;
- uint32_t prach_errors=0;
- uint8_t subframe=9;
- uint16_t preamble_energy_list[64],preamble_tx=50,preamble_delay_list[64];
- PRACH_RESOURCES_t prach_resources;
- //uint8_t prach_fmt;
- //int N_ZC;
- int delay = 0;
- double delay_avg=0;
- double ue_speed = 0;
- int NCS_config = 13,rootSequenceIndex=0;
- int threequarter_fs = 0;
- int mu=1;
- uint64_t SSB_positions=0x01;
+ // uint32_t nsymb;
+ // uint16_t preamble_max, preamble_energy_max;
+ FILE *input_fd=NULL;
+ char* input_file=NULL;
+ int n_bytes=0;
- int loglvl=OAILOG_INFO;
+ NR_DL_FRAME_PARMS *frame_parms;
+ NR_PRACH_RESOURCES_t prach_resources;
+ nfapi_nr_prach_config_t *prach_config;
+ nfapi_nr_prach_pdu_t *prach_pdu;
+ fapi_nr_prach_config_t *ue_prach_config;
+ fapi_nr_ul_config_prach_pdu *ue_prach_pdu;
+ channel_desc_t *UE2gNB;
+ SCM_t channel_model = Rayleigh1;
cpuf = get_cpu_freq_GHz();
-
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
randominit(0);
-
- while ((c = getopt (argc, argv, "hHaA:Cr:p:g:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
+ while ((c = getopt (argc, argv, "hHaA:Cc:r:p:g:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
switch (c) {
case 'a':
printf("Running AWGN simulation\n");
@@ -152,6 +129,14 @@ int main(int argc, char **argv)
//ntrials=1;
break;
+ case 'c':
+ config_index = atoi(optarg);
+ break;
+
+ case 'r':
+ msg1_frequencystart = atoi(optarg);
+ break;
+
case 'd':
delay = atoi(optarg);
break;
@@ -215,7 +200,7 @@ int main(int argc, char **argv)
break;
default:
- msg("Unsupported channel model!\n");
+ printf("Unsupported channel model!\n");
exit(-1);
}
@@ -231,13 +216,13 @@ int main(int argc, char **argv)
case 's':
snr0 = atof(optarg);
- msg("Setting SNR0 to %f\n",snr0);
+ printf("Setting SNR0 to %f\n",snr0);
break;
case 'S':
snr1 = atof(optarg);
snr1set=1;
- msg("Setting SNR1 to %f\n",snr1);
+ printf("Setting SNR1 to %f\n",snr1);
break;
case 'p':
@@ -263,7 +248,7 @@ int main(int argc, char **argv)
case 'H':
printf("High-Speed Flag enabled\n");
- hs_flag = 1;
+ restrictedSetConfig = 1;
break;
case 'L':
@@ -280,7 +265,7 @@ int main(int argc, char **argv)
if ((transmission_mode!=1) &&
(transmission_mode!=2) &&
(transmission_mode!=6)) {
- msg("Unsupported transmission mode %d\n",transmission_mode);
+ printf("Unsupported transmission mode %d\n",transmission_mode);
exit(-1);
}
@@ -290,7 +275,7 @@ int main(int argc, char **argv)
n_tx=atoi(optarg);
if ((n_tx==0) || (n_tx>2)) {
- msg("Unsupported number of tx antennas %d\n",n_tx);
+ printf("Unsupported number of tx antennas %d\n",n_tx);
exit(-1);
}
@@ -300,7 +285,7 @@ int main(int argc, char **argv)
n_rx=atoi(optarg);
if ((n_rx==0) || (n_rx>2)) {
- msg("Unsupported number of rx antennas %d\n",n_rx);
+ printf("Unsupported number of rx antennas %d\n",n_rx);
exit(-1);
}
@@ -315,6 +300,14 @@ int main(int argc, char **argv)
break;
case 'F':
+ input_fd = fopen(optarg,"r");
+ input_file = optarg;
+
+ if (input_fd==NULL) {
+ printf("Problem with filename %s\n",optarg);
+ exit(-1);
+ }
+
break;
default:
@@ -344,20 +337,20 @@ int main(int argc, char **argv)
}
}
- logInit();
+
+ if (config_index<67) { prach_sequence_length=0; slot = subframe*2; slot_gNB = 1+(subframe*2); }
+ uint16_t N_ZC;
+ N_ZC = prach_sequence_length == 0 ? 839 : 139;
+ printf("Config_index %d, prach_sequence_length %d\n",config_index,prach_sequence_length);
+
+ // Configure log
+ logInit();
set_glog(loglvl);
T_stdout = 1;
-
SET_LOG_DEBUG(PRACH);
- if (snr1set==0) {
- if (n_frames==1)
- snr1 = snr0+.1;
- else
- snr1 = snr0+5.0;
- }
-
+ // Configure gNB and RU
RC.gNB = (PHY_VARS_gNB**) malloc(2*sizeof(PHY_VARS_gNB *));
RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB));
memset(RC.gNB[0],0,sizeof(PHY_VARS_gNB));
@@ -367,90 +360,204 @@ int main(int argc, char **argv)
memset(RC.ru[0],0,sizeof(RU_t));
RC.nb_RU = 1;
- gNB = RC.gNB[0];
- ru = RC.ru[0];
-
-
- if (ue_speed1set==0) {
- if (n_frames==1)
- ue_speed1 = ue_speed0+10;
- else
- ue_speed1 = ue_speed0+50;
- }
-
- printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
-
- frame_parms = &gNB->frame_parms;
-
-
+ gNB = RC.gNB[0];
+ ru = RC.ru[0];
+ frame_parms = &gNB->frame_parms;
+ prach_config = &gNB->gNB_config.prach_config;
+ prach_pdu = &gNB->prach_vars.list[0].pdu;
+ frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
s_re = malloc(2*sizeof(double*));
s_im = malloc(2*sizeof(double*));
r_re = malloc(2*sizeof(double*));
r_im = malloc(2*sizeof(double*));
- frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
- frame_parms->nb_antennas_tx = n_tx;
- frame_parms->nb_antennas_rx = n_rx;
- frame_parms->N_RB_DL = N_RB_UL;
- frame_parms->N_RB_UL = N_RB_UL;
- frame_parms->threequarter_fs = threequarter_fs;
+ frame_parms->nb_antennas_tx = n_tx;
+ frame_parms->nb_antennas_rx = n_rx;
+ frame_parms->N_RB_DL = N_RB_UL;
+ frame_parms->N_RB_UL = N_RB_UL;
+ frame_parms->threequarter_fs = threequarter_fs;
+ frame_parms->frame_type = TDD;
+ frame_parms->freq_range = nr_FR1;
+ frame_parms->numerology_index = mu;
-
- nr_phy_config_request_sim(gNB,N_RB_UL,N_RB_UL,mu,Nid_cell,SSB_positions);
-
- frame_parms->frame_type = TDD;
- frame_parms->freq_range = nr_FR1;
+ nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
//nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
- printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d,Frame type %s, Frequency Range %s\n",NUMBER_OF_OFDM_CARRIERS,
- frame_parms->Ncp,frame_parms->samples_per_subframe,frame_parms->frame_type == FDD ? "FDD" : "TDD", frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2");
+ printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Frame type %s, Frequency Range %s\n",
+ NUMBER_OF_OFDM_CARRIERS,
+ frame_parms->Ncp,
+ frame_parms->samples_per_subframe,
+ frame_parms->frame_type == FDD ? "FDD" : "TDD",
+ frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2");
- ru->nr_frame_parms=frame_parms;
- ru->if_south = LOCAL_RF;
- ru->nb_tx = n_tx;
- ru->nb_rx = n_rx;
+ ru->nr_frame_parms = frame_parms;
+ ru->if_south = LOCAL_RF;
+ ru->nb_tx = n_tx;
+ ru->nb_rx = n_rx;
+ gNB->gNB_config.carrier_config.num_tx_ant.value = 1;
+ gNB->gNB_config.carrier_config.num_rx_ant.value = 1;
+ gNB->gNB_config.tdd_table.tdd_period.value = 6;
+
+ gNB->gNB_config.prach_config.num_prach_fd_occasions.value = num_prach_fd_occasions;
+ gNB->gNB_config.prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(num_prach_fd_occasions*sizeof(nfapi_nr_num_prach_fd_occasions_t));
+
+ gNB->proc.slot_rx = slot;
+
+ int ret = get_nr_prach_info_from_index(config_index,
+ (int)frame,
+ (int)slot_gNB,
+ absoluteFrequencyPointA,
+ mu,
+ frame_parms->frame_type,
+ &format,
+ &start_symbol,
+ &N_t_slot,
+ &N_dur);
+
+ if (ret == 0) {printf("No prach in %d.%d, mu %d, config_index %d\n",frame,slot,mu,config_index); exit(-1);}
+ format0 = format&0xff; // first column of format from table
+ format1 = (format>>8)&0xff; // second column of format from table
+
+ if (format1 != 0xff) {
+ switch(format0) {
+ case 0xa1:
+ prach_format = 9;
+ break;
+ case 0xa2:
+ prach_format = 10;
+ break;
+ case 0xa3:
+ prach_format = 11;
+ break;
+ default:
+ AssertFatal(1==0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
+ }
+ } else {
+ switch(format0) {
+ case 0xa1:
+ prach_format = 0;
+ break;
+ case 0xa2:
+ prach_format = 1;
+ break;
+ case 0xa3:
+ prach_format = 2;
+ break;
+ case 0xb1:
+ prach_format = 3;
+ break;
+ case 0xb2:
+ prach_format = 4;
+ break;
+ case 0xb3:
+ prach_format = 5;
+ break;
+ case 0xb4:
+ prach_format = 6;
+ break;
+ case 0xc0:
+ prach_format = 7;
+ break;
+ case 0xc2:
+ prach_format = 8;
+ break;
+ case 0:
+ // long formats are handled @ PHY
+ break;
+ case 1:
+ // long formats are handled @ PHY
+ break;
+ case 2:
+ // long formats are handled @ PHY
+ break;
+ case 3:
+ // long formats are handled @ PHY
+ break;
+ default:
+ AssertFatal(1==0, "Invalid PRACH format");
+ }
+ }
+
+ printf("PRACH format %d\n",prach_format);
+
+ prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value = rootSequenceIndex;
+ prach_config->num_prach_fd_occasions_list[fd_occasion].k1.value = msg1_frequencystart;
+ prach_config->restricted_set_config.value = restrictedSetConfig;
+ prach_config->prach_sequence_length.value = prach_sequence_length;
+ prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig);
+ prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value = 1+(64/(N_ZC/prach_pdu->num_cs));
+ prach_pdu->prach_format = prach_format;
+
+ memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
RC.nb_nr_L1_inst=1;
phy_init_nr_gNB(gNB,0,0);
nr_phy_init_RU(ru);
- set_tdd_config_nr(&gNB->gNB_config, 5000,
- 7, 6,
- 2, 4);
+ gNB->common_vars.rxdata = ru->common.rxdata;
+ set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
- //configure UE
+ // Configure UE
UE = malloc(sizeof(PHY_VARS_NR_UE));
memset((void*)UE,0,sizeof(PHY_VARS_NR_UE));
PHY_vars_UE_g = malloc(2*sizeof(PHY_VARS_NR_UE**));
PHY_vars_UE_g[0] = malloc(2*sizeof(PHY_VARS_NR_UE*));
PHY_vars_UE_g[0][0] = UE;
memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
- if (init_nr_ue_signal(UE, 1, 0) != 0)
- {
+ UE->nrUE_config.prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t));
+
+ if (init_nr_ue_signal(UE, 1, 0) != 0){
printf("Error at UE NR initialisation\n");
exit(-1);
}
- txdata = UE->common_vars.txdata;
- printf("txdata %p\n",&txdata[0][subframe*frame_parms->samples_per_subframe]);
+ ue_prach_pdu = &UE->prach_vars[0]->prach_pdu;
+ ue_prach_config = &UE->nrUE_config.prach_config;
+ UE->prach_resources[0] = &prach_resources;
+ txdata = UE->common_vars.txdata;
- double fs,bw;
+ UE->prach_vars[0]->amp = AMP;
+ ue_prach_pdu->root_seq_id = rootSequenceIndex;
+ ue_prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig);
+ ue_prach_pdu->restricted_set = restrictedSetConfig;
+ ue_prach_pdu->freq_msg1 = msg1_frequencystart;
+ ue_prach_pdu->prach_format = prach_format;
+ ue_prach_config->prach_sub_c_spacing = mu;
+ ue_prach_config->prach_sequence_length = prach_sequence_length;
+ ue_prach_config->restricted_set_config = restrictedSetConfig;
+ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences = prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value ;
+ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index = rootSequenceIndex;
+ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].k1 = msg1_frequencystart;
+
+ if (preamble_tx == 99)
+ preamble_tx = (uint16_t)(taus()&0x3f);
+
+ if (n_frames == 1)
+ printf("raPreamble %d\n",preamble_tx);
+
+ UE->prach_resources[0]->ra_PreambleIndex = preamble_tx;
+ UE->prach_resources[0]->init_msg1 = 1;
+
+ // Configure channel
+ bw = N_RB_UL*(180e3)*(1 << frame_parms->numerology_index);
+ AssertFatal(bw<=122.88e6,"Illegal channel bandwidth %f (mu %d,N_RB_UL %d)\n", bw, frame_parms->numerology_index, N_RB_UL);
+
+ if (bw <= 30.72e6)
+ fs = 30.72e6;
+ else if (bw <= 61.44e6)
+ fs = 61.44e6;
+ else if (bw <= 122.88e6)
+ fs = 122.88e6;
- bw = N_RB_UL*(180e3)*(1<frame_parms.numerology_index);
- AssertFatal(bw<=122.88e6,"Illegal channel bandwidth %f (mu %d,N_RB_UL %d)\n",bw, gNB->frame_parms.numerology_index,N_RB_UL);
- if (bw <= 30.72e6) fs = 30.72e6;
- else if (bw <= 61.44e6) fs = 61.44e6;
- else if (bw <= 122.88e6) fs = 122.88e6;
LOG_I(PHY,"Running with bandwidth %f Hz, fs %f samp/s, FRAME_LENGTH_COMPLEX_SAMPLES %d\n",bw,fs,FRAME_LENGTH_COMPLEX_SAMPLES);
-
UE2gNB = new_channel_desc_scm(UE->frame_parms.nb_antennas_tx,
gNB->frame_parms.nb_antennas_rx,
channel_model,
- fs,
- bw,
+ fs,
+ bw,
0.0,
delay,
0);
@@ -473,97 +580,80 @@ int main(int argc, char **argv)
bzero(r_im[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
}
- UE->frame_parms.prach_config_common.rootSequenceIndex=rootSequenceIndex;
- UE->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex=98;
- UE->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=NCS_config;
- UE->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag=hs_flag;
- UE->frame_parms.prach_config_common.prach_ConfigInfo.restrictedSetConfig=0;
- UE->frame_parms.prach_config_common.prach_ConfigInfo.msg1_frequencystart=0;
+ // compute PRACH sequence
+ compute_nr_prach_seq(prach_config->prach_sequence_length.value,
+ prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value,
+ prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value,
+ gNB->X_u);
-
- gNB->frame_parms.prach_config_common.rootSequenceIndex=rootSequenceIndex;
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex=98;
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=NCS_config;
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag=hs_flag;
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.restrictedSetConfig=0;
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.msg1_frequencystart=0;
-
- gNB->proc.slot_rx = subframe<<1;
-
- gNB->common_vars.rxdata = ru->common.rxdata;
-
-
- compute_nr_prach_seq(gNB->frame_parms.prach_config_common.rootSequenceIndex,
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,
- gNB->frame_parms.frame_type,
- gNB->frame_parms.freq_range,
- gNB->X_u);
-
- compute_nr_prach_seq(UE->frame_parms.prach_config_common.rootSequenceIndex,
- UE->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
- UE->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
- UE->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,
- UE->frame_parms.frame_type,
- UE->frame_parms.freq_range,
- UE->X_u);
-
-
-
- UE->prach_vars[0]->amp = AMP;
-
- UE->prach_resources[0] = &prach_resources;
-
- if (preamble_tx == 99)
- preamble_tx = (uint16_t)(taus()&0x3f);
-
- if (n_frames == 1)
- printf("raPreamble %d\n",preamble_tx);
-
- UE->prach_resources[0]->ra_PreambleIndex = preamble_tx;
- UE->prach_resources[0]->ra_TDD_map_index = 0;
+ compute_nr_prach_seq(ue_prach_config->prach_sequence_length,
+ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences,
+ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
+ UE->X_u);
/*tx_lev = generate_nr_prach(UE,
0, //gNB_id,
- subframe,
- 0); //Nf */ //commented for testing purpose
+ subframe); */ //commented for testing purpose
UE_nr_rxtx_proc_t proc={0};
- nr_ue_prach_procedures(UE,&proc,0,0,0);
-
+ proc.frame_tx = frame;
+ proc.nr_tti_tx = slot;
+ nr_ue_prach_procedures(UE,&proc,0,0);
/* tx_lev_dB not used later, no need to set */
//tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
- LOG_M("txsig0.m","txs0", &txdata[0][subframe*frame_parms->samples_per_subframe],frame_parms->samples_per_subframe,1,1);
- //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1);
+ prach_start = subframe*frame_parms->samples_per_subframe-UE->N_TA_offset;
+
+ #ifdef NR_PRACH_DEBUG
+ LOG_M("txsig0.m", "txs0", &txdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
+ LOG_M("txsig0_frame.m","txs0", txdata[0],frame_parms->samples_per_frame,1,1);
+ #endif
// multipath channel
- dump_nr_prach_config(&gNB->frame_parms,subframe);
+ // dump_nr_prach_config(&gNB->frame_parms,subframe);
- for (i=0; i<2*frame_parms->samples_per_subframe; i++) {
+ for (i = 0; i < frame_parms->samples_per_subframe<<1; i++) {
for (aa=0; aa<1; aa++) {
if (awgn_flag == 0) {
- s_re[aa][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]);
- s_im[aa][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]);
+ s_re[aa][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]);
+ s_im[aa][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]);
} else {
for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
if (aa==0) {
- r_re[aarx][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]);
- r_im[aarx][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]);
+ r_re[aarx][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]);
+ r_im[aarx][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]);
} else {
- r_re[aarx][i] += ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]);
- r_im[aarx][i] += ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]);
+ r_re[aarx][i] += ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]);
+ r_im[aarx][i] += ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]);
}
}
}
}
}
+ if (snr1set == 0) {
+ if (n_frames == 1)
+ snr1 = snr0 + .1;
+ else
+ snr1 = snr0 + 5.0;
+ }
+
+ printf("SNR0 %f, SNR1 %f\n", snr0, snr1);
+
+ if (ue_speed1set == 0) {
+ if (n_frames == 1)
+ ue_speed1 = ue_speed0 + 10;
+ else
+ ue_speed1 = ue_speed0 + 50;
+ }
+
+ rx_prach_start = subframe*frame_parms->samples_per_subframe;
+ if (n_frames==1) printf("slot %d, rx_prach_start %d\n",slot,rx_prach_start);
+ uint16_t preamble_rx, preamble_energy;
- for (SNR=snr0; SNRsamples_per_subframe,0);
+ multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_tti<<1, 0);
}
if (n_frames==1) {
@@ -594,55 +683,66 @@ int main(int argc, char **argv)
10*log10(tx_lev));
}
- for (i=0; isamples_per_subframe; i++) {
- for (aa=0; aaframe_parms.nb_antennas_rx; aa++) {
-
- ((short*) &gNB->common_vars.rxdata[aa][subframe*(frame_parms->samples_per_subframe)])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
- ((short*) &gNB->common_vars.rxdata[aa][subframe*(frame_parms->samples_per_subframe)])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
+ for (i = 0; i< frame_parms->samples_per_subframe; i++) {
+ for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
+ ((short*) &ru->common.rxdata[aa][rx_prach_start])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
+ ((short*) &ru->common.rxdata[aa][rx_prach_start])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
}
}
- uint16_t preamble_rx;
- rx_nr_prach_ru(ru,
- 0,
- subframe);
- gNB->prach_vars.rxsigF = ru->prach_rxsigF;
+ } else {
+ n_bytes = fread(&ru->common.rxdata[0][rx_prach_start],sizeof(int32_t),frame_parms->samples_per_subframe,input_fd);
+ printf("fread %d bytes from file %s\n",n_bytes,input_file);
+ if (n_bytes!=frame_parms->samples_per_subframe) {
+ printf("expected %d bytes\n",frame_parms->samples_per_subframe);
+ exit(-1);
+ }
+ }
- rx_nr_prach(gNB,
- 0,
- subframe,
- &preamble_rx,
- preamble_energy_list,
- preamble_delay_list);
-
- if (preamble_rx!=preamble_tx)
+
+ rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, frame, slot);
+
+ gNB->prach_vars.rxsigF = ru->prach_rxsigF;
+ if (n_frames == 1) printf("ncs %d,num_seq %d\n",prach_pdu->num_cs, prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value);
+ rx_nr_prach(gNB, prach_pdu, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay);
+
+ // printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx);
+
+ if (preamble_rx != preamble_tx)
prach_errors++;
- else {
- delay_avg += (double)preamble_delay_list[preamble_tx];
- }
+ else
+ delay_avg += (double)preamble_delay;
+
+ N_ZC = (prach_sequence_length) ? 139 : 839;
if (n_frames==1) {
- printf("preamble %d (tx %d) : energy %d, delay %d\n",preamble_rx,preamble_tx,preamble_energy_list[0],preamble_delay_list[0]);
-
-
- LOG_M("prach0.m","prach0", &txdata[0][subframe*frame_parms->samples_per_subframe],frame_parms->samples_per_subframe,1,1);
- LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0],24576,1,1);
- LOG_M("rxsig0.m","rxs0",
- &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_subframe],
- frame_parms->samples_per_subframe,1,1);
- LOG_M("rxsigF0.m","rxsF0", gNB->prach_vars.rxsigF[0],839*4,1,1);
- LOG_M("prach_preamble.m","prachp",&gNB->X_u[0],839,1,1);
+ printf("preamble %d (tx %d) : energy %d, delay %d\n",preamble_rx,preamble_tx,preamble_energy,preamble_delay);
+ #ifdef NR_PRACH_DEBUG
+ LOG_M("prach0.m","prach0", &txdata[0][prach_start], frame_parms->samples_per_subframe, 1, 1);
+ LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0], N_ZC, 1, 1);
+ LOG_M("rxsig0.m","rxs0", &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
+ LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
+ LOG_M("rxsigF0.m","rxsF0", gNB->prach_vars.rxsigF[0], N_ZC, 1, 1);
+ LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1);
+ LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1);
+ #endif
}
}
- printf("SNR %f dB, UE Speed %f km/h: errors %u/%d (delay %f)\n",SNR,ue_speed,prach_errors,n_frames,delay_avg/(double)(n_frames-prach_errors));
- //printf("(%f,%f)\n",ue_speed,(double)prach_errors/(double)n_frames);
+ printf("SNR %f dB, UE Speed %f km/h: errors %d/%d (delay %f)\n", SNR, ue_speed, prach_errors, n_frames, delay_avg/(double)(n_frames-prach_errors));
+ if (input_fd)
+ break;
+ if (prach_errors)
+ break;
+
} // UE Speed loop
-
- //printf("SNR %f dB, UE Speed %f km/h: errors %d/%d (delay %f)\n",SNR,ue_speed,prach_errors,n_frames,delay_avg/(double)(n_frames-prach_errors));
- // printf("(%f,%f)\n",SNR,(double)prach_errors/(double)n_frames);
+ if (!prach_errors) {
+ printf("PRACH test OK\n");
+ break;
+ }
+ if (input_fd)
+ break;
} //SNR loop
-
for (i=0; i<2; i++) {
free(s_re[i]);
free(s_im[i]);
@@ -655,17 +755,7 @@ int main(int argc, char **argv)
free(r_re);
free(r_im);
+ if (input_fd) fclose(input_fd);
return(0);
-
}
-
-
-
-/*
- for (i=1;i<4;i++)
- memcpy((void *)&PHY_vars->tx_vars[0].TX_DMA_BUFFER[i*12*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX*2],
- (void *)&PHY_vars->tx_vars[0].TX_DMA_BUFFER[0],
- 12*OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX*2);
-*/
-
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index a754df4763..004a7b8de8 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -37,7 +37,7 @@
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
#include "SCHED_NR/sched_nr.h"
@@ -59,6 +59,8 @@ uint16_t NB_UE_INST = 1;
// needed for some functions
PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={{NULL}};
+void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
+
int main(int argc, char **argv)
{
char c;
@@ -84,7 +86,7 @@ int main(int argc, char **argv)
int format=0;
//uint8_t extended_prefix_flag=0;
FILE *input_fd=NULL;
- uint8_t nacktoack_flag=0;
+ //uint8_t nacktoack_flag=0;
int16_t amp=0x7FFF;
int nr_tti_tx=0;
uint64_t actual_payload=0,payload_received;
@@ -283,7 +285,7 @@ int main(int argc, char **argv)
actual_payload=atoi(optarg);
break;
case 'T':
- nacktoack_flag=(uint8_t)atoi(optarg);
+ //nacktoack_flag=(uint8_t)atoi(optarg);
target_error_rate=0.001;
break;
default:
@@ -336,7 +338,7 @@ int main(int argc, char **argv)
}
AssertFatal(((format < 2)&&(nr_bit<3)&&(actual_payload<4)) ||
- ((format == 2)&&(nr_bit>2)&&(nr_bit<12)),"illegal combination format %d, nr_bit %d\n",
+ ((format == 2)&&(nr_bit>2)&&(nr_bit<65)),"illegal combination format %d, nr_bit %d\n",
format,nr_bit);
actual_payload &= ((1<pucch_config_common_nr->pucch_GroupHopping;
uint32_t hopping_id=UE->pucch_config_common_nr->hoppingId;
uint32_t dmrs_scrambling_id = 0, data_scrambling_id=0;
+ //t_nrPolar_params *currentPtr;
+
if(format==0){
// for now we are not considering SR just HARQ-ACK
if (nr_bit ==0)
@@ -467,14 +471,15 @@ int main(int argc, char **argv)
mcs=table2_mcs[actual_payload];
else AssertFatal(1==0,"Either nr_bit %d or sr_flag %d must be non-zero\n", nr_bit, sr_flag);
}
-
+ else if (format == 2 && nr_bit > 11) gNB->uci_polarParams = nr_polar_params(2, nr_bit, nrofPRB, 1, NULL);
+
for(SNR=snr0;SNR<=snr1;SNR=SNR+1){
ack_nack_errors=0;
n_errors = 0;
for (trial=0; trialofdm_symbol_size*sizeof(int));
if(format==0){
- nr_generate_pucch0(UE,txdataF,frame_parms,UE->pucch_config_dedicated,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB);
+ nr_generate_pucch0(UE,txdataF,frame_parms,PUCCH_GroupHopping,hopping_id,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB);
}
else if (format == 1){
nr_generate_pucch1(UE,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit);
@@ -498,7 +503,7 @@ int main(int argc, char **argv)
}
int rxlev = signal_energy(&rxdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size);
- // printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12));
+ if (n_trials==1) printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12));
if(format==0){
nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu;
nfapi_nr_pucch_pdu_t pucch_pdu;
@@ -506,6 +511,8 @@ int main(int argc, char **argv)
pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1;
pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1;
pucch_pdu.bit_len_harq = nr_bit;
+ pucch_pdu.bit_len_csi_part1 = 0;
+ pucch_pdu.bit_len_csi_part2 = 0;
pucch_pdu.sr_flag = sr_flag;
pucch_pdu.nr_of_symbols = nrofSymbols;
pucch_pdu.hopping_id = hopping_id;
@@ -534,7 +541,9 @@ int main(int argc, char **argv)
pucch_pdu.subcarrier_spacing = 1;
pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1;
pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1;
- pucch_pdu.bit_len_harq = nr_bit;
+ pucch_pdu.bit_len_csi_part1 = nr_bit;
+ pucch_pdu.bit_len_harq = 0;
+ pucch_pdu.bit_len_csi_part2 = 0;
pucch_pdu.sr_flag = 0;
pucch_pdu.nr_of_symbols = nrofSymbols;
pucch_pdu.hopping_id = hopping_id;
@@ -545,14 +554,15 @@ int main(int argc, char **argv)
pucch_pdu.dmrs_scrambling_id = dmrs_scrambling_id;
pucch_pdu.data_scrambling_id = data_scrambling_id;
nr_decode_pucch2(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu);
- int harq_bytes=pucch_pdu.bit_len_harq>>3;
- if ((pucch_pdu.bit_len_harq&7) > 0) harq_bytes++;
- for (int i=0;i>3;
+ if ((pucch_pdu.bit_len_csi_part1&7) > 0) csi_part1_bytes++;
+ for (int i=0;i>1)+(((actual_payload^payload_received)&4)>>2)+n_errors;
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index 5881b21b5f..b0557ef1b4 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -37,7 +37,7 @@
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
@@ -54,6 +54,8 @@ PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
+
double cpuf;
uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
@@ -391,7 +393,7 @@ int main(int argc, char **argv)
mod_order = nr_get_Qm_ul(Imcs, 0);
code_rate = nr_get_code_rate_ul(Imcs, 0);
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
- TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl);
+ TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl);
printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 169b82bf8d..bcaa967a30 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -41,11 +41,11 @@
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/TOOLS/tools_defs.h"
+#include "SCHED_NR/fapi_nr_l1.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR_UE/defs.h"
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
@@ -53,10 +53,13 @@
#include "openair1/SIMULATION/RF/rf.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
+//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
+
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
#include "SIMULATION/LTE_PHY/common_sim.h"
+
//#define DEBUG_ULSIM
PHY_VARS_gNB *gNB;
@@ -108,15 +111,15 @@ int main(int argc, char **argv)
int i;
double SNR, snr0 = -2.0, snr1 = 2.0;
double sigma, sigma_dB;
- double snr_step = 1;
+ double snr_step = .2;
uint8_t snr1set = 0;
- int slot = 0, frame = 0;
+ int slot = 8, frame = 0;
FILE *output_fd = NULL;
//uint8_t write_output_file = 0;
int trial, n_trials = 1, n_errors = 0, n_false_positive = 0, delay = 0;
uint8_t n_tx = 1, n_rx = 1;
//uint8_t transmission_mode = 1;
- uint16_t Nid_cell = 0;
+ //uint16_t Nid_cell = 0;
channel_desc_t *gNB2UE;
uint8_t extended_prefix_flag = 0;
//int8_t interf1 = -21, interf2 = -21;
@@ -124,10 +127,9 @@ int main(int argc, char **argv)
SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
//unsigned char frame_type = 0;
- int frame_length_complex_samples,frame_length_complex_samples_no_prefix;
NR_DL_FRAME_PARMS *frame_parms;
int loglvl = OAILOG_WARNING;
- uint64_t SSB_positions=0x01;
+ //uint64_t SSB_positions=0x01;
uint16_t nb_symb_sch = 12;
int start_symbol = 2;
uint16_t nb_rb = 50;
@@ -143,12 +145,13 @@ int main(int argc, char **argv)
float target_error_rate = 0.01;
int print_perf = 0;
cpuf = get_cpu_freq_GHz();
-
+ int msg3_flag = 0;
UE_nr_rxtx_proc_t UE_proc;
FILE *scg_fd=NULL;
-
+ int ibwps=24;
+ int ibwp_rboffset=41;
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
}
@@ -156,208 +159,236 @@ int main(int argc, char **argv)
//logInit();
randominit(0);
- while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:p:r:s:y:z:F:M:N:PR:S:L:")) != -1) {
+ while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:M:N:PR:S:L:")) != -1) {
+ printf("handling optarg %c\n",c);
switch (c) {
/*case 'd':
frame_type = 1;
break;*/
- case 'd':
- delay = atoi(optarg);
- break;
+ case 'a':
+ start_symbol = atoi(optarg);
+ AssertFatal(start_symbol >= 0 && start_symbol < 13,"start_symbol %d is not in 0..12\n",start_symbol);
+ break;
- case 'f':
- scg_fd = fopen(optarg, "r");
+ case 'b':
+ nb_symb_sch = atoi(optarg);
+ AssertFatal(nb_symb_sch > 0 && nb_symb_sch < 15,"start_symbol %d is not in 1..14\n",nb_symb_sch);
+ break;
+ case 'c':
+ n_rnti = atoi(optarg);
+ AssertFatal(n_rnti > 0 && n_rnti<=65535,"Illegal n_rnti %x\n",n_rnti);
+ break;
- if (scg_fd == NULL) {
- printf("Error opening %s\n", optarg);
- exit(-1);
- }
-
- break;
-
- case 'g':
- switch ((char) *optarg) {
- case 'A':
- channel_model = SCM_A;
- break;
-
- case 'B':
- channel_model = SCM_B;
- break;
-
- case 'C':
- channel_model = SCM_C;
- break;
-
- case 'D':
- channel_model = SCM_D;
- break;
-
- case 'E':
- channel_model = EPA;
- break;
-
- case 'F':
- channel_model = EVA;
- break;
-
- case 'G':
- channel_model = ETU;
- break;
-
- default:
- printf("Unsupported channel model!\n");
- exit(-1);
- }
-
- break;
+ case 'd':
+ delay = atoi(optarg);
+ break;
+
+ case 'e':
+ msg3_flag = 1;
+ break;
+
+ case 'f':
+ scg_fd = fopen(optarg, "r");
+
+ if (scg_fd == NULL) {
+ printf("Error opening %s\n", optarg);
+ exit(-1);
+ }
+ break;
+
+ case 'g':
+ switch ((char) *optarg) {
+ case 'A':
+ channel_model = SCM_A;
+ break;
+
+ case 'B':
+ channel_model = SCM_B;
+ break;
+
+ case 'C':
+ channel_model = SCM_C;
+ break;
+
+ case 'D':
+ channel_model = SCM_D;
+ break;
+
+ case 'E':
+ channel_model = EPA;
+ break;
+
+ case 'F':
+ channel_model = EVA;
+ break;
+
+ case 'G':
+ channel_model = ETU;
+ break;
+
+ default:
+ printf("Unsupported channel model!\n");
+ exit(-1);
+ }
+
+ break;
+
/*case 'i':
interf1 = atoi(optarg);
break;
-
- case 'j':
+
+ case 'j':
interf2 = atoi(optarg);
break;*/
- case 'l':
- nb_symb_sch = atoi(optarg);
- break;
-
- case 'm':
- Imcs = atoi(optarg);
- break;
-
- case 'n':
- n_trials = atoi(optarg);
- break;
-
- case 'p':
- extended_prefix_flag = 1;
- break;
-
- case 'r':
- nb_rb = atoi(optarg);
- break;
-
- case 's':
- snr0 = atof(optarg);
- printf("Setting SNR0 to %f\n", snr0);
- break;
+ case 'k':
+ printf("Setting threequarter_fs_flag\n");
+ openair0_cfg[0].threequarter_fs= 1;
+ break;
+ case 'l':
+ nb_symb_sch = atoi(optarg);
+ break;
+
+ case 'm':
+ Imcs = atoi(optarg);
+ break;
+
+ case 'n':
+ n_trials = atoi(optarg);
+ break;
+
+ case 'p':
+ extended_prefix_flag = 1;
+ break;
+
+ case 'r':
+ nb_rb = atoi(optarg);
+ break;
+
+ case 's':
+ snr0 = atof(optarg);
+ printf("Setting SNR0 to %f\n", snr0);
+ break;
+
/*
- case 'r':
- ricean_factor = pow(10,-.1*atof(optarg));
- if (ricean_factor>1) {
- printf("Ricean factor must be between 0 and 1\n");
- exit(-1);
- }
- break;
- */
-
+ case 'r':
+ ricean_factor = pow(10,-.1*atof(optarg));
+ if (ricean_factor>1) {
+ printf("Ricean factor must be between 0 and 1\n");
+ exit(-1);
+ }
+ break;
+ */
+
/*case 'x':
transmission_mode = atoi(optarg);
break;*/
+
+ case 'y':
+ n_tx = atoi(optarg);
+
+ if ((n_tx == 0) || (n_tx > 2)) {
+ printf("Unsupported number of tx antennas %d\n", n_tx);
+ exit(-1);
+ }
+
+ break;
+
+ case 'z':
+ n_rx = atoi(optarg);
+
+ if ((n_rx == 0) || (n_rx > 2)) {
+ printf("Unsupported number of rx antennas %d\n", n_rx);
+ exit(-1);
+ }
+
+ break;
+
+ case 'F':
+ input_fd = fopen(optarg, "r");
+
+ if (input_fd == NULL) {
+ printf("Problem with filename %s\n", optarg);
+ exit(-1);
+ }
+
+ break;
+
+ case 'M':
+ // SSB_positions = atoi(optarg);
+ break;
+
+ case 'N':
+ // Nid_cell = atoi(optarg);
+ break;
+
+ case 'R':
+ N_RB_DL = atoi(optarg);
+ N_RB_UL = N_RB_DL;
+ break;
+
+ case 'S':
+ snr1 = atof(optarg);
+ snr1set = 1;
+ printf("Setting SNR1 to %f\n", snr1);
+ break;
+
+ case 'P':
+ print_perf=1;
+ opp_enabled=1;
+ break;
+
+ case 'L':
+ loglvl = atoi(optarg);
+ break;
+
+ default:
+ case 'h':
+ printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]);
+ //printf("-d Use TDD\n");
+ printf("-d Introduce delay in terms of number of samples\n");
+ printf("-f Number of frames to simulate\n");
+ printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
+ printf("-h This message\n");
+ //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
+ //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
+ printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n");
+ printf("-m MCS value\n");
+ printf("-n Number of trials to simulate\n");
+ printf("-p Use extended prefix mode\n");
+ printf("-t Delay spread for multipath channel\n");
+ //printf("-x Transmission mode (1,2,6 for the moment)\n");
+ printf("-y Number of TX antennas used in eNB\n");
+ printf("-z Number of RX antennas used in UE\n");
+ printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
+ //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
+ printf("-F Input filename (.txt format) for RX conformance testing\n");
+ printf("-G raw file containing RRC configuration (generated by gNB)\n");
+ printf("-M Multiple SSB positions in burst\n");
+ printf("-N Nid_cell\n");
+ printf("-O oversampling factor (1,2,4,8,16)\n");
+ printf("-R N_RB_DL\n");
+ printf("-S Ending SNR, runs from SNR0 to SNR1\n");
+ printf("-P Print ULSCH performances\n");
+ exit(-1);
+ break;
- case 'y':
- n_tx = atoi(optarg);
-
- if ((n_tx == 0) || (n_tx > 2)) {
- printf("Unsupported number of tx antennas %d\n", n_tx);
- exit(-1);
- }
-
- break;
-
- case 'z':
- n_rx = atoi(optarg);
-
- if ((n_rx == 0) || (n_rx > 2)) {
- printf("Unsupported number of rx antennas %d\n", n_rx);
- exit(-1);
- }
-
- break;
-
- case 'F':
- input_fd = fopen(optarg, "r");
-
- if (input_fd == NULL) {
- printf("Problem with filename %s\n", optarg);
- exit(-1);
- }
-
- break;
-
- case 'M':
- SSB_positions = atoi(optarg);
- break;
-
- case 'N':
- Nid_cell = atoi(optarg);
- break;
-
- case 'R':
- N_RB_DL = atoi(optarg);
- N_RB_UL = N_RB_DL;
- break;
-
- case 'S':
- snr1 = atof(optarg);
- snr1set = 1;
- printf("Setting SNR1 to %f\n", snr1);
- break;
-
- case 'P':
- print_perf=1;
- opp_enabled=1;
- break;
-
- case 'L':
- loglvl = atoi(optarg);
- break;
-
- default:
- case 'h':
- printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]);
- //printf("-d Use TDD\n");
- printf("-d Introduce delay in terms of number of samples\n");
- printf("-f Number of frames to simulate\n");
- printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
- printf("-h This message\n");
- //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
- //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
- printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n");
- printf("-m MCS value\n");
- printf("-n Number of trials to simulate\n");
- printf("-p Use extended prefix mode\n");
- printf("-t Delay spread for multipath channel\n");
- //printf("-x Transmission mode (1,2,6 for the moment)\n");
- printf("-y Number of TX antennas used in eNB\n");
- printf("-z Number of RX antennas used in UE\n");
- printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
- //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
- printf("-F Input filename (.txt format) for RX conformance testing\n");
- printf("-G raw file containing RRC configuration (generated by gNB)\n");
- printf("-M Multiple SSB positions in burst\n");
- printf("-N Nid_cell\n");
- printf("-O oversampling factor (1,2,4,8,16)\n");
- printf("-R N_RB_DL\n");
- printf("-S Ending SNR, runs from SNR0 to SNR1\n");
- printf("-P Print ULSCH performances\n");
- exit(-1);
- break;
}
}
-
+
logInit();
set_glog(loglvl);
T_stdout = 1;
get_softmodem_params()->phy_test = 1;
-
+ get_softmodem_params()->do_ra = 0;
+ get_softmodem_params()->usim_test = 1;
+
+
if (snr1set == 0)
snr1 = snr0 + 10;
@@ -382,12 +413,15 @@ int main(int argc, char **argv)
gNB->UL_INFO.rx_ind.number_of_pdus = 0;
gNB->UL_INFO.crc_ind.number_crcs = 0;
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
+
+
frame_parms->nb_antennas_tx = n_tx;
frame_parms->nb_antennas_rx = n_rx;
frame_parms->N_RB_DL = N_RB_DL;
frame_parms->N_RB_UL = N_RB_UL;
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
+
RC.nb_nr_macrlc_inst = 1;
RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int));
for (i = 0; i < RC.nb_nr_macrlc_inst; i++)
@@ -416,6 +450,7 @@ int main(int argc, char **argv)
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
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,1,scc,0,0,NULL);
@@ -424,12 +459,14 @@ int main(int argc, char **argv)
phy_init_nr_gNB(gNB,0,0);
N_RB_DL = gNB->frame_parms.N_RB_DL;
+
+
+ NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0];
+
//crcTableInit();
//nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions);
- frame_length_complex_samples = frame_parms->samples_per_subframe;
- frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
//configure UE
UE = malloc(sizeof(PHY_VARS_NR_UE));
@@ -477,7 +514,7 @@ int main(int argc, char **argv)
rrc.carrier.MIB = (uint8_t*) malloc(4);
rrc.carrier.sizeof_MIB = do_MIB_NR(&rrc,0);
- nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup->spCellConfig);
+ nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup);
nr_ue_phy_config_request(&UE_mac->phy_config);
@@ -486,7 +523,11 @@ int main(int argc, char **argv)
NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0];
//nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu;
- nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req;
+ nfapi_nr_ul_tti_request_t *UL_tti_req = malloc(sizeof(*UL_tti_req));
+ NR_Sched_Rsp_t *Sched_INFO = malloc(sizeof(*Sched_INFO));
+ memset((void*)Sched_INFO,0,sizeof(*Sched_INFO));
+ Sched_INFO->UL_tti_req=UL_tti_req;
+
nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;
NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
@@ -533,6 +574,7 @@ int main(int argc, char **argv)
printf("\n");
+ for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
varArray_t *table_rx=initVarArray(1000,sizeof(double));
@@ -574,19 +616,40 @@ int main(int argc, char **argv)
UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t));
+ int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
+ int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
+ int ibwp_size = ibwps;
+ int ibwp_start = ibwp_rboffset;
+ if (msg3_flag == 1) {
+ if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
+ pusch_pdu->bwp_start = abwp_start;
+ else
+ pusch_pdu->bwp_start = ibwp_start;
+ pusch_pdu->bwp_size = ibwp_size;
+ start_rb += (ibwp_start - abwp_start);
+ printf("msg3: ibwp_size %d, abwp_size %d, ibwp_start %d, abwp_start %d\n",
+ ibwp_size,abwp_size,ibwp_start,abwp_start);
+ }
+ else {
+ pusch_pdu->bwp_start = abwp_start;
+ pusch_pdu->bwp_size = abwp_size;
+ }
+
pusch_pdu->pdu_bit_map = pdu_bit_map;
pusch_pdu->rnti = n_rnti;
pusch_pdu->mcs_index = Imcs;
pusch_pdu->mcs_table = mcs_table;
pusch_pdu->target_code_rate = code_rate;
pusch_pdu->qam_mod_order = mod_order;
- pusch_pdu->transform_precoding = 0;
- pusch_pdu->data_scrambling_id = 0;
+ pusch_pdu->transform_precoding = 1;
+ pusch_pdu->data_scrambling_id = *scc->physCellId;
pusch_pdu->nrOfLayers = 1;
pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol;
pusch_pdu->dmrs_config_type = 0;
- pusch_pdu->ul_dmrs_scrambling_id = 0;
+ pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
pusch_pdu->scid = 0;
+ pusch_pdu->dmrs_ports = 1;
+ pusch_pdu->num_dmrs_cdm_grps_no_data = 1;
pusch_pdu->resource_alloc = 1;
pusch_pdu->rb_start = start_rb;
pusch_pdu->rb_size = nb_rb;
@@ -604,6 +667,9 @@ int main(int argc, char **argv)
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
+ // prepare ULSCH/PUSCH reception
+ nr_schedule_response(Sched_INFO);
+
// --------- setting parameters for UE --------
scheduled_response.module_id = 0;
@@ -627,6 +693,7 @@ int main(int argc, char **argv)
ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = 0;
ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
+ ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = 0;
ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
@@ -638,75 +705,135 @@ int main(int argc, char **argv)
//there are plenty of other parameters that we don't seem to be using for now. e.g.
ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
- nb_re_dmrs = ((ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type == pusch_dmrs_type1) ? 6 : 4);
- available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
- TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, precod_nbr_layers);
+ nb_re_dmrs = ((ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type == pusch_dmrs_type1) ? 6 : 4);
+ available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
+ TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
pusch_pdu->pusch_data.tb_size = TBS>>3;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS;
- // set FAPI parameters for UE, put them in the scheduled response and call
- nr_ue_scheduled_response(&scheduled_response);
- /////////////////////////phy_procedures_nr_ue_TX///////////////////////
- ///////////
+ nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
+ int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);// - (int)(800*factor);
+ int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
- phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0);
+ for (int i=0;i<(TBS>>3);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
+ double scale = 1;
- if (n_trials==1)
- LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_length_complex_samples,1,1);
+ if (input_fd == NULL) {
- ///////////
- ////////////////////////////////////////////////////
- tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
+ if (SNR==snr0) {
+ // set FAPI parameters for UE, put them in the scheduled response and call
+ nr_ue_scheduled_response(&scheduled_response);
+
+
+ /////////////////////////phy_procedures_nr_ue_TX///////////////////////
+ ///////////
+
+ phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0);
+
+
+ if (n_trials==1) {
+ LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1);
+ LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1);
+ }
+ ///////////
+ ////////////////////////////////////////////////////
+ tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
+
+ txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
+ frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
+
+ txlev_float = (double)txlev/scale; // output of signal_energy is fixed point representation
+
+
+ //AWGN
+ }
+ }
+ else n_trials = 1;
- txlev = signal_energy_amp_shift(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
- frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
- txlev_float = (double)txlev/(double)AMP; // output of signal_energy is fixed point representation
+ sigma_dB = 10*log10(txlev_float)-SNR;
+ sigma = pow(10,sigma_dB/10);
+ printf("txlev_float %f, sigma_dB %f\n",10*log10(txlev_float),sigma_dB);
n_errors = 0;
n_false_positive = 0;
- //AWGN
- sigma_dB = 10*log10(txlev_float)-SNR;
- sigma = pow(10,sigma_dB/10);
+ errors_scrambling = 0;
+ errors_decoding = 0;
+ int error_flag;
for (trial = 0; trial < n_trials; trial++) {
+
+ error_flag = 0;
+ //----------------------------------------------------------
+ //------------------------ add noise -----------------------
+ //----------------------------------------------------------
+ if (input_fd == NULL ) {
+ for (i=0; inb_antennas_rx; ap++) {
+ ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((double)(((int16_t *)&UE->common_vars.txdata[ap][slot_offset])[(i<<1)])/sqrt(scale) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
+ ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((double)(((int16_t *)&UE->common_vars.txdata[ap][slot_offset])[(i<<1)+1])/sqrt(scale) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
+ }
+ }
+ }
+ else {
+ AssertFatal(frame_parms->nb_antennas_rx == 1, "nb_ant != 1\n");
+ // 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
+ AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing);
+ double factor = 1;
+ if (openair0_cfg[0].threequarter_fs== 1) factor =.75;
+ int ta_offset=1600;
+ if (N_RB_DL <217) ta_offset=800;
+ else if (N_RB_DL < 106) ta_offset = 400;
- errors_scrambling = 0;
- errors_decoding = 0;
-
- //----------------------------------------------------------
- //------------------------ add noise -----------------------
- //----------------------------------------------------------
- for (i=0; inb_antennas_rx; ap++) {
- ((short*) gNB->common_vars.rxdata[ap])[(2*i) + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); // convert to fixed point
- ((short*) gNB->common_vars.rxdata[ap])[2*i+1 + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP);
- }
- }
- ////////////////////////////////////////////////////////////
-
- //----------------------------------------------------------
- //------------------- gNB phy procedures -------------------
- //----------------------------------------------------------
- gNB->UL_INFO.rx_ind.number_of_pdus = 0;
- gNB->UL_INFO.crc_ind.number_crcs = 0;
+ fread((void*)&gNB->common_vars.rxdata[0][slot_offset],
+ sizeof(int16_t),
+ slot_length<<1,
+ input_fd);
+ for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
+ slot_offset,
+ ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
+ ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
+ fclose(input_fd);
+ }
+ ////////////////////////////////////////////////////////////
+
+ //----------------------------------------------------------
+ //------------------- gNB phy procedures -------------------
+ //----------------------------------------------------------
+ gNB->UL_INFO.rx_ind.number_of_pdus = 0;
+ gNB->UL_INFO.crc_ind.number_crcs = 0;
start_meas(&gNB->phy_proc_rx);
phy_procedures_gNB_common_RX(gNB, frame, slot);
- if (n_trials==1)
- LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],frame_length_complex_samples_no_prefix,1,1);
+ if (n_trials==1) {
+ LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][0],frame_parms->samples_per_subframe*10,1,1);
+ LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0]+start_symbol*frame_parms->ofdm_symbol_size,nb_symb_sch*frame_parms->ofdm_symbol_size,1,1);
+
+ }
phy_procedures_gNB_uespec_RX(gNB, frame, slot);
+ if (n_trials == 1) {
+ LOG_M("rxsigF0_ext.m","rxsF0_ext",
+ &gNB->pusch_vars[0]->rxdataF_ext[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1);
+ LOG_M("chestF0.m","chF0",
+ &gNB->pusch_vars[0]->ul_ch_estimates[0][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
+ LOG_M("chestF0_ext.m","chF0_ext",
+ &gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1);
+ LOG_M("rxsigF0_comp.m","rxsF0_comp",
+ &gNB->pusch_vars[0]->rxdataF_comp[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1);
+ }
start_meas(&gNB->phy_proc_rx);
////////////////////////////////////////////////////////////
if (gNB->ulsch[0][0]->last_iteration_cnt >=
- gNB->ulsch[0][0]->max_ldpc_iterations+1)
+ gNB->ulsch[0][0]->max_ldpc_iterations+1) {
+ error_flag = 1;
n_errors++;
-
+ }
+
//----------------------------------------------------------
//----------------- count and print errors -----------------
//----------------------------------------------------------
@@ -738,22 +865,30 @@ int main(int argc, char **argv)
errors_decoding++;
}
}
-
- if (errors_decoding > 0) {
+ if (n_trials == 1) {
+ for (int r=0;rharq_processes[harq_pid]->C;r++)
+ for (int i=0;iharq_processes[harq_pid]->K>>3;i++) {
+ if ((ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]) != 0) printf("************");
+ printf("r %d: in[%d] %x, out[%d] %x (%x)\n",r,
+ i,ulsch_ue[0]->harq_processes[harq_pid]->c[r][i],
+ i,ulsch_gNB->harq_processes[harq_pid]->c[r][i],
+ ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]);
+ }
+ }
+ if (errors_decoding > 0 && error_flag == 0) {
n_false_positive++;
if (n_trials==1)
printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding = %u\n" "\x1B[0m", frame, trial, errors_decoding);
}
-
} // trial loop
printf("*****************************************\n");
- printf("SNR %f: n_errors (negative CRC) = %d/%d, false_positive %d/%d, errors_scrambling %u/%d\n", SNR, n_errors, n_trials, n_false_positive, n_trials, errors_scrambling, n_trials);
+ printf("SNR %f: n_errors (negative CRC) = %d/%d, false_positive %d/%d, errors_scrambling %u/%u\n", SNR, n_errors, n_trials, n_false_positive, n_trials, errors_scrambling, available_bits*n_trials);
printf("\n");
printf("SNR %f: Channel BLER %e, Channel BER %e\n", SNR,(double)n_errors/n_trials,(double)errors_scrambling/available_bits/n_trials);
printf("*****************************************\n");
printf("\n");
-
+
if (print_perf==1) {
printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
printStatIndent(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
@@ -779,7 +914,6 @@ int main(int argc, char **argv)
}
} // SNR loop
-
printf("\n");
free(test_input_bit);
diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
index f4835570bf..d344992586 100644
--- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
+++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
@@ -27,18 +27,20 @@
#include "SIMULATION/RF/rf.h"
#include
-void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length);
+void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length);
double frand_a_b(double a, double b);
-void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int delay);
+void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int delay);
void multipath_tv_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
- uint16_t length,
- uint8_t keep_channel) {
- double complex **tx,**rx,* **H_t,*rx_temp; //, *tv_H_t;
+ uint32_t length,
+ uint8_t keep_channel)
+{
+
+ double complex **tx,**rx,***H_t,*rx_temp;//, *tv_H_t;
double path_loss = pow(10,desc->path_loss_dB/20);
int i,j,k,dd;
dd = abs(desc->channel_offset);
@@ -126,7 +128,8 @@ void multipath_tv_channel(channel_desc_t *desc,
}
//TODO: make phi_rad a parameter of this function
-void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length) {
+void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){
+
int i,j,p,l,k;
double *alpha,*phi_rad,pi=acos(-1),*w_Hz;
alpha = (double *)calloc(desc->nb_paths,sizeof(double));
@@ -193,7 +196,8 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length) {
}
// time varying convolution
-void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int dd) {
+void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd){
+
int i,j;
for(i=0; i<((int)nb_samples-dd); i++) {
diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h
index 0bc5975d99..6071e1e743 100644
--- a/openair1/SIMULATION/TOOLS/sim.h
+++ b/openair1/SIMULATION/TOOLS/sim.h
@@ -426,21 +426,12 @@ void multipath_tv_channel(channel_desc_t *desc,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
- uint16_t length,
+ uint32_t length,
uint8_t keep_channel);
/**@} */
/**@} */
-void rxAddInput( struct complex16 *input_sig,
- struct complex16 *after_channel_sig,
- int rxAnt,
- channel_desc_t *channelDesc,
- int nbSamples,
- uint64_t TS,
- uint32_t CirSize
- );
-
int modelid_fromname(char *modelname);
double channelmod_get_snr_dB(void);
double channelmod_get_sinr_dB(void);
diff --git a/openair1/SIMULATION/TOOLS/taus.c b/openair1/SIMULATION/TOOLS/taus.c
index 5fe0ce4d78..cdd4aebec3 100644
--- a/openair1/SIMULATION/TOOLS/taus.c
+++ b/openair1/SIMULATION/TOOLS/taus.c
@@ -21,7 +21,8 @@
#include
#include
-#include "SIMULATION/TOOLS/sim.h"
+//#include "SIMULATION/TOOLS/sim.h"
+
unsigned int s0, s1, s2, b;
diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h
index 1eb58b16b2..77f7e26c67 100644
--- a/openair2/COMMON/platform_constants.h
+++ b/openair2/COMMON/platform_constants.h
@@ -101,6 +101,7 @@
#define NUMBER_OF_NR_DLSCH_MAX 2//16
#define NUMBER_OF_NR_ULSCH_MAX 2//16
+#define NUMBER_OF_NR_PUCCH_MAX 2
#define NUMBER_OF_NR_SR_MAX 16
diff --git a/openair2/COMMON/s1ap_messages_def.h b/openair2/COMMON/s1ap_messages_def.h
index 57201721ce..5e5794fc55 100644
--- a/openair2/COMMON/s1ap_messages_def.h
+++ b/openair2/COMMON/s1ap_messages_def.h
@@ -66,6 +66,7 @@ MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_m
MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_resp_t , s1ap_e_rab_release_resp)
MESSAGE_DEF(S1AP_PATH_SWITCH_REQ , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_t , s1ap_path_switch_req)
MESSAGE_DEF(S1AP_PATH_SWITCH_REQ_ACK , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_ack_t , s1ap_path_switch_req_ack)
+MESSAGE_DEF(S1AP_E_RAB_MODIFICATION_IND , MESSAGE_PRIORITY_MED, s1ap_e_rab_modification_ind_t , s1ap_e_rab_modification_ind)
/* S1AP -> RRC messages */
MESSAGE_DEF(S1AP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t , s1ap_downlink_nas )
diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h
index 8e13e35d65..befab4ebdf 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -45,6 +45,7 @@
#define S1AP_E_RAB_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modify_resp
#define S1AP_PATH_SWITCH_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req
#define S1AP_PATH_SWITCH_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req_ack
+#define S1AP_E_RAB_MODIFICATION_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modification_ind
#define S1AP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_downlink_nas
#define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req
@@ -277,12 +278,26 @@ typedef struct e_rab_tobe_added_s {
uint8_t drb_ID;
/* The transport layer address for the IP packets */
- transport_layer_addr_t eNB_addr;
+ transport_layer_addr_t sgw_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
} e_rab_tobe_added_t;
+typedef struct e_rab_admitted_tobe_added_s {
+ /* Unique e_rab_id for the UE. */
+ uint8_t e_rab_id;
+
+ /* Unique drb_ID for the UE. */
+ uint8_t drb_ID;
+
+ /* The transport layer address for the IP packets */
+ transport_layer_addr_t gnb_addr;
+
+ /* S-GW Tunnel endpoint identifier */
+ uint32_t gtp_teid;
+} e_rab_admitted_tobe_added_t;
+
typedef struct e_rab_tobeswitched_s {
@@ -642,6 +657,27 @@ typedef struct s1ap_path_switch_req_ack_s {
} s1ap_path_switch_req_ack_t;
+typedef struct s1ap_e_rab_modification_ind_s {
+
+ unsigned eNB_ue_s1ap_id:24;
+
+ /* MME UE id */
+ uint32_t mme_ue_s1ap_id;
+
+ /* Number of e_rab setup-ed in the list */
+ uint8_t nb_of_e_rabs_tobemodified;
+
+ uint8_t nb_of_e_rabs_nottobemodified;
+
+ /* list of e_rab setup-ed by RRC layers */
+ e_rab_setup_t e_rabs_tobemodified[S1AP_MAX_E_RAB];
+
+ e_rab_setup_t e_rabs_nottobemodified[S1AP_MAX_E_RAB];
+
+ uint16_t ue_initial_id;
+
+} s1ap_e_rab_modification_ind_t;
+
// S1AP --> RRC messages
typedef struct s1ap_ue_release_command_s {
diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h
index ed3470a7d6..f0743e60a5 100644
--- a/openair2/COMMON/x2ap_messages_types.h
+++ b/openair2/COMMON/x2ap_messages_types.h
@@ -315,7 +315,7 @@ typedef struct x2ap_senb_addition_req_ack_s {
typedef struct x2ap_ENDC_sgnb_addition_req_s {
int ue_x2_id;
-
+ LTE_PhysCellId_t target_physCellId;
/* used for RRC->X2AP in source eNB */
int rnti;
@@ -363,7 +363,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s {
uint8_t nb_e_rabs_admitted_tobeadded;
/* list of e_rab to be added by RRC layers */
- e_rab_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB];
+ e_rab_admitted_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB];
/* list of e_rab to be setup by RRC layers */
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
@@ -386,6 +386,7 @@ typedef struct x2ap_ENDC_reconf_complete_s {
int MeNB_ue_x2_id;
int SgNB_ue_x2_id;
+ LTE_PhysCellId_t target_physCellId;
x2ap_sgNB_reconf_response_information_t reconf_response;
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
index 975ac4e96f..f1daacbb65 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
@@ -49,18 +49,13 @@ struct lfds700_misc_prng_state ps[NUM_MAX_ENB];
struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB];
struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB];
-/* the slice config as kept in the underlying system */
-Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES];
-/* a structure that keeps updates which will be reflected in slice_config later */
-Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES];
-/* indicates whether sc_update contains new data */
-int perform_slice_config_update_count = 1;
-/* queue of incoming new UE<>slice association commands */
-Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES];
-int n_ue_slice_assoc_updates = 0;
-/* mutex for sc_update: do not receive new config and write it at the same time */
-pthread_mutex_t sc_update_mtx = PTHREAD_MUTEX_INITIALIZER;
+/* Ringbuffer-related to slice configuration */
+struct lfds700_ringbuffer_element *slice_config_array[NUM_MAX_ENB];
+struct lfds700_ringbuffer_state slice_config_ringbuffer_state[NUM_MAX_ENB];
+/* Ringbuffer-related to slice configuration */
+struct lfds700_ringbuffer_element *ue_assoc_array[NUM_MAX_ENB];
+struct lfds700_ringbuffer_state ue_assoc_ringbuffer_state[NUM_MAX_ENB];
int flexran_agent_mac_stats_reply_ue(mid_t mod_id,
Protocol__FlexUeStatsReport **ue_report,
@@ -1354,6 +1349,33 @@ void flexran_agent_init_mac_agent(mid_t mod_id) {
AssertFatal(i == 0, "posix_memalign(): could not allocate aligned memory for lfds library\n");
lfds700_ringbuffer_init_valid_on_current_logical_core(&ringbuffer_state[mod_id],
dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL);
+
+ struct lfds700_misc_prng_state scrng;
+ i = posix_memalign((void **) &slice_config_array[mod_id],
+ LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES,
+ sizeof(struct lfds700_ringbuffer_element) * num_elements);
+ AssertFatal(i == 0,
+ "posix_memalign(): could not allocate aligned memory\n");
+ lfds700_ringbuffer_init_valid_on_current_logical_core(
+ &slice_config_ringbuffer_state[mod_id],
+ slice_config_array[mod_id],
+ num_elements,
+ &scrng,
+ NULL);
+
+ struct lfds700_misc_prng_state uarng;
+ i = posix_memalign((void **) &ue_assoc_array[mod_id],
+ LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES,
+ sizeof(struct lfds700_ringbuffer_element) * num_elements);
+ AssertFatal(i == 0,
+ "posix_memalign(): could not allocate aligned memory\n");
+ lfds700_ringbuffer_init_valid_on_current_logical_core(
+ &ue_assoc_ringbuffer_state[mod_id],
+ ue_assoc_array[mod_id],
+ num_elements,
+ &uarng,
+ NULL);
+
for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
for (j = 0; j < 8; j++) {
if (RC.mac && RC.mac[mod_id])
@@ -1465,9 +1487,74 @@ void flexran_agent_fill_mac_cell_config(mid_t mod_id, uint8_t cc_id,
conf->si_config->has_sfn = 1;
}
- /* get a pointer to the config which is maintained in the agent throughout
- * its lifetime */
- conf->slice_config = flexran_agent_get_slice_config(mod_id);
+ conf->slice_config = malloc(sizeof(Protocol__FlexSliceConfig));
+ if (conf->slice_config) {
+ protocol__flex_slice_config__init(conf->slice_config);
+ Protocol__FlexSliceConfig *sc = conf->slice_config;
+
+ sc->dl = malloc(sizeof(Protocol__FlexSliceDlUlConfig));
+ DevAssert(sc->dl);
+ protocol__flex_slice_dl_ul_config__init(sc->dl);
+ sc->dl->algorithm = flexran_get_dl_slice_algo(mod_id);
+ sc->dl->has_algorithm = 1;
+ sc->dl->n_slices = flexran_get_num_dl_slices(mod_id);
+ if (sc->dl->n_slices > 0) {
+ sc->dl->slices = calloc(sc->dl->n_slices, sizeof(Protocol__FlexSlice *));
+ DevAssert(sc->dl->slices);
+ for (int i = 0; i < sc->dl->n_slices; ++i) {
+ sc->dl->slices[i] = malloc(sizeof(Protocol__FlexSlice));
+ DevAssert(sc->dl->slices[i]);
+ protocol__flex_slice__init(sc->dl->slices[i]);
+ flexran_get_dl_slice(mod_id, i, sc->dl->slices[i], sc->dl->algorithm);
+ }
+ } else {
+ sc->dl->scheduler = flexran_get_dl_scheduler_name(mod_id);
+ }
+
+ sc->ul = malloc(sizeof(Protocol__FlexSliceDlUlConfig));
+ DevAssert(sc->ul);
+ protocol__flex_slice_dl_ul_config__init(sc->ul);
+ sc->ul->algorithm = flexran_get_ul_slice_algo(mod_id);
+ sc->ul->has_algorithm = 1;
+ sc->ul->n_slices = flexran_get_num_ul_slices(mod_id);
+ if (sc->ul->n_slices > 0) {
+ sc->ul->slices = calloc(sc->ul->n_slices, sizeof(Protocol__FlexSlice *));
+ DevAssert(sc->ul->slices);
+ for (int i = 0; i < sc->ul->n_slices; ++i) {
+ sc->ul->slices[i] = malloc(sizeof(Protocol__FlexSlice));
+ DevAssert(sc->ul->slices[i]);
+ protocol__flex_slice__init(sc->ul->slices[i]);
+ flexran_get_ul_slice(mod_id, i, sc->ul->slices[i], sc->ul->algorithm);
+ }
+ } else {
+ sc->ul->scheduler = flexran_get_ul_scheduler_name(mod_id);
+ }
+ }
+}
+
+void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf) {
+ Protocol__FlexSliceConfig *sc = conf->slice_config;
+ for (int i = 0; i < sc->dl->n_slices; ++i) {
+ free(sc->dl->slices[i]);
+ sc->dl->slices[i] = NULL;
+ /* scheduler names are not freed: we assume we read them directly from the
+ * underlying memory and do not dispose it */
+ }
+ free(sc->dl->slices);
+ /* scheduler name is not freed */
+ free(sc->dl);
+ sc->dl = NULL;
+ for (int i = 0; i < sc->ul->n_slices; ++i) {
+ free(sc->ul->slices[i]);
+ sc->ul->slices[i] = NULL;
+ /* scheduler names are not freed */
+ }
+ free(sc->ul->slices);
+ /* scheduler name is not freed */
+ free(sc->ul);
+ sc->ul = NULL;
+ free(conf->slice_config);
+ conf->slice_config = NULL;
}
void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id,
@@ -1481,10 +1568,12 @@ void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id,
ue_conf->rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
ue_conf->has_rnti = 1;
- ue_conf->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, ue_id);
- ue_conf->has_dl_slice_id = 1;
- ue_conf->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, ue_id);
- ue_conf->has_ul_slice_id = 1;
+ int dl_id = flexran_get_ue_dl_slice_id(mod_id, ue_id);
+ ue_conf->dl_slice_id = dl_id;
+ ue_conf->has_dl_slice_id = dl_id >= 0;
+ int ul_id = flexran_get_ue_ul_slice_id(mod_id, ue_id);
+ ue_conf->ul_slice_id = ul_id;
+ ue_conf->has_ul_slice_id = ul_id >= 0;
ue_conf->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id, ue_id);
ue_conf->has_ue_aggregated_max_bitrate_ul = 1;
@@ -1565,6 +1654,15 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id)
LOG_E(FLEXRAN_AGENT, "MAC agent CM for eNB %d is not registered\n", mod_id);
return -1;
}
+
+ lfds700_ringbuffer_cleanup(&ringbuffer_state[mod_id], NULL );
+ free(dl_mac_config_array[mod_id]);
+ lfds700_ringbuffer_cleanup(&slice_config_ringbuffer_state[mod_id], NULL );
+ free(slice_config_array[mod_id]);
+ lfds700_ringbuffer_cleanup(&ue_assoc_ringbuffer_state[mod_id], NULL );
+ free(ue_assoc_array[mod_id]);
+ lfds700_misc_library_cleanup();
+
AGENT_MAC_xface *xface = agent_mac_xface[mod_id];
xface->flexran_agent_send_sr_info = NULL;
xface->flexran_agent_send_sf_trigger = NULL;
@@ -1579,234 +1677,91 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id)
return 0;
}
-AGENT_MAC_xface *flexran_agent_get_mac_xface(mid_t mod_id)
-{
- return agent_mac_xface[mod_id];
+void helper_destroy_mac_slice_config(Protocol__FlexSliceConfig *slice_config) {
+ if (slice_config->dl) {
+ if (slice_config->dl->scheduler)
+ free(slice_config->dl->scheduler);
+ for (int i = 0; i < slice_config->dl->n_slices; i++)
+ if (slice_config->dl->slices[i]->scheduler)
+ free(slice_config->dl->slices[i]->scheduler);
+ }
+ if (slice_config->ul) {
+ if (slice_config->ul->scheduler)
+ free(slice_config->ul->scheduler);
+ for (int i = 0; i < slice_config->ul->n_slices; i++)
+ if (slice_config->ul->slices[i]->scheduler)
+ free(slice_config->ul->slices[i]->scheduler);
+ }
+
+ Protocol__FlexCellConfig helper;
+ helper.slice_config = slice_config;
+ flexran_agent_destroy_mac_slice_config(&helper);
}
-void flexran_create_config_structures(mid_t mod_id)
-{
- int i;
- int n_dl = flexran_get_num_dl_slices(mod_id);
- int m_ul = flexran_get_num_ul_slices(mod_id);
- slice_config[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul);
- sc_update[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul);
- if (!slice_config[mod_id] || !sc_update[mod_id]) return;
+void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice_config) {
+ if (!*slice_config) return;
+ /* just use the memory and set to NULL in original */
+ Protocol__FlexSliceConfig *sc = *slice_config;
+ *slice_config = NULL;
- flexran_agent_read_slice_config(mod_id, slice_config[mod_id]);
- flexran_agent_read_slice_config(mod_id, sc_update[mod_id]);
- for (i = 0; i < n_dl; i++) {
- flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]);
- flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]);
- }
- for (i = 0; i < m_ul; i++) {
- flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]);
- flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]);
+ struct lfds700_misc_prng_state ls;
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+ lfds700_misc_prng_init(&ls);
+ enum lfds700_misc_flag overwrite_occurred_flag;
+
+ Protocol__FlexSliceConfig *overwritten_sc;
+ lfds700_ringbuffer_write(&slice_config_ringbuffer_state[mod_id],
+ NULL,
+ (void *)sc,
+ &overwrite_occurred_flag,
+ NULL,
+ (void **)&overwritten_sc,
+ &ls);
+
+ if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) {
+ helper_destroy_mac_slice_config(overwritten_sc);
+ LOG_E(FLEXRAN_AGENT, "lost slice config: too many reconfigurations at once\n");
}
}
-void flexran_check_and_remove_slices(mid_t mod_id)
-{
- Protocol__FlexDlSlice **dl = sc_update[mod_id]->dl;
- Protocol__FlexDlSlice **dlreal = slice_config[mod_id]->dl;
- int i = 0;
- while (i < sc_update[mod_id]->n_dl) {
- /* remove slices whose percentage is zero */
- if (dl[i]->percentage > 0) {
- ++i;
- continue;
- }
- if (flexran_remove_dl_slice(mod_id, i) < 1) {
- LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n",
- mod_id, i, dl[i]->id);
- ++i;
- continue;
- }
- LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n",
- mod_id, i, dl[i]->id);
- if (dl[i]->n_sorting > 0) free(dl[i]->sorting);
- free(dl[i]->scheduler_name);
- if (dlreal[i]->n_sorting > 0) {
- dlreal[i]->n_sorting = 0;
- free(dlreal[i]->sorting);
- }
- free(dlreal[i]->scheduler_name);
- --sc_update[mod_id]->n_dl;
- --slice_config[mod_id]->n_dl;
- const size_t last = sc_update[mod_id]->n_dl;
- /* we need to memcpy the higher slice to the position we just deleted */
- memcpy(dl[i], dl[last], sizeof(*dl[last]));
- memset(dl[last], 0, sizeof(*dl[last]));
- memcpy(dlreal[i], dlreal[last], sizeof(*dlreal[last]));
- memset(dlreal[last], 0, sizeof(*dlreal[last]));
- /* dont increase i but recheck the slice which has been copied to here */
- }
- Protocol__FlexUlSlice **ul = sc_update[mod_id]->ul;
- Protocol__FlexUlSlice **ulreal = slice_config[mod_id]->ul;
- i = 0;
- while (i < sc_update[mod_id]->n_ul) {
- if (ul[i]->percentage > 0) {
- ++i;
- continue;
- }
- if (flexran_remove_ul_slice(mod_id, i) < 1) {
- LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n",
- mod_id, i, ul[i]->id);
- ++i;
- continue;
- }
- LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n",
- mod_id, i, ul[i]->id);
- free(ul[i]->scheduler_name);
- free(ulreal[i]->scheduler_name);
- --sc_update[mod_id]->n_ul;
- --slice_config[mod_id]->n_ul;
- const size_t last = sc_update[mod_id]->n_ul;
- /* see DL remarks */
- memcpy(ul[i], ul[last], sizeof(*ul[last]));
- memset(ul[last], 0, sizeof(*ul[last]));
- memcpy(ulreal[i], ulreal[last], sizeof(*ulreal[last]));
- memset(ulreal[last], 0, sizeof(*ulreal[last]));
- /* dont increase i but recheck the slice which has been copied to here */
+void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config) {
+ struct lfds700_misc_prng_state ls;
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+ lfds700_misc_prng_init(&ls);
+ enum lfds700_misc_flag overwrite_occurred_flag;
+
+ Protocol__FlexUeConfig *overwritten_ue_config;
+ lfds700_ringbuffer_write(&ue_assoc_ringbuffer_state[mod_id],
+ NULL,
+ (void *) *ue_config,
+ &overwrite_occurred_flag,
+ NULL,
+ (void **)&overwritten_ue_config,
+ &ls);
+
+ if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) {
+ free(overwritten_ue_config);
+ LOG_E(FLEXRAN_AGENT, "lost UE-slice association: too many UE-slice associations at once\n");
}
}
-void flexran_agent_slice_update(mid_t mod_id)
-{
- int i;
- int changes = 0;
+void flexran_agent_slice_update(mid_t mod_id) {
+ struct lfds700_misc_prng_state ls;
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+ lfds700_misc_prng_init(&ls);
- if (perform_slice_config_update_count <= 0) return;
- perform_slice_config_update_count--;
-
- pthread_mutex_lock(&sc_update_mtx);
-
- if (!slice_config[mod_id]) {
- /* if the configuration does not exist for agent, create from eNB structure
- * and exit */
- flexran_create_config_structures(mod_id);
- pthread_mutex_unlock(&sc_update_mtx);
- return;
+ Protocol__FlexSliceConfig *sc = NULL;
+ struct lfds700_ringbuffer_state *state = &slice_config_ringbuffer_state[mod_id];
+ if (lfds700_ringbuffer_read(state, NULL, (void **) &sc, &ls) != 0) {
+ apply_update_dl_slice_config(mod_id, sc->dl);
+ apply_update_ul_slice_config(mod_id, sc->ul);
+ helper_destroy_mac_slice_config(sc);
}
- /********* read existing config *********/
- /* simply update slice_config all the time and write new config
- * (apply_new_slice_dl_config() only updates if changes are necessary) */
- slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id);
- slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id);
- for (i = 0; i < slice_config[mod_id]->n_dl; i++) {
- flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]);
+ Protocol__FlexUeConfig *ue_config = NULL;
+ state = &ue_assoc_ringbuffer_state[mod_id];
+ if (lfds700_ringbuffer_read(state, NULL, (void **) &ue_config, &ls) != 0) {
+ apply_ue_slice_assoc_update(mod_id, ue_config);
+ free(ue_config);
}
- for (i = 0; i < slice_config[mod_id]->n_ul; i++) {
- flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]);
- }
-
- /********* write new config *********/
- /* check for removal (sc_update[X]->dl[Y].percentage == 0)
- * and update sc_update & slice_config accordingly */
- flexran_check_and_remove_slices(mod_id);
-
- /* create new DL and UL slices if necessary */
- for (i = slice_config[mod_id]->n_dl; i < sc_update[mod_id]->n_dl; i++) {
- flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id);
- }
- for (i = slice_config[mod_id]->n_ul; i < sc_update[mod_id]->n_ul; i++) {
- flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id);
- }
- slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id);
- slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id);
- changes += apply_new_slice_config(mod_id, slice_config[mod_id], sc_update[mod_id]);
- for (i = 0; i < slice_config[mod_id]->n_dl; i++) {
- changes += apply_new_slice_dl_config(mod_id,
- slice_config[mod_id]->dl[i],
- sc_update[mod_id]->dl[i]);
- flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]);
- }
- for (i = 0; i < slice_config[mod_id]->n_ul; i++) {
- changes += apply_new_slice_ul_config(mod_id,
- slice_config[mod_id]->ul[i],
- sc_update[mod_id]->ul[i]);
- flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]);
- }
- flexran_agent_read_slice_config(mod_id, slice_config[mod_id]);
- if (n_ue_slice_assoc_updates > 0) {
- changes += apply_ue_slice_assoc_update(mod_id);
- }
- if (changes > 0)
- LOG_I(FLEXRAN_AGENT, "[%d] slice configuration: applied %d changes\n", mod_id, changes);
-
- pthread_mutex_unlock(&sc_update_mtx);
-}
-
-Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id)
-{
- if (!slice_config[mod_id]) return NULL;
- Protocol__FlexSliceConfig *config = NULL;
-
- pthread_mutex_lock(&sc_update_mtx);
- config = flexran_agent_create_slice_config(slice_config[mod_id]->n_dl,
- slice_config[mod_id]->n_ul);
- if (!config) {
- pthread_mutex_unlock(&sc_update_mtx);
- return NULL;
- }
- config->has_intraslice_share_active = 1;
- config->intraslice_share_active = slice_config[mod_id]->intraslice_share_active;
- config->has_interslice_share_active = 1;
- config->interslice_share_active = slice_config[mod_id]->interslice_share_active;
- for (int i = 0; i < slice_config[mod_id]->n_dl; ++i) {
- if (!config->dl[i]) continue;
- config->dl[i]->has_id = 1;
- config->dl[i]->id = slice_config[mod_id]->dl[i]->id;
- config->dl[i]->has_label = 1;
- config->dl[i]->label = slice_config[mod_id]->dl[i]->label;
- config->dl[i]->has_percentage = 1;
- config->dl[i]->percentage = slice_config[mod_id]->dl[i]->percentage;
- config->dl[i]->has_isolation = 1;
- config->dl[i]->isolation = slice_config[mod_id]->dl[i]->isolation;
- config->dl[i]->has_priority = 1;
- config->dl[i]->priority = slice_config[mod_id]->dl[i]->priority;
- config->dl[i]->has_position_low = 1;
- config->dl[i]->position_low = slice_config[mod_id]->dl[i]->position_low;
- config->dl[i]->has_position_high = 1;
- config->dl[i]->position_high = slice_config[mod_id]->dl[i]->position_high;
- config->dl[i]->has_maxmcs = 1;
- config->dl[i]->maxmcs = slice_config[mod_id]->dl[i]->maxmcs;
- config->dl[i]->n_sorting = slice_config[mod_id]->dl[i]->n_sorting;
- config->dl[i]->sorting = calloc(config->dl[i]->n_sorting, sizeof(Protocol__FlexDlSorting));
- if (!config->dl[i]->sorting) config->dl[i]->n_sorting = 0;
- for (int j = 0; j < config->dl[i]->n_sorting; ++j)
- config->dl[i]->sorting[j] = slice_config[mod_id]->dl[i]->sorting[j];
- config->dl[i]->has_accounting = 1;
- config->dl[i]->accounting = slice_config[mod_id]->dl[i]->accounting;
- config->dl[i]->scheduler_name = strdup(slice_config[mod_id]->dl[i]->scheduler_name);
- }
- for (int i = 0; i < slice_config[mod_id]->n_ul; ++i) {
- if (!config->ul[i]) continue;
- config->ul[i]->has_id = 1;
- config->ul[i]->id = slice_config[mod_id]->ul[i]->id;
- config->ul[i]->has_label = 1;
- config->ul[i]->label = slice_config[mod_id]->ul[i]->label;
- config->ul[i]->has_percentage = 1;
- config->ul[i]->percentage = slice_config[mod_id]->ul[i]->percentage;
- config->ul[i]->has_isolation = 1;
- config->ul[i]->isolation = slice_config[mod_id]->ul[i]->isolation;
- config->ul[i]->has_priority = 1;
- config->ul[i]->priority = slice_config[mod_id]->ul[i]->priority;
- config->ul[i]->has_first_rb = 1;
- config->ul[i]->first_rb = slice_config[mod_id]->ul[i]->first_rb;
- config->ul[i]->has_maxmcs = 1;
- config->ul[i]->maxmcs = slice_config[mod_id]->ul[i]->maxmcs;
- config->ul[i]->n_sorting = slice_config[mod_id]->ul[i]->n_sorting;
- config->ul[i]->sorting = calloc(config->ul[i]->n_sorting, sizeof(Protocol__FlexUlSorting));
- if (!config->ul[i]->sorting) config->ul[i]->n_sorting = 0;
- for (int j = 0; j < config->ul[i]->n_sorting; ++j)
- config->ul[i]->sorting[j] = slice_config[mod_id]->ul[i]->sorting[j];
- config->ul[i]->has_accounting = 1;
- config->ul[i]->accounting = slice_config[mod_id]->ul[i]->accounting;
- config->ul[i]->scheduler_name = strdup(slice_config[mod_id]->ul[i]->scheduler_name);
- }
-
- pthread_mutex_unlock(&sc_update_mtx);
- return config;
}
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h
index 2f9f99c740..5a8d4f31aa 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h
@@ -115,7 +115,16 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id);
/* Inform controller about possibility to update slice configuration */
void flexran_agent_slice_update(mid_t mod_id);
-/* return a pointer to the current config */
-Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id);
+/* marks slice_config so that it can be applied later. Takes ownership of the
+ * FlexSliceConfig message */
+void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice);
+
+/* inserts a new ue_config into the structure keeping ue to slice association
+ * updates and marks so it can be applied. Takes ownership of the FlexUeConfig message */
+void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config);
+
+/* free slice_config part of flexCellConfig, filled in
+ * flexran_agent_fill_mac_cell_config() */
+void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf);
#endif
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
index a85cbac543..93de0b11ec 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
@@ -33,14 +33,6 @@
#include "flexran_agent_mac_internal.h"
#include "flexran_agent_mac_slice_verification.h"
-/* from flexran_agent_mac.c */
-extern Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES];
-extern Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES];
-extern int perform_slice_config_update_count;
-extern Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES];
-extern int n_ue_slice_assoc_updates;
-extern pthread_mutex_t sc_update_mtx;
-
Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_message,
Protocol__FlexranMessage *old_message) {
@@ -1033,724 +1025,166 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) {
}
-Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul)
-{
- int i;
- Protocol__FlexSliceConfig *fsc = malloc(sizeof(Protocol__FlexSliceConfig));
- if (!fsc) return NULL;
- protocol__flex_slice_config__init(fsc);
-
- /* say there are n_dl slices but reserve memory for up to MAX_NUM_SLICES so
- * we don't need to reserve again later */
- fsc->n_dl = n_dl;
- fsc->dl = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexDlSlice *));
- if (!fsc->dl) fsc->n_dl = 0;
- for (i = 0; i < MAX_NUM_SLICES; i++) {
- fsc->dl[i] = malloc(sizeof(Protocol__FlexDlSlice));
- if (!fsc->dl[i]) continue;
- protocol__flex_dl_slice__init(fsc->dl[i]);
- }
-
- /* as above */
- fsc->n_ul = m_ul;
- fsc->ul = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexUlSlice *));
- if (!fsc->ul) fsc->n_ul = 0;
- for (i = 0; i < MAX_NUM_SLICES; i++) {
- fsc->ul[i] = malloc(sizeof(Protocol__FlexUlSlice));
- if (!fsc->ul[i]) continue;
- protocol__flex_ul_slice__init(fsc->ul[i]);
- }
- return fsc;
-}
-
-void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s)
-{
- s->intraslice_share_active = flexran_get_intraslice_sharing_active(mod_id);
- s->has_intraslice_share_active = 1;
- s->interslice_share_active = flexran_get_interslice_sharing_active(mod_id);
- s->has_interslice_share_active = 1;
-}
-
-void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice)
-{
- dl_slice->id = flexran_get_dl_slice_id(mod_id, slice_idx);
- dl_slice->has_id = 1;
- /* read label from corresponding sc_update entry or give default */
- dl_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB;
- dl_slice->has_label = 1;
- for (int i = 0; i < sc_update[mod_id]->n_dl; i++) {
- if (sc_update[mod_id]->dl[i]->id == dl_slice->id
- && sc_update[mod_id]->dl[i]->has_label) {
- dl_slice->label = sc_update[mod_id]->dl[i]->label;
- break;
- }
- }
- dl_slice->percentage = flexran_get_dl_slice_percentage(mod_id, slice_idx);
- dl_slice->has_percentage = 1;
- dl_slice->isolation = flexran_get_dl_slice_isolation(mod_id, slice_idx);
- dl_slice->has_isolation = 1;
- dl_slice->priority = flexran_get_dl_slice_priority(mod_id, slice_idx);
- dl_slice->has_priority = 1;
- dl_slice->position_low = flexran_get_dl_slice_position_low(mod_id, slice_idx);
- dl_slice->has_position_low = 1;
- dl_slice->position_high = flexran_get_dl_slice_position_high(mod_id, slice_idx);
- dl_slice->has_position_high = 1;
- dl_slice->maxmcs = flexran_get_dl_slice_maxmcs(mod_id, slice_idx);
- dl_slice->has_maxmcs = 1;
- dl_slice->n_sorting = flexran_get_dl_slice_sorting(mod_id, slice_idx, &dl_slice->sorting);
- if (dl_slice->n_sorting < 1) dl_slice->sorting = NULL;
- dl_slice->accounting = flexran_get_dl_slice_accounting_policy(mod_id, slice_idx);
- dl_slice->has_accounting = 1;
- const char *s_name = flexran_get_dl_slice_scheduler(mod_id, slice_idx);
- if (!dl_slice->scheduler_name
- || strcmp(dl_slice->scheduler_name, s_name) != 0) {
- dl_slice->scheduler_name = realloc(dl_slice->scheduler_name, strlen(s_name) + 1);
- strcpy(dl_slice->scheduler_name, s_name);
- }
-}
-
-void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice)
-{
- ul_slice->id = flexran_get_ul_slice_id(mod_id, slice_idx);
- ul_slice->has_id = 1;
- /* read label from corresponding sc_update entry or give default */
- ul_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB;
- ul_slice->has_label = 1;
- for (int i = 0; i < sc_update[mod_id]->n_ul; i++) {
- if (sc_update[mod_id]->ul[i]->id == ul_slice->id
- && sc_update[mod_id]->ul[i]->has_label) {
- ul_slice->label = sc_update[mod_id]->ul[i]->label;
- break;
- }
- }
- ul_slice->percentage = flexran_get_ul_slice_percentage(mod_id, slice_idx);
- ul_slice->has_percentage = 1;
- /*ul_slice->isolation = flexran_get_ul_slice_isolation(mod_id, slice_idx);*/
- ul_slice->has_isolation = 0;
- /*ul_slice->priority = flexran_get_ul_slice_priority(mod_id, slice_idx);*/
- ul_slice->has_priority = 0;
- ul_slice->first_rb = flexran_get_ul_slice_first_rb(mod_id, slice_idx);
- ul_slice->has_first_rb = 1;
- /*ul_slice-> = flexran_get_ul_slice_length_rb(mod_id, slice_idx);
- ul_slice->has_length_rb = 0;*/
- ul_slice->maxmcs = flexran_get_ul_slice_maxmcs(mod_id, slice_idx);
- ul_slice->has_maxmcs = 1;
- ul_slice->n_sorting = 0;
- /*if (ul_slice->sorting) {
- free(ul_slice->sorting);
- ul_slice->sorting = NULL;
- }
- ul_slice->n_sorting = flexran_get_ul_slice_sorting(mod_id, slice_idx, &ul_slice->sorting);
- if (ul_slice->n_sorting < 1) ul_slice->sorting = NULL;*/
- /*ul_slice->accounting = flexran_get_ul_slice_accounting_policy(mod_id, slice_idx);*/
- ul_slice->has_accounting = 0;
- const char *s_name = flexran_get_ul_slice_scheduler(mod_id, slice_idx);
- if (!ul_slice->scheduler_name
- || strcmp(ul_slice->scheduler_name, s_name) != 0) {
- ul_slice->scheduler_name = realloc(ul_slice->scheduler_name, strlen(s_name) + 1);
- strcpy(ul_slice->scheduler_name, s_name);
- }
-}
-
-int check_dl_sorting_update(Protocol__FlexDlSlice *old, Protocol__FlexDlSlice *new)
-{
- /* sorting_update => true when old->n_sorting == 0 or different numbers of
- * elements; otherwise will check * element-wise */
- int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting);
- for (int i = 0; i < old->n_sorting && !sorting_update; ++i) {
- sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]);
- }
- return sorting_update;
-}
-
-int check_ul_sorting_update(Protocol__FlexUlSlice *old, Protocol__FlexUlSlice *new)
-{
- /* sorting_update => true when old->n_sorting == 0 or different numbers of
- * elements; otherwise will check * element-wise */
- int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting);
- for (int i = 0; i < old->n_sorting && !sorting_update; ++i) {
- sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]);
- }
- return sorting_update;
-}
-
-void overwrite_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *exist, Protocol__FlexSliceConfig *update)
-{
- if (update->has_intraslice_share_active
- && exist->intraslice_share_active != update->intraslice_share_active) {
- LOG_I(FLEXRAN_AGENT, "[%d] update intraslice_share_active: %d -> %d\n",
- mod_id, exist->intraslice_share_active, update->intraslice_share_active);
- exist->intraslice_share_active = update->intraslice_share_active;
- exist->has_intraslice_share_active = 1;
- }
- if (update->has_interslice_share_active
- && exist->interslice_share_active != update->interslice_share_active) {
- LOG_I(FLEXRAN_AGENT, "[%d] update interslice_share_active: %d -> %d\n",
- mod_id, exist->interslice_share_active, update->interslice_share_active);
- exist->interslice_share_active = update->interslice_share_active;
- exist->has_interslice_share_active = 1;
- }
-}
-
-void overwrite_slice_config_dl(mid_t mod_id, Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update)
-{
- if (update->label != exist->label) {
- LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update label: %d -> %d\n",
- mod_id, update->id, exist->label, update->label);
- exist->label = update->label;
- exist->has_label = 1;
- }
- if (update->percentage != exist->percentage) {
- LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update percentage: %d -> %d\n",
- mod_id, update->id, exist->percentage, update->percentage);
- exist->percentage = update->percentage;
- exist->has_percentage = 1;
- }
- if (update->isolation != exist->isolation) {
- LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update isolation: %d -> %d\n",
- mod_id, update->id, exist->isolation, update->isolation);
- exist->isolation = update->isolation;
- exist->has_isolation = 1;
- }
- if (update->priority != exist->priority) {
- LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update priority: %d -> %d\n",
- mod_id, update->id, exist->priority, update->priority);
- exist->priority = update->priority;
- exist->has_priority = 1;
- }
- if (update->position_low != exist->position_low) {
- LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_low: %d -> %d\n",
- mod_id, update->id, exist->position_low, update->position_low);
- exist->position_low = update->position_low;
- exist->has_position_low = 1;
- }
- if (update->position_high != exist->position_high) {
- LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_high: %d -> %d\n",
- mod_id, update->id, exist->position_high, update->position_high);
- exist->position_high = update->position_high;
- exist->has_position_high = 1;
- }
- if (update->maxmcs != exist->maxmcs) {
- LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update maxmcs: %d -> %d\n",
- mod_id, update->id, exist->maxmcs, update->maxmcs);
- exist->maxmcs = update->maxmcs;
- exist->has_maxmcs = 1;
- }
- if (check_dl_sorting_update(exist, update)) {
- LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update sorting array\n", mod_id, update->id);
- if (exist->n_sorting != update->n_sorting) {
- exist->n_sorting = update->n_sorting;
- exist->sorting = realloc(exist->sorting, exist->n_sorting * sizeof(Protocol__FlexDlSorting));
- if (!exist->sorting) exist->n_sorting = 0;
- }
- for (int i = 0; i < exist->n_sorting; i++)
- exist->sorting[i] = update->sorting[i];
- }
- if (update->accounting != exist->accounting) {
- LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update accounting: %d -> %d\n",
- mod_id, update->id, exist->accounting, update->accounting);
- exist->accounting = update->accounting;
- exist->has_accounting = 1;
- }
- if (!exist->scheduler_name
- || strcmp(update->scheduler_name, exist->scheduler_name) != 0) {
- LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update scheduler: %s -> %s\n",
- mod_id, update->id, exist->scheduler_name, update->scheduler_name);
- if (exist->scheduler_name) free(exist->scheduler_name);
- exist->scheduler_name = strdup(update->scheduler_name);
- }
-}
-
-void overwrite_slice_config_ul(mid_t mod_id, Protocol__FlexUlSlice *exist, Protocol__FlexUlSlice *update)
-{
- if (update->label != exist->label) {
- LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update label: %d -> %d\n",
- mod_id, update->id, exist->label, update->label);
- exist->label = update->label;
- exist->has_label = 1;
- }
- if (update->percentage != exist->percentage) {
- LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update percentage: %d -> %d\n",
- mod_id, update->id, exist->percentage, update->percentage);
- exist->percentage = update->percentage;
- exist->has_percentage = 1;
- }
- if (update->isolation != exist->isolation) {
- LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update isolation: %d -> %d\n",
- mod_id, update->id, exist->isolation, update->isolation);
- exist->isolation = update->isolation;
- exist->has_isolation = 1;
- }
- if (update->priority != exist->priority) {
- LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update priority: %d -> %d\n",
- mod_id, update->id, exist->priority, update->priority);
- exist->priority = update->priority;
- exist->has_priority = 1;
- }
- if (update->first_rb != exist->first_rb) {
- LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update first_rb: %d -> %d\n",
- mod_id, update->id, exist->first_rb, update->first_rb);
- exist->first_rb = update ->first_rb;
- exist->has_first_rb = 1;
- }
- /*if (update->lenght_rb != exist->lenght_rb) {
- LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update lenght_rb: %d -> %d\n",
- mod_id, update->id, exist->lenght_rb, update->lenght_rb);
- exist->lenght_rb = update->lenght_rb;
- }*/
- if (update->maxmcs != exist->maxmcs) {
- LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update maxmcs: %d -> %d\n",
- mod_id, update->id, exist->maxmcs, update->maxmcs);
- exist->maxmcs = update->maxmcs;
- exist->has_maxmcs = 1;
- }
- /* TODO
- int sorting_update = 0;
- int n = min(exist->n_sorting, update->n_sorting);
- int i = 0;
- while (i < n && !sorting_update) {
- sorting_update = sorting_update || (update->sorting[i] != exist->sorting[i]);
- i++;
- }
- if (sorting_update) {
- LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update sorting array\n", update->id, mod_id);
- if (exist->n_sorting != update->n_sorting)
- LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] only writing %d elements\n",
- mod_id, update->id, n);
- for (i = 0; i < n; i++)
- exist->sorting[i] = update->sorting[i];
- }
- */
- if (update->accounting != exist->accounting) {
- LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update accounting: %d -> %d\n",
- mod_id, update->id, exist->accounting, update->accounting);
- exist->accounting = update->accounting;
- exist->has_accounting = 1;
- }
- if (!exist->scheduler_name
- || strcmp(update->scheduler_name, exist->scheduler_name) != 0) {
- LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update scheduler: %s -> %s\n",
- mod_id, update->id, exist->scheduler_name, update->scheduler_name);
- if (exist->scheduler_name) free(exist->scheduler_name);
- exist->scheduler_name = strdup(update->scheduler_name);
- }
-}
-
-void fill_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *s, Protocol__FlexDlSlice *from)
-{
- /* function fills slice with information from another slice or with default
- * values (currently slice 0) if from is NULL */
- /* TODO fill the slice depending on the chosen label */
- if (!s->has_label) {
- s->has_label = 1;
- s->label = from ? from->label : sc_update[mod_id]->dl[0]->label;
- }
- if (!s->has_percentage) {
- s->has_percentage = 1;
- s->percentage = from ? from->percentage : sc_update[mod_id]->dl[0]->percentage;
- }
- if (!s->has_isolation) {
- s->has_isolation = 1;
- s->isolation = from ? from->isolation : sc_update[mod_id]->dl[0]->isolation;
- }
- if (!s->has_priority) {
- s->has_priority = 1;
- s->priority = from ? from->priority : sc_update[mod_id]->dl[0]->priority;
- }
- if (!s->has_position_low) {
- s->has_position_low = 1;
- s->position_low = from ? from->position_low : sc_update[mod_id]->dl[0]->position_low;
- }
- if (!s->has_position_high) {
- s->has_position_high = 1;
- s->position_high = from ? from->position_high : sc_update[mod_id]->dl[0]->position_high;
- }
- if (!s->has_maxmcs) {
- s->has_maxmcs = 1;
- s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->dl[0]->maxmcs;
- }
- if (s->n_sorting == 0) {
- s->n_sorting = from ? from->n_sorting : sc_update[mod_id]->dl[0]->n_sorting;
- s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexDlSorting));
- if (!s->sorting) s->n_sorting = 0;
- for (int i = 0; i < s->n_sorting; ++i)
- s->sorting[i] = from ? from->sorting[i] : sc_update[0]->dl[0]->sorting[i];
- }
- if (!s->has_accounting) {
- s->accounting = from ? from->accounting : sc_update[mod_id]->dl[0]->accounting;
- }
- if (!s->scheduler_name) {
- s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->dl[0]->scheduler_name);
- }
-}
-
-Protocol__FlexDlSlice *get_existing_dl_slice(mid_t mod_id, int id)
-{
- for (int i = 0; i < sc_update[mod_id]->n_dl; ++i) {
- if (id == sc_update[mod_id]->dl[i]->id) {
- return sc_update[mod_id]->dl[i];
- }
- }
- return NULL;
-}
-
-Protocol__FlexDlSlice *create_new_dl_slice(mid_t mod_id, int id)
-{
- LOG_I(FLEXRAN_AGENT,
- "[%d] Creating DL slice with ID %d, taking default values from DL slice 0\n",
- mod_id, id);
- Protocol__FlexDlSlice *to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl];
- sc_update[mod_id]->n_dl++;
- AssertFatal(sc_update[mod_id]->n_dl <= MAX_NUM_SLICES,
- "cannot create more than MAX_NUM_SLICES\n");
- to->id = id;
- return to;
-}
-
-void fill_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *s, Protocol__FlexUlSlice *from)
-{
- /* function fills slice with information from another slice or with default
- * values (currently slice 0) if from is NULL */
- /* TODO fill the slice depending on the chosen label */
- if (!s->has_label) {
- s->has_label = 1;
- s->label = from ? from->label : sc_update[mod_id]->ul[0]->label;
- }
- if (!s->has_percentage) {
- s->has_percentage = 1;
- s->percentage = from ? from->percentage : sc_update[mod_id]->ul[0]->percentage;
- }
- if (!s->has_isolation) {
- s->has_isolation = 1;
- s->isolation = from ? from->isolation : sc_update[mod_id]->ul[0]->isolation;
- }
- if (!s->has_priority) {
- s->has_priority = 1;
- s->priority = from ? from->priority : sc_update[mod_id]->ul[0]->priority;
- }
- if (!s->has_first_rb) {
- s->has_first_rb = 1;
- s->first_rb = from ? from->first_rb : sc_update[mod_id]->ul[0]->first_rb;
- }
- if (!s->has_maxmcs) {
- s->has_maxmcs = 1;
- s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->ul[0]->maxmcs;
- }
- if (s->n_sorting == 0) {
- s->n_sorting = from ? from->n_sorting : sc_update[0]->ul[0]->n_sorting;
- s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexUlSorting));
- if (!s->sorting) s->n_sorting = 0;
- for (int i = 0; i < s->n_sorting; ++i)
- s->sorting[i] = from ? from->sorting[i] : sc_update[0]->ul[0]->sorting[i];
- }
- if (!s->has_accounting) {
- s->accounting = from ? from->accounting : sc_update[0]->ul[0]->accounting;
- }
- if (!s->scheduler_name) {
- s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->ul[0]->scheduler_name);
- }
-}
-
-Protocol__FlexUlSlice *get_existing_ul_slice(mid_t mod_id, int id)
-{
- for (int i = 0; i < sc_update[mod_id]->n_ul; ++i) {
- if (id == sc_update[mod_id]->ul[i]->id) {
- return sc_update[mod_id]->ul[i];
- }
- }
- return NULL;
-}
-
-Protocol__FlexUlSlice *create_new_ul_slice(mid_t mod_id, int id)
-{
- LOG_I(FLEXRAN_AGENT,
- "[%d] Creating UL slice with ID %d, taking default values from UL slice 0\n",
- mod_id, id);
- Protocol__FlexUlSlice *to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul];
- sc_update[mod_id]->n_ul++;
- AssertFatal(sc_update[mod_id]->n_ul <= MAX_NUM_SLICES,
- "cannot create more than MAX_NUM_SLICES\n");
- to->id = id;
- return to;
-}
-
-void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup)
-{
- int verified = 1;
- if (!sc_update[mod_id]) {
- LOG_E(FLEXRAN_AGENT, "Can not update slice policy (no existing slice profile)\n");
- return;
- }
-
- pthread_mutex_lock(&sc_update_mtx);
- /* no need for tests in the current state as there are only two protobuf
- * bools for intra-/interslice sharing. The function applies new values if
- * applicable */
- overwrite_slice_config(mod_id, sc_update[mod_id], sup);
-
- if (sup->n_dl == 0) {
- LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id);
+void update_or_remove_dl(mid_t mod_id, Protocol__FlexSlice *s) {
+ if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET
+ && !s->label && !s->scheduler) {
+ LOG_I(FLEXRAN_AGENT, "remove DL slice ID %d\n", s->id);
+ const int rc = flexran_remove_dl_slice(mod_id, s);
+ if (!rc)
+ LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id);
} else {
- /* verify slice parameters */
- for (int i = 0; i < sup->n_dl; i++) {
- if (!sup->dl[i]->has_id) {
- verified = 0;
- break;
- }
- Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id);
- /* fill up so that the slice is complete. This way, we don't need to
- * worry about it later */
- fill_dl_slice(mod_id, sup->dl[i], dls);
- verified = verified && flexran_verify_dl_slice(mod_id, sup->dl[i]);
- if (!verified) break;
- }
-
- /* verify group-based parameters (e.g. sum percentage should not exceed
- * 100%). Can be used to perform admission control */
- verified = verified && flexran_verify_group_dl_slices(mod_id,
- sc_update[mod_id]->dl, sc_update[mod_id]->n_dl, sup->dl, sup->n_dl);
-
- if (verified) {
- for (int i = 0; i < sup->n_dl; i++) {
- /* if all verifications were successful, get existing slice for ID or
- * create new one and overwrite with the update */
- Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id);
- if (!dls) dls = create_new_dl_slice(mod_id, sup->dl[i]->id);
- overwrite_slice_config_dl(mod_id, dls, sup->dl[i]);
- }
- } else {
- LOG_E(FLEXRAN_AGENT, "[%d] DL slice verification failed, refusing application\n", mod_id);
- }
+ LOG_I(FLEXRAN_AGENT, "updating DL slice ID %d\n", s->id);
+ const int rc = flexran_create_dl_slice(mod_id, s);
+ if (rc < 0)
+ LOG_W(FLEXRAN_AGENT,
+ "error while update slice ID %d: flexran_create_dl_slice() -> %d\n",
+ s->id, rc);
}
+}
- verified = 1;
- if (sup->n_ul == 0) {
- LOG_I(FLEXRAN_AGENT, "[%d] no UL slice configuration in flex_slice_config message\n", mod_id);
+void update_or_remove_ul(mid_t mod_id, Protocol__FlexSlice *s) {
+ if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET
+ && !s->label && !s->scheduler) {
+ LOG_I(FLEXRAN_AGENT, "remove UL slice ID %d\n", s->id);
+ const int rc = flexran_remove_ul_slice(mod_id, s);
+ if (!rc)
+ LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id);
} else {
- /* verify slice parameters */
- for (int i = 0; i < sup->n_ul; i++) {
- if (!sup->ul[i]->has_id) {
- verified = 0;
- break;
- }
- Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id);
- /* fill up so that the slice is complete. This way, we don't need to
- * worry about it later */
- fill_ul_slice(mod_id, sup->ul[i], uls);
- verified = verified && flexran_verify_ul_slice(mod_id, sup->ul[i]);
- if (!verified) break;
- }
-
- /* verify group-based parameters (e.g. sum percentage should not exceed
- * 100%). Can be used to perform admission control */
- verified = verified && flexran_verify_group_ul_slices(mod_id,
- sc_update[mod_id]->ul, sc_update[mod_id]->n_ul, sup->ul, sup->n_ul);
-
- if (verified) {
- for (int i = 0; i < sup->n_ul; i++) {
- /* if all verifications were successful, get existing slice for ID or
- * create new one and overwrite with the update */
- Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id);
- if (!uls) uls = create_new_ul_slice(mod_id, sup->ul[i]->id);
- overwrite_slice_config_ul(mod_id, uls, sup->ul[i]);
- }
- } else {
- LOG_E(FLEXRAN_AGENT, "[%d] UL slice verification failed, refusing application\n", mod_id);
- }
+ LOG_I(FLEXRAN_AGENT, "updating UL slice ID %d\n", s->id);
+ const int rc = flexran_create_ul_slice(mod_id, s);
+ if (rc < 0)
+ LOG_W(FLEXRAN_AGENT,
+ "error while updating slice ID %d: flexran_create_ul_slice() -> %d)\n",
+ s->id, rc);
}
- pthread_mutex_unlock(&sc_update_mtx);
-
- perform_slice_config_update_count = 1;
}
-int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news)
-{
- /* not setting the old configuration is intentional, as it will be picked up
- * later when reading the configuration. There is thus a direct feedback
- * whether it has been set. */
- int changes = 0;
- if (olds->intraslice_share_active != news->intraslice_share_active) {
- flexran_set_intraslice_sharing_active(mod_id, news->intraslice_share_active);
- changes++;
- }
- if (olds->interslice_share_active != news->interslice_share_active) {
- flexran_set_interslice_sharing_active(mod_id, news->interslice_share_active);
- changes++;
- }
- return changes;
-}
-
-int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc)
-{
- /* not setting the old configuration is intentional, as it will be picked up
- * later when reading the configuration. There is thus a direct feedback
- * whether it has been set. */
- int changes = 0;
- int slice_idx = flexran_find_dl_slice(mod_id, newc->id);
- if (slice_idx < 0) {
- LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id);
- return 0;
- }
- if (oldc->percentage != newc->percentage) {
- flexran_set_dl_slice_percentage(mod_id, slice_idx, newc->percentage);
- changes++;
- }
- if (oldc->isolation != newc->isolation) {
- flexran_set_dl_slice_isolation(mod_id, slice_idx, newc->isolation);
- changes++;
- }
- if (oldc->priority != newc->priority) {
- flexran_set_dl_slice_priority(mod_id, slice_idx, newc->priority);
- changes++;
- }
- if (oldc->position_low != newc->position_low) {
- flexran_set_dl_slice_position_low(mod_id, slice_idx, newc->position_low);
- changes++;
- }
- if (oldc->position_high != newc->position_high) {
- flexran_set_dl_slice_position_high(mod_id, slice_idx, newc->position_high);
- changes++;
- }
- if (oldc->maxmcs != newc->maxmcs) {
- flexran_set_dl_slice_maxmcs(mod_id, slice_idx, newc->maxmcs);
- changes++;
- }
- if (check_dl_sorting_update(oldc, newc)) {
- flexran_set_dl_slice_sorting(mod_id, slice_idx, newc->sorting, newc->n_sorting);
- changes++;
- }
- if (oldc->accounting != newc->accounting) {
- flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting);
- changes++;
- }
- if (!oldc->scheduler_name
- || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) {
- int ret = flexran_set_dl_slice_scheduler(mod_id, slice_idx, newc->scheduler_name);
- AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n",
- newc->id, slice_idx);
- changes++;
- }
- return changes;
-}
-
-int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc)
-{
- /* not setting the old configuration is intentional, as it will be picked up
- * later when reading the configuration. There is thus a direct feedback
- * whether it has been set. */
- int changes = 0;
- int slice_idx = flexran_find_ul_slice(mod_id, newc->id);
- if (slice_idx < 0) {
- LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id);
- return 0;
- }
- if (oldc->percentage != newc->percentage) {
- flexran_set_ul_slice_percentage(mod_id, slice_idx, newc->percentage);
- changes++;
- }
- if (oldc->isolation != newc->isolation) {
- /*flexran_set_ul_slice_isolation(mod_id, slice_idx, newc->isolation);
- *changes++;*/
- LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting isolation is not supported\n",
- mod_id, newc->id);
- }
- if (oldc->priority != newc->priority) {
- /*flexran_set_ul_slice_priority(mod_id, slice_idx, newc->priority);
- *changes++;*/
- LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the priority is not supported\n",
- mod_id, newc->id);
- }
- if (oldc->first_rb != newc->first_rb) {
- flexran_set_ul_slice_first_rb(mod_id, slice_idx, newc->first_rb);
- changes++;
- }
- /*if (oldc->length_rb != newc->length_rb) {
- flexran_set_ul_slice_length_rb(mod_id, slice_idx, newc->length_rb);
- changes++;
- LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting length_rb is not supported\n",
- mod_id, newc->id);
- }*/
- if (oldc->maxmcs != newc->maxmcs) {
- flexran_set_ul_slice_maxmcs(mod_id, slice_idx, newc->maxmcs);
- changes++;
- }
- /*if (check_ul_sorting_update(oldc, newc)) {
- flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n);
- changes++;
- LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the sorting is not supported\n",
- mod_id, newc->id);
- }*/
- if (oldc->accounting != newc->accounting) {
- /*flexran_set_ul_slice_accounting_policy(mod_id, slice_idx, newc->accounting);
- *changes++;*/
- LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n",
- mod_id, newc->id);
- }
- if (!oldc->scheduler_name
- || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) {
- int ret = flexran_set_ul_slice_scheduler(mod_id, slice_idx, newc->scheduler_name);
- AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n",
- newc->id, slice_idx);
- changes++;
- }
- return changes;
-}
-
-void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config)
-{
- if (n_ue_slice_assoc_updates == MAX_NUM_SLICES) {
- LOG_E(FLEXRAN_AGENT,
- "[%d] can not handle flex_ue_config message, buffer is full; try again later\n",
- mod_id);
+void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *dl) {
+ if (!dl)
return;
+
+ Protocol__FlexSliceAlgorithm dl_algo = flexran_get_dl_slice_algo(mod_id);
+ if (dl->has_algorithm && dl_algo != dl->algorithm) {
+ LOG_I(FLEXRAN_AGENT, "loading new DL slice algorithm %d\n", dl->algorithm);
+ dl_algo = dl->algorithm;
+ flexran_set_dl_slice_algo(mod_id, dl_algo);
}
+
+ /* first update existing slices, then create new. Thus, we go through the
+ * list twice. First round, if a slice exists, handle and mark as such. Then,
+ * apply all others in the second round */
+ if (dl->n_slices > 0) {
+ if (dl_algo == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
+ LOG_E(FLEXRAN_AGENT, "cannot update slices: no algorithm loaded\n");
+ return;
+ }
+ int handled_dl[dl->n_slices];
+ for (int i = 0; i < dl->n_slices; ++i) {
+ if (flexran_find_dl_slice(mod_id, dl->slices[i]->id) < 0) {
+ handled_dl[i] = 0;
+ continue;
+ }
+ update_or_remove_dl(mod_id, dl->slices[i]);
+ handled_dl[i] = 1;
+ }
+ for (int i = 0; i < dl->n_slices; ++i) {
+ if (handled_dl[i])
+ continue;
+ update_or_remove_dl(mod_id, dl->slices[i]);
+ }
+ }
+
+ if (dl->scheduler) {
+ if (dl_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
+ LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n");
+ return;
+ }
+ LOG_I(FLEXRAN_AGENT, "loading DL new scheduling algorithm '%s'\n", dl->scheduler);
+ const int rc = flexran_set_dl_scheduler(mod_id, dl->scheduler);
+ if (rc < 0) {
+ LOG_E(FLEXRAN_AGENT,
+ "error while updating scheduling algorithm: "
+ "flexran_update_dl_sched_algo() -> %d)\n",
+ rc);
+ return;
+ }
+ }
+}
+
+void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *ul) {
+ if (!ul)
+ return;
+
+ Protocol__FlexSliceAlgorithm ul_algo = flexran_get_ul_slice_algo(mod_id);
+ if (ul->has_algorithm && ul_algo != ul->algorithm) {
+ LOG_I(FLEXRAN_AGENT, "loading new UL slice algorithm %d\n", ul->algorithm);
+ ul_algo = ul->algorithm;
+ flexran_set_ul_slice_algo(mod_id, ul_algo);
+ }
+ if (ul->n_slices > 0) {
+ if (ul_algo == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
+ LOG_E(FLEXRAN_AGENT, "cannot update slices: no algorithm loaded\n");
+ return;
+ }
+ int handled_ul[ul->n_slices];
+ for (int i = 0; i < ul->n_slices; ++i) {
+ if (flexran_find_ul_slice(mod_id, ul->slices[i]->id) < 0) {
+ handled_ul[i] = 0;
+ continue;
+ }
+ update_or_remove_ul(mod_id, ul->slices[i]);
+ handled_ul[i] = 1;
+ }
+ for (int i = 0; i < ul->n_slices; ++i) {
+ if (handled_ul[i])
+ continue;
+ update_or_remove_ul(mod_id, ul->slices[i]);
+ }
+ }
+
+ if (ul->scheduler) {
+ if (ul_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
+ LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n");
+ return;
+ }
+ LOG_I(FLEXRAN_AGENT, "loading new UL scheduling algorithm '%s'\n", ul->scheduler);
+ const int rc = flexran_set_ul_scheduler(mod_id, ul->scheduler);
+ if (rc < 0) {
+ LOG_E(FLEXRAN_AGENT,
+ "error while updating scheduling algorithm: "
+ "flexran_update_dl_sched_algo() -> %d)\n",
+ rc);
+ return;
+ }
+ }
+}
+
+int apply_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config)
+{
if (!ue_config->has_rnti) {
LOG_E(FLEXRAN_AGENT,
"[%d] cannot update UE to slice association, no RNTI in flex_ue_config message\n",
mod_id);
- return;
+ return 0;
}
- if (ue_config->has_dl_slice_id)
- LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to DL slice ID %d\n",
- mod_id, ue_config->rnti, ue_config->dl_slice_id);
- if (ue_config->has_ul_slice_id)
- LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to UL slice ID %d\n",
- mod_id, ue_config->rnti, ue_config->ul_slice_id);
- ue_slice_assoc_update[n_ue_slice_assoc_updates++] = ue_config;
- perform_slice_config_update_count = 2;
-}
-
-int apply_ue_slice_assoc_update(mid_t mod_id)
-{
- int i;
- int changes = 0;
- for (i = 0; i < n_ue_slice_assoc_updates; i++) {
- int ue_id = find_UE_id(mod_id, ue_slice_assoc_update[i]->rnti);
- if (ue_id < 0 || ue_id > MAX_MOBILES_PER_ENB){
- LOG_E(FLEXRAN_AGENT,"UE_id %d is wrong!!\n",ue_id);
- continue;
- }
- if (ue_slice_assoc_update[i]->has_dl_slice_id) {
- int slice_idx = flexran_find_dl_slice(mod_id, ue_slice_assoc_update[i]->dl_slice_id);
- if (flexran_dl_slice_exists(mod_id, slice_idx)) {
- flexran_set_ue_dl_slice_idx(mod_id, ue_id, slice_idx);
- changes++;
- } else {
- LOG_W(FLEXRAN_AGENT, "[%d] DL slice %d does not exist, refusing change\n",
- mod_id, ue_slice_assoc_update[i]->dl_slice_id);
- }
- }
- if (ue_slice_assoc_update[i]->has_ul_slice_id) {
- int slice_idx = flexran_find_ul_slice(mod_id, ue_slice_assoc_update[i]->ul_slice_id);
- if (flexran_ul_slice_exists(mod_id, slice_idx)) {
- flexran_set_ue_ul_slice_idx(mod_id, ue_id, slice_idx);
- changes++;
- } else {
- LOG_W(FLEXRAN_AGENT, "[%d] UL slice %d does not exist, refusing change\n",
- mod_id, ue_slice_assoc_update[i]->ul_slice_id);
- }
+ int UE_id = flexran_get_mac_ue_id_rnti(mod_id, ue_config->rnti);
+ if (ue_config->has_dl_slice_id) {
+ if (flexran_get_dl_slice_algo(mod_id) == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
+ LOG_E(FLEXRAN_AGENT, "no DL slice algorithm loaded\n");
+ } else {
+ LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %04x - %d/UE %d to DL slice ID %d\n",
+ mod_id, ue_config->rnti, ue_config->rnti, UE_id, ue_config->dl_slice_id);
+ flexran_set_ue_dl_slice_id(mod_id, UE_id, ue_config->dl_slice_id);
}
}
- n_ue_slice_assoc_updates = 0;
- return changes;
+ if (ue_config->has_ul_slice_id) {
+ if (flexran_get_ul_slice_algo(mod_id) == PROTOCOL__FLEX_SLICE_ALGORITHM__None) {
+ LOG_E(FLEXRAN_AGENT, "no UL slice algorithm loaded\n");
+ } else {
+ LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %04x - %d/UE %d to UL slice ID %d\n",
+ mod_id, ue_config->rnti, ue_config->rnti, UE_id, ue_config->ul_slice_id);
+ flexran_set_ue_ul_slice_id(mod_id, UE_id, ue_config->ul_slice_id);
+ }
+ }
+ return 0;
}
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h
index 957fe6065e..9db5d61a11 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h
@@ -103,43 +103,11 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name);
/*** Functions for handling a slice config ***/
-/* allocate memory for a Protocol__FlexSliceConfig structure with n_dl DL slice
- * configs and m_ul UL slice configs */
-Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul);
-
-/* read the general slice parameters via RAN into the given
- * Protocol__FlexSliceConfig struct */
-void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s);
-
-/* read the DL slice config via the RAN into a given Protocol__FlexDlSlice
- * struct */
-void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice);
-
-/* read the UL slice config via the RAN into a given Protocol__FlexUlSlice
- * struct */
-void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice);
-
-/* reads content of slice over the sc_update structure, so that it can be
- * applied later by performing a diff between slice_config and sc_update */
-void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice);
-
-/* apply generic slice parameters (e.g. intra-/interslice sharing activated or
- * not) if there are changes. Returns the number of changed parameters. */
-int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news);
-
-/* apply new configuration of slice in DL if there are changes between the
- * parameters. Returns the number of changed parameters. */
-int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc);
-
-/* apply new configuration of slice in UL if there are changes between the
- * parameters. Returns the number of changed parameters. */
-int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc);
-
-/* inserts a new ue_config into the structure keeping ue to slice association
- * updates and marks so it can be applied */
-void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config);
+/* Prepare the application of a slicing config */
+void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *slice);
+void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *slice);
/* apply a new association between a UE and a slice (both DL and UL) */
-int apply_ue_slice_assoc_update(mid_t mod_id);
+int apply_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config);
#endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c
index 67329e91be..6e54e155c2 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c
@@ -28,346 +28,3 @@
#include "flexran_agent_mac_slice_verification.h"
-
-/* overlap check for UL slices, helper type */
-struct sregion_s {
- int start;
- int length;
-};
-
-/* forward declaration of locally-used verification functions */
-int flexran_dl_slice_verify_pct(int pct);
-int flexran_dl_slice_verify_priority(int prio);
-int flexran_dl_slice_verify_position(int pos_low, int pos_high);
-int flexran_dl_slice_verify_maxmcs(int maxmcs);
-int flexran_ul_slice_verify_pct(int pct);
-int flexran_ul_slice_verify_priority(int prio);
-int flexran_ul_slice_verify_first_rb(int first_rb);
-int flexran_ul_slice_verify_maxmcs(int maxmcs);
-int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n);
-
-int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls)
-{
- /* check mandatory parameters */
- if (!dls->has_id) {
- LOG_E(FLEXRAN_AGENT, "[%d] Incoming DL slice configuration has no ID\n", mod_id);
- return 0;
- }
-
- /* verify parameters individualy */
- /* label is enum */
- if (!flexran_dl_slice_verify_pct(dls->percentage)) {
- LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice percentage (%d)\n",
- mod_id, dls->id, dls->percentage);
- return 0;
- }
- /* isolation is a protobuf bool */
- if (!flexran_dl_slice_verify_priority(dls->priority)) {
- LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice priority (%d)\n",
- mod_id, dls->id, dls->priority);
- return 0;
- }
- if (!flexran_dl_slice_verify_position(dls->position_low, dls->position_high)) {
- LOG_E(FLEXRAN_AGENT,
- "[%d][DL slice %d] illegal DL slice position low (%d) and/or high (%d)\n",
- mod_id, dls->id, dls->position_low, dls->position_high);
- return 0;
- }
- if (!flexran_dl_slice_verify_maxmcs(dls->maxmcs)) {
- LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice max mcs %d\n",
- mod_id, dls->id, dls->maxmcs);
- return 0;
- }
- if (dls->n_sorting == 0) {
- LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting in DL slice\n",
- mod_id, dls->id);
- return 0;
- }
- if (!dls->sorting) {
- LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting found in DL slice\n",
- mod_id, dls->id);
- return 0;
- }
- /* sorting is an enum */
- /* accounting is an enum */
- if (!dls->scheduler_name) {
- LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no scheduler name found\n",
- mod_id, dls->id);
- return 0;
- }
- if (strcmp(dls->scheduler_name, "schedule_ue_spec") != 0) {
- LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] setting the scheduler to something "
- "different than schedule_ue_spec is currently not allowed\n",
- mod_id, dls->id);
- return 0;
- }
-
- return 1;
-}
-
-int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing,
- int n_ex, Protocol__FlexDlSlice **update, int n_up)
-{
- int i, j, n;
- int pct, pct_orig;
- /* for every update, array points to existing slice, or NULL if update
- * creates new slice */
- Protocol__FlexDlSlice *s[n_up];
- for (i = 0; i < n_up; i++) {
- s[i] = NULL;
- for (j = 0; j < n_ex; j++) {
- if (existing[j]->id == update[i]->id)
- s[i] = existing[j];
- }
- }
-
- /* check that number of created and number of added slices in total matches
- * [1,10] */
- n = n_ex;
- for (i = 0; i < n_up; i++) {
- /* new slice */
- if (!s[i]) n += 1;
- /* slice will be deleted */
- else if (s[i]->percentage == 0) n -= 1;
- /* else "only" an update */
- }
-
- if (n < 1 || n > MAX_NUM_SLICES) {
- LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting DL slices (%d -> %d)\n",
- mod_id, n_ex, n);
- return 0;
- }
-
- /* check that the sum of all slices percentages (including removed/added
- * slices) matches [1,100] */
- pct = 0;
- for (i = 0; i < n_ex; i++) {
- pct += existing[i]->percentage;
- }
- pct_orig = pct;
- for (i = 0; i < n_up; i++) {
- /* if there is an existing slice, subtract its percentage and add the
- * update's percentage */
- if (s[i])
- pct -= s[i]->percentage;
- pct += update[i]->percentage;
- }
- if (pct < 1 || pct > 100) {
- LOG_E(FLEXRAN_AGENT,
- "[%d] invalid total RB share for DL slices (%d%% -> %d%%)\n",
- mod_id, pct_orig, pct);
- return 0;
- }
-
- return 1;
-}
-
-int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls)
-{
- /* check mandatory parameters */
- if (!uls->has_id) {
- LOG_E(FLEXRAN_AGENT, "[%d] Incoming UL slice configuration has no ID\n", mod_id);
- return 0;
- }
-
- /* verify parameters individually */
- /* label is enum */
- if (!flexran_ul_slice_verify_pct(uls->percentage)) {
- LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n",
- mod_id, uls->id, uls->percentage);
- return 0;
- }
- /* isolation is a protobuf bool */
- if (!flexran_ul_slice_verify_priority(uls->priority)) {
- LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n",
- mod_id, uls->id, uls->priority);
- return 0;
- }
- if (!flexran_ul_slice_verify_first_rb(uls->first_rb)) {
- LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice first RB (%d)\n",
- mod_id, uls->id, uls->first_rb);
- return 0;
- }
- if (!flexran_ul_slice_verify_maxmcs(uls->maxmcs)) {
- LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice max mcs (%d)\n",
- mod_id, uls->id, uls->maxmcs);
- return 0;
- }
- /* TODO
- if (uls->n_sorting == 0) {
- LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting in UL slice\n",
- mod_id, uls->id);
- return 0;
- }
- if (!uls->sorting) {
- LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting found in UL slice\n",
- mod_id, uls->id);
- return 0;
- }
- */
- /* sorting is an enum */
- /* accounting is an enum */
- if (!uls->scheduler_name) {
- LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no scheduler name found\n",
- mod_id, uls->id);
- return 0;
- }
- if (strcmp(uls->scheduler_name, "schedule_ulsch_rnti") != 0) {
- LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] setting the scheduler to something "
- "different than schedule_ulsch_rnti is currently not allowed\n",
- mod_id, uls->id);
- return 0;
- }
-
- return 1;
-}
-
-int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing,
- int n_ex, Protocol__FlexUlSlice **update, int n_up)
-{
- int i, j, n;
- int pct, pct_orig;
- /* for every update, array "s" points to existing slice, or NULL if update
- * creates new slice; array "offs" gives the offset of this slice */
- Protocol__FlexUlSlice *s[n_up];
- int offs[n_up];
- for (i = 0; i < n_up; i++) {
- s[i] = NULL;
- offs[i] = 0;
- for (j = 0; j < n_ex; j++) {
- if (existing[j]->id == update[i]->id) {
- s[i] = existing[j];
- offs[i] = j;
- }
- }
- }
-
- /* check that number of created and number of added slices in total matches
- * [1,10] */
- n = n_ex;
- for (i = 0; i < n_up; i++) {
- /* new slice */
- if (!s[i]) n += 1;
- /* slice will be deleted */
- else if (s[i]->percentage == 0) n -= 1;
- /* else "only" an update */
- }
-
- if (n < 1 || n > MAX_NUM_SLICES) {
- LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting UL slices (%d -> %d)\n",
- mod_id, n_ex, n);
- return 0;
- }
-
- /* check that the sum of all slices percentages (including removed/added
- * slices) matches [1,100] */
- pct = 0;
- for (i = 0; i < n_ex; i++) {
- pct += existing[i]->percentage;
- }
- pct_orig = pct;
- for (i = 0; i < n_up; i++) {
- /* if there is an existing slice, subtract its percentage and add the
- * update's percentage */
- if (s[i])
- pct -= s[i]->percentage;
- pct += update[i]->percentage;
- }
- if (pct < 1 || pct > 100) {
- LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n",
- mod_id, pct_orig, pct);
- return 0;
- }
-
- /* check that there is no overlap in slices resulting as the combination of
- * first_rb and percentage */
- struct sregion_s sregion[n];
- const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */
- int k = n_ex;
- for (i = 0; i < n_ex; i++) {
- sregion[i].start = existing[i]->first_rb;
- sregion[i].length = existing[i]->percentage * N_RB / 100;
- }
- for (i = 0; i < n_up; i++) {
- ptrdiff_t d = s[i] ? offs[i] : k++;
- AssertFatal(d >= 0 && d < k, "illegal pointer offset (%ld, k=%d)\n", d, k);
- sregion[d].start = update[i]->first_rb;
- sregion[d].length = update[i]->percentage * N_RB / 100;
- }
- AssertFatal(k == n, "illegal number of slices while calculating overlap\n");
- if (!check_ul_slice_overlap(mod_id, sregion, k)) {
- LOG_E(FLEXRAN_AGENT, "[%d] UL slices are overlapping\n", mod_id);
- return 0;
- }
-
- return 1;
-}
-
-int flexran_dl_slice_verify_pct(int pct)
-{
- return pct >= 0 && pct <= 100;
-}
-
-int flexran_dl_slice_verify_priority(int prio)
-{
- return prio >= 0;
-}
-
-int flexran_dl_slice_verify_position(int pos_low, int pos_high)
-{
- return pos_low < pos_high && pos_low >= 0 && pos_high <= N_RBG_MAX;
-}
-
-int flexran_dl_slice_verify_maxmcs(int maxmcs)
-{
- return maxmcs >= 0 && maxmcs <= 28;
-}
-
-int flexran_ul_slice_verify_pct(int pct)
-{
- return pct >= 0 && pct <= 100;
-}
-
-int flexran_ul_slice_verify_priority(int prio)
-{
- return prio >= 0;
-}
-
-int flexran_ul_slice_verify_first_rb(int first_rb)
-{
- return first_rb >= 0 && first_rb < 100;
-}
-
-int flexran_ul_slice_verify_maxmcs(int maxmcs)
-{
- return maxmcs >= 0 && maxmcs <= 20;
-}
-
-int sregion_compare(const void *_a, const void *_b)
-{
- const struct sregion_s *a = (const struct sregion_s *)_a;
- const struct sregion_s *b = (const struct sregion_s *)_b;
- const int res = a->start - b->start;
- if (res < 0) return -1;
- else if (res == 0) return 0;
- else return 1;
-}
-
-int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n)
-{
- int i;
- int overlap, op, u;
- const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */
- qsort(sr, n, sizeof(sr[0]), sregion_compare);
- for (i = 0; i < n; i++) {
- u = i == n-1 ? N_RB : sr[i+1].start;
- AssertFatal(sr[i].start <= u, "unsorted slice list\n");
- overlap = sr[i].start + sr[i].length - u;
- if (overlap <= 0) continue;
- op = overlap * 100 / sr[i].length;
- LOG_W(FLEXRAN_AGENT, "[%d] slice overlap of %d%% detected\n", mod_id, op);
- if (op >= 10) /* more than 10% overlap -> refuse */
- return 0;
- }
- return 1;
-}
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h
index a8f4030d36..c9e66b6f88 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h
@@ -29,9 +29,3 @@
#include "flexran_agent_common_internal.h"
#include "flexran_agent_mac_internal.h"
-int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls);
-int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing,
- int n_ex, Protocol__FlexDlSlice **update, int n_up);
-int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls);
-int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing,
- int n_ex, Protocol__FlexUlSlice **update, int n_up);
diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
index 92c9917622..ec907a1956 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c
@@ -921,7 +921,4 @@ int flexran_agent_unregister_rrc_xface(mid_t mod_id)
return 0;
}
-AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id)
-{
- return agent_rrc_xface[mod_id];
-}
+
diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c
index 04a47406e1..c2d7cb9e55 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c
@@ -125,6 +125,63 @@ void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply) {
}
}
+void flexran_agent_handle_mme_update(mid_t mod_id,
+ size_t n_mme,
+ Protocol__FlexS1apMme **mme) {
+ if (n_mme == 0 || n_mme > 1) {
+ LOG_E(FLEXRAN_AGENT, "cannot handle %lu MMEs yet\n", n_mme);
+ return;
+ }
+
+ if (!mme[0]->s1_ip) {
+ LOG_E(FLEXRAN_AGENT, "no S1 IP present, cannot handle request\n");
+ return;
+ }
+
+ if (mme[0]->has_state
+ && mme[0]->state == PROTOCOL__FLEX_MME_STATE__FLMMES_DISCONNECTED) {
+ int rc = flexran_remove_s1ap_mme(mod_id, 1, &mme[0]->s1_ip);
+ if (rc == 0)
+ LOG_I(FLEXRAN_AGENT, "remove MME at IP %s\n", mme[0]->s1_ip);
+ else
+ LOG_W(FLEXRAN_AGENT,
+ "could not remove MME: flexran_remove_s1ap_mme() returned %d\n",
+ rc);
+ } else {
+ int rc = flexran_add_s1ap_mme(mod_id, 1, &mme[0]->s1_ip);
+ if (rc == 0)
+ LOG_I(FLEXRAN_AGENT, "add MME at IP %s\n", mme[0]->s1_ip);
+ else
+ LOG_W(FLEXRAN_AGENT,
+ "could not add MME: flexran_add_s1ap_mme() returned %d\n",
+ rc);
+ }
+}
+
+void flexran_agent_handle_plmn_update(mid_t mod_id,
+ int CC_id,
+ size_t n_plmn,
+ Protocol__FlexPlmn **plmn_id) {
+ if (n_plmn < 1 || n_plmn > 6) {
+ LOG_E(FLEXRAN_AGENT, "cannot handle %lu PLMNs\n", n_plmn);
+ return;
+ }
+
+ /* We assume the controller has checked all the parameters within each
+ * plmn_id */
+ int rc = flexran_set_new_plmn_id(mod_id, CC_id, n_plmn, plmn_id);
+ if (rc == 0) {
+ LOG_I(FLEXRAN_AGENT, "set %lu new PLMNs:\n", n_plmn);
+ for (int i = 0; i < (int)n_plmn; ++i)
+ LOG_I(FLEXRAN_AGENT, " MCC %d MNC %d MNC length %d\n",
+ plmn_id[i]->mcc, plmn_id[i]->mnc, plmn_id[0]->mnc_length);
+ } else {
+ LOG_W(FLEXRAN_AGENT,
+ "could not set new PLMN configuration: flexran_set_new_plmn_id() returned %d\n",
+ rc);
+ }
+}
+
int flexran_agent_register_s1ap_xface(mid_t mod_id) {
if (agent_s1ap_xface[mod_id]) {
LOG_E(FLEXRAN_AGENT, "S1AP agent CM for eNB %d is already registered\n", mod_id);
diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h
index 1cca6ac9c1..006eaa1d3c 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h
@@ -60,6 +60,17 @@ int flexran_agent_s1ap_stats_reply(mid_t mod_id,
/* Free allocated S1AP stats message */
void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply);
+/* Add or remove MME updates */
+void flexran_agent_handle_mme_update(mid_t mod_id,
+ size_t n_mme,
+ Protocol__FlexS1apMme **mme);
+
+/* Set a new PLMN configuration */
+void flexran_agent_handle_plmn_update(mid_t mod_id,
+ int CC_id,
+ size_t n_plmn,
+ Protocol__FlexPlmn **plmn_id);
+
/* Register technology specific interface callbacks */
int flexran_agent_register_s1ap_xface(mid_t mod_id);
diff --git a/openair2/ENB_APP/MACRLC_paramdef.h b/openair2/ENB_APP/MACRLC_paramdef.h
index 55ce9d5059..fcee6142f0 100644
--- a/openair2/ENB_APP/MACRLC_paramdef.h
+++ b/openair2/ENB_APP/MACRLC_paramdef.h
@@ -58,6 +58,7 @@
#define CONFIG_STRING_MACRLC_SCHED_MODE "scheduler_mode"
#define CONFIG_MACRLC_PUSCH10xSNR "puSch10xSnr"
#define CONFIG_MACRLC_PUCCH10xSNR "puCch10xSnr"
+#define CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO "default_sched_dl_algo"
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* MacRLC configuration parameters */
@@ -84,6 +85,7 @@
{CONFIG_STRING_MACRLC_SCHED_MODE, NULL, 0, strptr:NULL, defstrval:"default", TYPE_STRING, 0}, \
{CONFIG_MACRLC_PUSCH10xSNR, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
{CONFIG_MACRLC_PUCCH10xSNR, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
+{CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO, NULL, 0, strptr:NULL, defstrval:"round_robin_dl", TYPE_STRING, 0}, \
}
#define MACRLC_CC_IDX 0
#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1
@@ -105,6 +107,7 @@
#define MACRLC_SCHED_MODE_IDX 17
#define MACRLC_PUSCH10xSNR_IDX 18
#define MACRLC_PUCCH10xSNR_IDX 19
+#define MACRLC_DEFAULT_SCHED_DL_ALGO_IDX 20
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
#endif
diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto
index 733d883c92..2f2267b628 100644
--- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto
@@ -61,82 +61,30 @@ enum flex_qam {
//
// Slice config related structures and enums
//
-enum flex_dl_sorting {
-
- CR_ROUND = 0; // Highest HARQ first
- CR_SRB12 = 1; // Highest SRB1+2 first
- CR_HOL = 2; // Highest HOL first
- CR_LC = 3; // Greatest RLC buffer first
- CR_CQI = 4; // Highest CQI first
- CR_LCP = 5; // Highest LC priority first
+enum flex_slice_algorithm {
+ None = 0;
+ Static = 1;
+ NVS = 2;
}
-enum flex_ul_sorting {
- CRU_ROUND = 0; // Highest HARQ first
- CRU_BUF = 1; // Highest BSR first
- CRU_BTS = 2; // More bytes to schedule first
- CRU_MCS = 3; // Highest MCS first
- CRU_LCP = 4; // Highest LC priority first
- CRU_HOL = 5; // Highest HOL first
+message flex_slice_static {
+ optional uint32 posLow = 1;
+ optional uint32 posHigh = 2;
}
-enum flex_dl_accounting_policy {
- POL_FAIR = 0;
- POL_GREEDY = 1;
- POL_NUM = 2;
+message flex_slice {
+ optional uint32 id = 1;
+ optional string label = 2;
+ optional string scheduler = 3;
+ oneof params {
+ flex_slice_static static = 10;
+ }
}
-enum flex_ul_accounting_policy {
- POLU_FAIR = 0;
- POLU_GREEDY = 1;
- POLU_NUM = 2;
-}
-
-enum flex_slice_label {
- xMBB = 0;
- URLLC = 1;
- mMTC = 2;
- xMTC = 3;
- Other = 4;
-}
-
-message flex_dl_slice {
- optional uint32 id = 1;
- optional flex_slice_label label = 2;
- // should be between 0 and 100
- optional uint32 percentage = 3;
- // whether this slice should be exempted form interslice sharing
- optional bool isolation = 4;
- // increasing value means increasing prio
- optional uint32 priority = 5;
- // min and max RB to use (in frequency) in the range [0, N_RBG_MAX]
- optional uint32 position_low = 6;
- optional uint32 position_high = 7;
- // maximum MCS to be allowed in this slice
- optional uint32 maxmcs = 8;
- repeated flex_dl_sorting sorting = 9;
- optional flex_dl_accounting_policy accounting = 10;
- optional string scheduler_name = 11;
-}
-
-message flex_ul_slice {
- optional uint32 id = 1;
- optional flex_slice_label label = 2;
- // should be between 0 and 100
- optional uint32 percentage = 3;
- // whether this slice should be exempted form interslice sharing
- optional bool isolation = 4;
- // increasing value means increasing prio
- optional uint32 priority = 5;
- // RB start to use (in frequency) in the range [0, N_RB_MAX]
- optional uint32 first_rb = 6;
- // TODO RB number
- //optional uint32 length_rb = 7;
- // maximum MCS to be allowed in this slice
- optional uint32 maxmcs = 8;
- repeated flex_ul_sorting sorting = 9;
- optional flex_ul_accounting_policy accounting = 10;
- optional string scheduler_name = 11;
+message flex_slice_dl_ul_config {
+ optional flex_slice_algorithm algorithm = 1;
+ repeated flex_slice slices = 2;
+ optional string scheduler = 3; // if no slicing
}
//
diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
index 324153613d..1a69deec71 100644
--- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
@@ -49,14 +49,8 @@ message flex_cell_config {
}
message flex_slice_config {
- // whether remaining RBs after first intra-slice allocation will
- // be allocated to UEs of the same slice
- optional bool intraslice_share_active = 3;
- // whether remaining RBs after slice allocation will be allocated
- // to UEs of another slice. Isolated slices will be ignored.
- optional bool interslice_share_active = 4;
- repeated flex_dl_slice dl = 1;
- repeated flex_ul_slice ul = 2;
+ optional flex_slice_dl_ul_config dl = 6;
+ optional flex_slice_dl_ul_config ul = 7;
}
message flex_ue_config {
diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c
index 0e1c7e64bc..7c91e57813 100644
--- a/openair2/ENB_APP/enb_app.c
+++ b/openair2/ENB_APP/enb_app.c
@@ -273,7 +273,6 @@ void *eNB_app_task(void *args_p) {
if (EPC_MODE_ENABLED) {
LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p),
S1AP_REGISTER_ENB_CNF(msg_p).nb_mme);
- DevAssert(register_enb_pending > 0);
register_enb_pending--;
/* Check if at least eNB is registered with one MME */
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 6dcc574746..1d189832b4 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -29,6 +29,7 @@
#include
#include
+#include
#include "common/utils/LOG/log.h"
#include "assertions.h"
@@ -260,6 +261,16 @@ void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]) {
global_scheduler_mode=SCHED_MODE_DEFAULT;
printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr));
}
+
+ char *s = *MacRLC_ParamList.paramarray[j][MACRLC_DEFAULT_SCHED_DL_ALGO_IDX].strptr;
+ void *d = dlsym(NULL, s);
+ AssertFatal(d, "%s(): no default scheduler DL algo '%s' found\n", __func__, s);
+ // release default, add new
+ pp_impl_param_t *dl_pp = &RC.mac[j]->pre_processor_dl;
+ dl_pp->dl_algo.unset(&dl_pp->dl_algo.data);
+ dl_pp->dl_algo = *(default_sched_dl_algo_t *) d;
+ dl_pp->dl_algo.data = dl_pp->dl_algo.setup();
+ LOG_I(ENB_APP, "using default scheduler DL algo '%s'\n", dl_pp->dl_algo.name);
}// j=0..num_inst
} /*else {// MacRLC_ParamList.numelt > 0 // ignore it
@@ -1545,7 +1556,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) {
RRC_CONFIGURATION_REQ(msg_p).eMBMS_configured = 0;
printf("No eMBMS configuration, skipping it\n");
// eMTC configuration
- char brparamspath[MAX_OPTNAME_SIZE*2 + 16];
+ char brparamspath[MAX_OPTNAME_SIZE*2 + 160];
sprintf(brparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_EMTC_PARAMETERS);
config_get(eMTCParams, sizeof(eMTCParams)/sizeof(paramdef_t), brparamspath);
RRC_CONFIGURATION_REQ(msg_p).eMTC_configured = eMTCconfig.eMTC_configured&1;
@@ -1554,7 +1565,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) {
else printf("No eMTC configuration, skipping it\n");
// Sidelink configuration
- char SLparamspath[MAX_OPTNAME_SIZE*2 + 16];
+ char SLparamspath[MAX_OPTNAME_SIZE*2 + 160];
sprintf(SLparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_SL_PARAMETERS);
config_get( SLParams, sizeof(SLParams)/sizeof(paramdef_t), SLparamspath);
// Sidelink Resource pool information
diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c
index dc320ef974..7569ca1ac1 100644
--- a/openair2/ENB_APP/flexran_agent_common.c
+++ b/openair2/ENB_APP/flexran_agent_common.c
@@ -306,6 +306,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
if (reply->cell_config[i]->mbsfn_subframe_config_sfalloc)
free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
+ /* si_config is shared between MAC and RRC, free here */
if (reply->cell_config[i]->si_config) {
for(int j = 0; j < reply->cell_config[i]->si_config->n_si_message; j++) {
free(reply->cell_config[i]->si_config->si_message[j]);
@@ -316,26 +317,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
}
if (reply->cell_config[i]->slice_config) {
- for (int j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) {
- if (reply->cell_config[i]->slice_config->dl[j]->n_sorting > 0)
- free(reply->cell_config[i]->slice_config->dl[j]->sorting);
-
- free(reply->cell_config[i]->slice_config->dl[j]->scheduler_name);
- free(reply->cell_config[i]->slice_config->dl[j]);
- }
-
- free(reply->cell_config[i]->slice_config->dl);
-
- for (int j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) {
- if (reply->cell_config[i]->slice_config->ul[j]->n_sorting > 0)
- free(reply->cell_config[i]->slice_config->ul[j]->sorting);
-
- free(reply->cell_config[i]->slice_config->ul[j]->scheduler_name);
- free(reply->cell_config[i]->slice_config->ul[j]);
- }
-
- free(reply->cell_config[i]->slice_config->ul);
- free(reply->cell_config[i]->slice_config);
+ flexran_agent_destroy_mac_slice_config(reply->cell_config[i]);
}
free(reply->cell_config[i]);
@@ -893,31 +875,40 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot
Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
Protocol__FlexEnbConfigReply *enb_config = input->enb_config_reply_msg;
- if (enb_config->n_cell_config == 0) {
- LOG_W(FLEXRAN_AGENT,
- "received enb_config_reply message does not contain a cell_config\n");
- *msg = NULL;
- return 0;
- }
-
if (enb_config->n_cell_config > 1)
LOG_W(FLEXRAN_AGENT, "ignoring slice configs for other cell except cell 0\n");
- if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) {
- prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config);
- } else if (enb_config->cell_config[0]->has_eutra_band
- && enb_config->cell_config[0]->has_dl_freq
- && enb_config->cell_config[0]->has_ul_freq
- && enb_config->cell_config[0]->has_dl_bandwidth) {
- initiate_soft_restart(mod_id, enb_config->cell_config[0]);
- } else if (flexran_agent_get_rrc_xface(mod_id)
- && enb_config->cell_config[0]->has_x2_ho_net_control) {
- LOG_I(FLEXRAN_AGENT,
- "setting X2 HO NetControl to %d\n",
- enb_config->cell_config[0]->x2_ho_net_control);
- const int rc = flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control);
- if (rc < 0)
- LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network");
+ if (enb_config->n_cell_config > 0) {
+ if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) {
+ prepare_update_slice_config(mod_id, &enb_config->cell_config[0]->slice_config);
+ }
+ if (enb_config->cell_config[0]->has_eutra_band
+ && enb_config->cell_config[0]->has_dl_freq
+ && enb_config->cell_config[0]->has_ul_freq
+ && enb_config->cell_config[0]->has_dl_bandwidth) {
+ initiate_soft_restart(mod_id, enb_config->cell_config[0]);
+ }
+ if (flexran_agent_get_rrc_xface(mod_id)
+ && enb_config->cell_config[0]->has_x2_ho_net_control) {
+ LOG_I(FLEXRAN_AGENT,
+ "setting X2 HO NetControl to %d\n",
+ enb_config->cell_config[0]->x2_ho_net_control);
+ const int rc = flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control);
+ if (rc < 0)
+ LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network");
+ }
+ if (flexran_agent_get_rrc_xface(mod_id) && enb_config->cell_config[0]->n_plmn_id > 0) {
+ flexran_agent_handle_plmn_update(mod_id,
+ 0,
+ enb_config->cell_config[0]->n_plmn_id,
+ enb_config->cell_config[0]->plmn_id);
+ }
+ }
+
+ if (flexran_agent_get_s1ap_xface(mod_id) && enb_config->s1ap) {
+ flexran_agent_handle_mme_update(mod_id,
+ enb_config->s1ap->n_mme,
+ enb_config->s1ap->mme);
}
*msg = NULL;
@@ -930,7 +921,11 @@ int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Proto
Protocol__FlexUeConfigReply *ue_config_reply = input->ue_config_reply_msg;
for (i = 0; flexran_agent_get_mac_xface(mod_id) && i < ue_config_reply->n_ue_config; i++)
- prepare_ue_slice_assoc_update(mod_id, ue_config_reply->ue_config[i]);
+ prepare_ue_slice_assoc_update(mod_id, &ue_config_reply->ue_config[i]);
+ /* prepare_ue_slice_assoc_update takes ownership of the individual
+ * FlexUeConfig messages. Therefore, mark zero messages to not accidentally
+ * free them twice */
+ ue_config_reply->n_ue_config = 0;
*msg = NULL;
return 0;
diff --git a/openair2/ENB_APP/flexran_agent_extern.h b/openair2/ENB_APP/flexran_agent_extern.h
index 119bc3d44c..5f17cf4841 100644
--- a/openair2/ENB_APP/flexran_agent_extern.h
+++ b/openair2/ENB_APP/flexran_agent_extern.h
@@ -41,10 +41,15 @@
AGENT_PHY_xface *flexran_agent_get_phy_xface(mid_t mod_id);
/* Control module interface for the communication of the MAC Control Module with the agent */
-AGENT_MAC_xface *flexran_agent_get_mac_xface(mid_t mod_id);
+
+extern AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB];
+#define flexran_agent_get_mac_xface(mod_id) (agent_mac_xface[mod_id])
+/* Control module interface for the communication of the RRC Control Module with the agent */
/* Control module interface for the communication of the RRC Control Module with the agent */
-AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id);
+// AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id);
+extern AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB];
+#define flexran_agent_get_rrc_xface(mod_id) (agent_rrc_xface[mod_id])
/* Control module interface for the communication of the RRC Control Module with the agent */
AGENT_PDCP_xface *flexran_agent_get_pdcp_xface(mid_t mod_id);
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c
index 32cb8c74e1..79c992a4d7 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.c
+++ b/openair2/ENB_APP/flexran_agent_ran_api.c
@@ -30,6 +30,7 @@
#include "flexran_agent_ran_api.h"
#include "s1ap_eNB_ue_context.h"
#include "s1ap_eNB_management_procedures.h"
+#include "openair2/LAYER2/MAC/slicing/slicing.h"
static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) {
return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id];
@@ -3013,471 +3014,293 @@ uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti)
}
/**************************** SLICING ****************************/
-int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) {
- if (!mac_is_present(mod_id)) return -1;
+Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id) {
+ if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
- int slice_idx = 0; //RC.mac[mod_id]->UE_info.assoc_dl_slice_idx[ue_id];
-
- if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl)
- return RC.mac[mod_id]->slice_info.dl[slice_idx].id;
-
- return 0;
+ switch (RC.mac[mod_id]->pre_processor_dl.algorithm) {
+ case STATIC_SLICING:
+ return PROTOCOL__FLEX_SLICE_ALGORITHM__Static;
+ default:
+ return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
+ }
}
-void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) {
+int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) {
+ if (!mac_is_present(mod_id)) return 0;
+ eNB_MAC_INST *mac = RC.mac[mod_id];
+ const int cc_id = 0;
+
+ pp_impl_param_t dl = mac->pre_processor_dl;
+ switch (algo) {
+ case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
+ mac->pre_processor_dl = static_dl_init(mod_id, cc_id);
+ break;
+ default:
+ mac->pre_processor_dl.algorithm = 0;
+ mac->pre_processor_dl.dl = dlsch_scheduler_pre_processor;
+ mac->pre_processor_dl.dl_algo.data = mac->pre_processor_dl.dl_algo.setup();
+ mac->pre_processor_dl.slices = NULL;
+ break;
+ }
+ if (dl.slices)
+ dl.destroy(&dl.slices);
+ if (dl.dl_algo.data)
+ dl.dl_algo.unset(&dl.dl_algo.data);
+ return 1;
+}
+
+Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id) {
+ if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
+
+ switch (RC.mac[mod_id]->pre_processor_ul.algorithm) {
+ case STATIC_SLICING:
+ return PROTOCOL__FLEX_SLICE_ALGORITHM__Static;
+ default:
+ return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
+ }
+}
+
+int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) {
+ if (!mac_is_present(mod_id)) return 0;
+ eNB_MAC_INST *mac = RC.mac[mod_id];
+ const int cc_id = 0;
+
+ pp_impl_param_t ul = mac->pre_processor_ul;
+ switch (algo) {
+ case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
+ mac->pre_processor_ul = static_ul_init(mod_id, cc_id);
+ break;
+ default:
+ mac->pre_processor_ul.algorithm = 0;
+ mac->pre_processor_ul.ul = ulsch_scheduler_pre_processor;
+ mac->pre_processor_ul.ul_algo.data = mac->pre_processor_ul.ul_algo.setup();
+ mac->pre_processor_ul.slices = NULL;
+ break;
+ }
+ if (ul.slices)
+ ul.destroy(&ul.slices);
+ if (ul.ul_algo.data)
+ ul.ul_algo.unset(&ul.ul_algo.data);
+ return 1;
+}
+
+int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) {
+ if (!mac_is_present(mod_id)) return -1;
+ slice_info_t *slices = RC.mac[mod_id]->pre_processor_dl.slices;
+ if (!slices) return -1;
+ const int idx = slices->UE_assoc_slice[ue_id];
+ return slices->s[idx]->id;
+}
+
+void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return;
-
- if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return;
-
- if (!flexran_dl_slice_exists(mod_id, slice_idx)) return;
-
- //RC.mac[mod_id]->UE_info.assoc_dl_slice_idx[ue_id] = slice_idx;
+ int idx = flexran_find_dl_slice(mod_id, slice_id);
+ if (idx < 0) return;
+ pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
+ dl->move_UE(dl->slices, ue_id, idx);
}
int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) {
if (!mac_is_present(mod_id)) return -1;
-
- int slice_idx = 0; //RC.mac[mod_id]->UE_info.assoc_ul_slice_idx[ue_id];
-
- if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul)
- return RC.mac[mod_id]->slice_info.ul[slice_idx].id;
-
- return 0;
+ slice_info_t *slices = RC.mac[mod_id]->pre_processor_ul.slices;
+ if (!slices) return -1;
+ const int idx = slices->UE_assoc_slice[ue_id];
+ return slices->s[idx]->id;
}
-void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) {
+void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return;
-
- if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return;
-
- if (!flexran_ul_slice_exists(mod_id, slice_idx)) return;
-
- //RC.mac[mod_id]->UE_info.assoc_ul_slice_idx[ue_id] = slice_idx;
+ int idx = flexran_find_ul_slice(mod_id, slice_id);
+ if (idx < 0) return;
+ pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
+ ul->move_UE(ul->slices, ue_id, idx);
}
-int flexran_dl_slice_exists(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl;
+int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
+ if (!mac_is_present(mod_id)) return 0;
+ void *params = NULL;
+ switch (s->params_case) {
+ case PROTOCOL__FLEX_SLICE__PARAMS_STATIC:
+ params = malloc(sizeof(static_slice_param_t));
+ if (!params) return 0;
+ ((static_slice_param_t *)params)->posLow = s->static_->poslow;
+ ((static_slice_param_t *)params)->posHigh = s->static_->poshigh;
+ break;
+ default:
+ break;
+ }
+ pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
+ char *l = s->label ? strdup(s->label) : NULL;
+ void *algo = &dl->dl_algo; // default scheduler
+ if (s->scheduler) {
+ algo = dlsym(NULL, s->scheduler);
+ if (!algo) {
+ free(params);
+ LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler);
+ return -15;
+ }
+ }
+ return dl->addmod_slice(dl->slices, s->id, l, algo, params);
}
-int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) {
- if (!mac_is_present(mod_id)) return -1;
-
- int newidx = RC.mac[mod_id]->slice_info.n_dl;
-
- if (newidx >= MAX_NUM_SLICES) return -1;
-
- ++RC.mac[mod_id]->slice_info.n_dl;
- flexran_set_dl_slice_id(mod_id, newidx, slice_id);
- return newidx;
+int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
+ if (!mac_is_present(mod_id)) return 0;
+ const int idx = flexran_find_dl_slice(mod_id, s->id);
+ if (idx < 0) return 0;
+ pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
+ return dl->remove_slice(dl->slices, idx);
}
int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return -1;
-
- slice_info_t *sli = &RC.mac[mod_id]->slice_info;
- int n = sli->n_dl;
-
- for (int i = 0; i < n; i++) {
- if (sli->dl[i].id == slice_id) return i;
- }
-
+ slice_info_t *si = RC.mac[mod_id]->pre_processor_dl.slices;
+ for (int i = 0; i < si->num; ++i)
+ if (si->s[i]->id == slice_id)
+ return i;
return -1;
}
-int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- slice_info_t *sli = &RC.mac[mod_id]->slice_info;
-
- if (sli->n_dl <= 1) return -1;
-
- if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name);
-
- --sli->n_dl;
-
- /* move last element to the position of the removed one */
- if (slice_idx != sli->n_dl)
- memcpy(&sli->dl[slice_idx], &sli->dl[sli->n_dl], sizeof(sli->dl[sli->n_dl]));
-
- memset(&sli->dl[sli->n_dl], 0, sizeof(sli->dl[sli->n_dl]));
- /* all UEs that have been in the old slice are put into slice index 0 */
- //int *assoc_list = RC.mac[mod_id]->UE_info.assoc_dl_slice_idx;
-
- //for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) {
- // if (assoc_list[i] == slice_idx)
- // assoc_list[i] = 0;
- //}
-
- return 1;
+void flexran_get_dl_slice(mid_t mod_id,
+ int slice_idx,
+ Protocol__FlexSlice *slice,
+ Protocol__FlexSliceAlgorithm algo) {
+ if (!mac_is_present(mod_id)) return;
+ slice_t *s_ = RC.mac[mod_id]->pre_processor_dl.slices->s[slice_idx];
+ slice->has_id = 1;
+ slice->id = s_->id;
+ slice->label = s_->label;
+ slice->scheduler = s_->dl_algo.name;
+ slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET;
+ switch (algo) {
+ case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
+ slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic));
+ if (!slice->static_) return;
+ protocol__flex_slice_static__init(slice->static_);
+ slice->static_->has_poslow = 1;
+ slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow;
+ slice->static_->has_poshigh = 1;
+ slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh;
+ slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC;
+ break;
+ default:
+ break;
+ }
}
int flexran_get_num_dl_slices(mid_t mod_id) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.n_dl;
-}
-
-int flexran_get_intraslice_sharing_active(mid_t mod_id) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.intraslice_share_active;
-}
-void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.intraslice_share_active = intraslice_active;
-}
-
-int flexran_get_interslice_sharing_active(mid_t mod_id) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.interslice_share_active;
-}
-void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.interslice_share_active = interslice_active;
-}
-
-slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.dl[slice_idx].id;
-}
-void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.dl[slice_idx].id = slice_id;
-}
-
-int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.dl[slice_idx].pct * 100.0f;
-}
-void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.dl[slice_idx].pct = percentage / 100.0f;
-}
-
-int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.dl[slice_idx].isol;
-}
-void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.dl[slice_idx].isol = is_isolated;
-}
-
-int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.dl[slice_idx].prio;
-}
-void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.dl[slice_idx].prio = priority;
-}
-
-int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low;
-}
-void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low = poslow;
-}
-
-int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high;
-}
-void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high = poshigh;
-}
-
-int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs;
-}
-void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs = maxmcs;
-}
-
-int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list) {
- if (!mac_is_present(mod_id)) return -1;
-
- if (!(*sorting_list)) {
- *sorting_list = calloc(CR_NUM, sizeof(Protocol__FlexDlSorting));
-
- if (!(*sorting_list)) return -1;
- }
-
- uint32_t policy = RC.mac[mod_id]->slice_info.dl[slice_idx].sorting;
-
- for (int i = 0; i < CR_NUM; i++) {
- switch (policy >> 4 * (CR_NUM - 1 - i) & 0xF) {
- case CR_ROUND:
- (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND;
- break;
-
- case CR_SRB12:
- (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_SRB12;
- break;
-
- case CR_HOL:
- (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_HOL;
- break;
-
- case CR_LC:
- (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LC;
- break;
-
- case CR_CQI:
- (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_CQI;
- break;
-
- case CR_LCP:
- (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LCP;
- break;
-
- default:
- /* this should not happen, but a "default" */
- (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND;
- break;
- }
- }
-
- return CR_NUM;
-}
-void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n) {
- if (!mac_is_present(mod_id)) return;
-
- uint32_t policy = 0;
-
- for (int i = 0; i < n && i < CR_NUM; i++) {
- switch (sorting_list[i]) {
- case PROTOCOL__FLEX_DL_SORTING__CR_ROUND:
- policy = policy << 4 | CR_ROUND;
- break;
-
- case PROTOCOL__FLEX_DL_SORTING__CR_SRB12:
- policy = policy << 4 | CR_SRB12;
- break;
-
- case PROTOCOL__FLEX_DL_SORTING__CR_HOL:
- policy = policy << 4 | CR_HOL;
- break;
-
- case PROTOCOL__FLEX_DL_SORTING__CR_LC:
- policy = policy << 4 | CR_LC;
- break;
-
- case PROTOCOL__FLEX_DL_SORTING__CR_CQI:
- policy = policy << 4 | CR_CQI;
- break;
-
- case PROTOCOL__FLEX_DL_SORTING__CR_LCP:
- policy = policy << 4 | CR_LCP;
- break;
-
- default: /* suppresses warnings */
- policy = policy << 4 | CR_ROUND;
- break;
- }
- }
-
- /* fill up with 0 == CR_ROUND */
- if (CR_NUM > n) policy = policy << 4 * (CR_NUM - n);
-
- RC.mac[mod_id]->slice_info.dl[slice_idx].sorting = policy;
-}
-
-Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR;
-
- switch (RC.mac[mod_id]->slice_info.dl[slice_idx].accounting) {
- case POL_FAIR:
- return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR;
-
- case POL_GREEDY:
- return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY;
-
- default:
- return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR;
- }
-}
-void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting) {
- if (!mac_is_present(mod_id)) return;
-
- switch (accounting) {
- case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR:
- RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR;
- return;
-
- case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY:
- RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_GREEDY;
- return;
-
- default:
- RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR;
- return;
- }
-}
-
-char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return NULL;
-
- return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name;
-}
-int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name) {
if (!mac_is_present(mod_id)) return 0;
-
- if (RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name)
- free(RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name);
-
- RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = strdup(name);
- RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb = dlsym(NULL, name);
- return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb != NULL;
+ if (!RC.mac[mod_id]->pre_processor_dl.slices) return 0;
+ return RC.mac[mod_id]->pre_processor_dl.slices->num;
}
-int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) {
+int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
if (!mac_is_present(mod_id)) return -1;
+ void *params = NULL;
+ switch (s->params_case) {
+ case PROTOCOL__FLEX_SLICE__PARAMS_STATIC:
+ params = malloc(sizeof(static_slice_param_t));
+ if (!params) return 0;
+ ((static_slice_param_t *)params)->posLow = s->static_->poslow;
+ ((static_slice_param_t *)params)->posHigh = s->static_->poshigh;
+ break;
+ default:
+ break;
+ }
+ pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
+ char *l = s->label ? strdup(s->label) : NULL;
+ void *algo = &ul->ul_algo; // default scheduler
+ if (s->scheduler) {
+ algo = dlsym(NULL, s->scheduler);
+ if (!algo) {
+ free(params);
+ LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler);
+ return -15;
+ }
+ }
+ return ul->addmod_slice(ul->slices, s->id, l, algo, params);
+}
- int newidx = RC.mac[mod_id]->slice_info.n_ul;
-
- if (newidx >= MAX_NUM_SLICES) return -1;
-
- ++RC.mac[mod_id]->slice_info.n_ul;
- flexran_set_ul_slice_id(mod_id, newidx, slice_id);
- return newidx;
+int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
+ if (!mac_is_present(mod_id)) return 0;
+ const int idx = flexran_find_ul_slice(mod_id, s->id);
+ if (idx < 0) return 0;
+ pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
+ return ul->remove_slice(ul->slices, idx);
}
int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) {
if (!mac_is_present(mod_id)) return -1;
-
- slice_info_t *sli = &RC.mac[mod_id]->slice_info;
- int n = sli->n_ul;
-
- for (int i = 0; i < n; i++) {
- if (sli->ul[i].id == slice_id) return i;
- }
-
+ slice_info_t *si = RC.mac[mod_id]->pre_processor_ul.slices;
+ for (int i = 0; i < si->num; ++i)
+ if (si->s[i]->id == slice_id)
+ return i;
return -1;
}
-int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
+void flexran_get_ul_slice(mid_t mod_id,
+ int slice_idx,
+ Protocol__FlexSlice *slice,
+ Protocol__FlexSliceAlgorithm algo) {
+ if (!mac_is_present(mod_id)) return;
+ slice_t *s_ = RC.mac[mod_id]->pre_processor_ul.slices->s[slice_idx];
+ slice->has_id = 1;
+ slice->id = s_->id;
+ slice->label = s_->label;
+ slice->scheduler = s_->ul_algo.name;
+ slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET;
+ switch (algo) {
+ case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
+ slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic));
+ if (!slice->static_) return;
+ protocol__flex_slice_static__init(slice->static_);
+ slice->static_->has_poslow = 1;
+ slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow;
+ slice->static_->has_poshigh = 1;
+ slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh;
+ slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC;
+ break;
+ default:
+ break;
+ }
- slice_info_t *sli = &RC.mac[mod_id]->slice_info;
-
- if (sli->n_ul <= 1) return -1;
-
- if (sli->ul[slice_idx].sched_name) free(sli->ul[slice_idx].sched_name);
-
- --sli->n_ul;
-
- /* move last element to the position of the removed one */
- if (slice_idx != sli->n_ul)
- memcpy(&sli->ul[slice_idx], &sli->ul[sli->n_ul], sizeof(sli->ul[sli->n_ul]));
-
- memset(&sli->ul[sli->n_ul], 0, sizeof(sli->ul[sli->n_ul]));
- /* all UEs that have been in the old slice are put into slice index 0 */
- //int *assoc_list = RC.mac[mod_id]->UE_info.assoc_ul_slice_idx;
-
- //for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) {
- // if (assoc_list[i] == slice_idx)
- // assoc_list[i] = 0;
- //}
-
- return sli->n_ul;
}
int flexran_get_num_ul_slices(mid_t mod_id) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.n_ul;
-}
-
-int flexran_ul_slice_exists(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul;
-}
-
-slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.ul[slice_idx].id;
-}
-void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.ul[slice_idx].id = slice_id;
-}
-
-int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.ul[slice_idx].pct * 100.0f;
-}
-void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.ul[slice_idx].pct = percentage / 100.0f;
-}
-
-int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb;
-}
-
-void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb = first_rb;
-}
-
-int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return -1;
-
- return RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs;
-}
-void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) {
- if (!mac_is_present(mod_id)) return;
-
- RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs = maxmcs;
-}
-
-char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx) {
- if (!mac_is_present(mod_id)) return NULL;
-
- return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name;
-}
-int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) {
if (!mac_is_present(mod_id)) return 0;
+ if (!RC.mac[mod_id]->pre_processor_ul.slices) return 0;
+ return RC.mac[mod_id]->pre_processor_ul.slices->num;
+}
- if (RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name)
- free(RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name);
+char *flexran_get_dl_scheduler_name(mid_t mod_id) {
+ if (!mac_is_present(mod_id)) return NULL;
+ return RC.mac[mod_id]->pre_processor_dl.dl_algo.name;
+}
- RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = strdup(name);
- RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb = dlsym(NULL, name);
- return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL;
+int flexran_set_dl_scheduler(mid_t mod_id, char *sched) {
+ if (!mac_is_present(mod_id)) return -1;
+ void *d = dlsym(NULL, sched);
+ if (!d) return -2;
+ pp_impl_param_t *dl_pp = &RC.mac[mod_id]->pre_processor_dl;
+ dl_pp->dl_algo.unset(&dl_pp->dl_algo.data);
+ dl_pp->dl_algo = *(default_sched_dl_algo_t *) d;
+ dl_pp->dl_algo.data = dl_pp->dl_algo.setup();
+ return 0;
+}
+
+char *flexran_get_ul_scheduler_name(mid_t mod_id) {
+ if (!mac_is_present(mod_id)) return NULL;
+ return RC.mac[mod_id]->pre_processor_ul.ul_algo.name;
+}
+
+int flexran_set_ul_scheduler(mid_t mod_id, char *sched) {
+ if (!mac_is_present(mod_id)) return -1;
+ void *d = dlsym(NULL, sched);
+ if (!d) return -2;
+ pp_impl_param_t *ul_pp = &RC.mac[mod_id]->pre_processor_ul;
+ ul_pp->ul_algo.unset(&ul_pp->ul_algo.data);
+ ul_pp->ul_algo = *(default_sched_ul_algo_t *) d;
+ ul_pp->ul_algo.data = ul_pp->ul_algo.setup();
+ return 0;
}
/************************** S1AP **************************/
@@ -3634,6 +3457,168 @@ int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apM
return 0;
}
+int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) {
+ s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
+ if (!s1ap) return -1;
+ if (!rrc_is_present(mod_id)) return -2;
+
+ /* Reconstruct S1AP_REGISTER_ENB_REQ */
+ MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, S1AP_REGISTER_ENB_REQ);
+ RCconfig_S1(m, mod_id);
+
+ const int CC_id = 0;
+ eNB_RRC_INST *rrc = RC.rrc[CC_id];
+ RrcConfigurationReq *conf = &rrc->configuration;
+ S1AP_REGISTER_ENB_REQ(m).num_plmn = conf->num_plmn;
+ for (int i = 0; i < conf->num_plmn; ++i) {
+ S1AP_REGISTER_ENB_REQ(m).mcc[i] = conf->mcc[i];
+ S1AP_REGISTER_ENB_REQ(m).mnc[i] = conf->mnc[i];
+ S1AP_REGISTER_ENB_REQ(m).mnc_digit_length[i] = conf->mnc_digit_length[i];
+ }
+
+ /* reconstruct MME list, it might have been updated since initial
+ * configuration */
+ S1AP_REGISTER_ENB_REQ(m).nb_mme = 0;
+ struct s1ap_eNB_mme_data_s *mme = NULL;
+ RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) {
+ const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme;
+ S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = mme->mme_s1_ip.ipv4;
+ strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme->mme_s1_ip.ipv4_address);
+ S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = mme->mme_s1_ip.ipv6;
+ strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6_address, mme->mme_s1_ip.ipv6_address);
+ S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = mme->broadcast_plmn_num;
+ for (int i = 0; i < mme->broadcast_plmn_num; ++i)
+ S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = mme->broadcast_plmn_index[i];
+ S1AP_REGISTER_ENB_REQ(m).nb_mme += 1;
+ }
+
+ if (S1AP_REGISTER_ENB_REQ(m).nb_mme + n_mme > S1AP_MAX_NB_MME_IP_ADDRESS)
+ return -1;
+
+ for (int i = 0; i < n_mme; ++i) {
+ const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme;
+ strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme_ipv4[0]);
+ S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = 1;
+ S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = 0;
+ S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = S1AP_REGISTER_ENB_REQ(m).num_plmn;
+ for (int i = 0; i < S1AP_REGISTER_ENB_REQ(m).num_plmn; ++i)
+ S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = i;
+ S1AP_REGISTER_ENB_REQ(m).nb_mme += 1;
+ }
+
+ itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m);
+
+ return 0;
+}
+
+int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) {
+ s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
+ if (!s1ap) return -1;
+ struct s1ap_eNB_mme_data_s *mme = NULL;
+ RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) {
+ if (mme->mme_s1_ip.ipv4
+ && strncmp(mme->mme_s1_ip.ipv4_address, mme_ipv4[0], 16) == 0)
+ break;
+ }
+ if (!mme)
+ return -2;
+
+ MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, SCTP_CLOSE_ASSOCIATION);
+ SCTP_CLOSE_ASSOCIATION(m).assoc_id = mme->assoc_id;
+ itti_send_msg_to_task (TASK_SCTP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m);
+
+ switch (mme->state) {
+ case S1AP_ENB_STATE_WAITING:
+ s1ap->s1ap_mme_nb -= 1;
+ if (s1ap->s1ap_mme_pending_nb > 0)
+ s1ap->s1ap_mme_pending_nb -= 1;
+ break;
+ case S1AP_ENB_STATE_CONNECTED:
+ case S1AP_ENB_OVERLOAD: /* I am not sure the decrements are right here */
+ s1ap->s1ap_mme_nb -= 1;
+ s1ap->s1ap_mme_associated_nb -= 1;
+ break;
+ case S1AP_ENB_STATE_DISCONNECTED:
+ default:
+ break;
+ }
+ RB_REMOVE(s1ap_mme_map, &s1ap->s1ap_mme_head, mme);
+
+ return 0;
+}
+
+int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__FlexPlmn **plmn_id) {
+ if (!rrc_is_present(mod_id))
+ return -1;
+ s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
+ if (!s1ap)
+ return -2;
+
+ eNB_RRC_INST *rrc = RC.rrc[CC_id];
+ RrcConfigurationReq *conf = &rrc->configuration;
+
+ uint8_t num_plmn_old = conf->num_plmn;
+ uint16_t mcc[PLMN_LIST_MAX_SIZE];
+ uint16_t mnc[PLMN_LIST_MAX_SIZE];
+ uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE];
+ for (int i = 0; i < num_plmn_old; ++i) {
+ mcc[i] = conf->mcc[i];
+ mnc[i] = conf->mnc[i];
+ mnc_digit_length[i] = conf->mnc_digit_length[i];
+ }
+
+ conf->num_plmn = (uint8_t) n_plmn;
+ for (int i = 0; i < conf->num_plmn; ++i) {
+ conf->mcc[i] = plmn_id[i]->mcc;
+ conf->mnc[i] = plmn_id[i]->mnc;
+ conf->mnc_digit_length[i] = plmn_id[i]->mnc_length;
+ }
+
+ rrc_eNB_carrier_data_t *carrier = &rrc->carrier[CC_id];
+ extern uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,
+ int Mod_id,
+ int CC_id,
+ BOOLEAN_t brOption,
+ RrcConfigurationReq *configuration);
+ carrier->sizeof_SIB1 = do_SIB1(carrier, mod_id, CC_id, FALSE, conf);
+ if (carrier->sizeof_SIB1 < 0)
+ return -1337; /* SIB1 encoding failed, hell will probably break loose */
+
+ s1ap->num_plmn = (uint8_t) n_plmn;
+ for (int i = 0; i < conf->num_plmn; ++i) {
+ s1ap->mcc[i] = plmn_id[i]->mcc;
+ s1ap->mnc[i] = plmn_id[i]->mnc;
+ s1ap->mnc_digit_length[i] = plmn_id[i]->mnc_length;
+ }
+
+ int bpn_failed = 0;
+ struct s1ap_eNB_mme_data_s *mme = NULL;
+ RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) {
+ for (int i = 0; i < mme->broadcast_plmn_num; ++i) {
+ /* search the new index and update. If we don't find, we count this using
+ * bpn_failed to now how many broadcast_plmns could not be updated */
+ int idx = mme->broadcast_plmn_index[i];
+ int omcc = mcc[idx];
+ int omnc = mnc[idx];
+ int omncl = mnc_digit_length[idx];
+ int j = 0;
+ for (j = 0; j < s1ap->num_plmn; ++j) {
+ if (s1ap->mcc[j] == omcc
+ && s1ap->mnc[j] == omnc
+ && s1ap->mnc_digit_length[j] == omncl) {
+ mme->broadcast_plmn_index[i] = j;
+ break;
+ }
+ }
+ if (j == s1ap->num_plmn) /* could not find the old PLMN in the new ones */
+ bpn_failed++;
+ }
+ }
+ if (bpn_failed > 0)
+ return -10000 - bpn_failed;
+ return 0;
+}
+
int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf){
if (!rrc_is_present(mod_id)) return -1;
s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
@@ -3644,7 +3629,7 @@ int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_con
RB_FOREACH(ue, s1ap_ue_map, &s1ap->s1ap_ue_head){
if (ue->eNB_ue_s1ap_id == enb_ue_s1ap_id) break;
}
- if (ue == NULL) return -1;
+ if (!ue) return 0; // UE does not exist: it might be connected but CN did not answer
if (ue->mme_ref->mme_s1_ip.ipv4)
ue_conf->mme_s1_ip = (char*) &ue->mme_ref->mme_s1_ip.ipv4_address[0];
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h
index ce32883852..2d8a86f7d0 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.h
+++ b/openair2/ENB_APP/flexran_agent_ran_api.h
@@ -656,156 +656,66 @@ int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index);
uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti);
/************************** Slice configuration **************************/
+/* Get the currently active DL slicing algorithm */
+Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id);
+/* Set the active DL slicing algorithm */
+int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo);
+
+/* Get the currently active UL slicing algorithm */
+Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id);
+/* Set the active UL slicing algorithm */
+int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo);
/* Get the DL slice ID for a UE */
int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id);
-
-/* Set the DL slice index(!) for a UE */
-void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx);
+/* Set the DL slice for a UE */
+void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id);
/* Get the UL slice ID for a UE */
int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id);
+/* Set the UL slice for a UE */
+void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id);
-/* Set the UL slice index(!) for a UE */
-void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx);
-
-/* Whether intraslice sharing is active, return boolean */
-int flexran_get_intraslice_sharing_active(mid_t mod_id);
-/* Set whether intraslice sharing is active */
-void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active);
-
-/* Whether intraslice sharing is active, return boolean */
-int flexran_get_interslice_sharing_active(mid_t mod_id);
-/* Set whether intraslice sharing is active */
-void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active);
+/* Create slice in DL, returns the new slice index */
+int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s);
+/* Remove slice in DL, returns new number of slices or -1 on error */
+int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s);
+/* Finds slice in DL with given slice_id and returns slice index */
+int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id);
+/* Return the parameters of slice at index slice_idx */
+void flexran_get_dl_slice(mid_t mod_id,
+ int slice_idx,
+ Protocol__FlexSlice *slice,
+ Protocol__FlexSliceAlgorithm algo);
/* Get the number of slices in DL */
int flexran_get_num_dl_slices(mid_t mod_id);
-/* Query slice existence in DL. Return is boolean value */
-int flexran_dl_slice_exists(mid_t mod_id, int slice_idx);
+/* Create slice in UL, returns the new slice index */
+int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s);
+/* Remove slice in UL */
+int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s);
-/* Create slice in DL, returns the new slice index */
-int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id);
/* Finds slice in DL with given slice_id and returns slice index */
-int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id);
-/* Remove slice in DL, returns new number of slices or -1 on error */
-int flexran_remove_dl_slice(mid_t mod_id, int slice_idx);
-
-/* Get the ID of a slice in DL */
-slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx);
-/* Set the ID of a slice in DL */
-void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id);
-
-/* Get the RB share a slice in DL, value 0-100 */
-int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx);
-/* Set the RB share a slice in DL, value 0-100 */
-void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage);
-
-/* Whether a slice in DL is isolated */
-int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx);
-/* Set whether a slice in DL is isolated */
-void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated);
-
-/* Get the priority of a slice in DL */
-int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx);
-/* Get the priority of a slice in DL */
-void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority);
-
-/* Get the lower end of the frequency range for the slice positioning in DL */
-int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx);
-/* Set the lower end of the frequency range for the slice positioning in DL */
-void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow);
-
-/* Get the higher end of the frequency range for the slice positioning in DL */
-int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx);
-/* Set the higher end of the frequency range for the slice positioning in DL */
-void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh);
-
-/* Get the maximum MCS for slice in DL */
-int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx);
-/* Set the maximum MCS for slice in DL */
-void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs);
-
-/* Get the sorting order of a slice in DL, return value is number of elements
- * in sorting_list */
-int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list);
-/* Set the sorting order of a slice in DL */
-void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n);
-
-/* Get the accounting policy for a slice in DL */
-Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx);
-/* Set the accounting policy for a slice in DL */
-void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting);
-
-/* Get the scheduler name for a slice in DL */
-char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx);
-/* Set the scheduler name for a slice in DL */
-int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name);
-
+int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id);
+/* Return the parameters of slice at index slice_idx */
+void flexran_get_ul_slice(mid_t mod_id,
+ int slice_idx,
+ Protocol__FlexSlice *slice,
+ Protocol__FlexSliceAlgorithm algo);
/* Get the number of slices in UL */
int flexran_get_num_ul_slices(mid_t mod_id);
-/* Query slice existence in UL. Return is boolean value */
-int flexran_ul_slice_exists(mid_t mod_id, int slice_idx);
+/* Get the name of/Set the DL scheduling algorithm. If slicing is active, this
+ * corresponds to the default algorithm for slices, otherwise the currently
+ * used one. */
+char *flexran_get_dl_scheduler_name(mid_t mod_id);
+int flexran_set_dl_scheduler(mid_t mod_id, char *sched);
-/* Create slice in UL, returns the new slice index */
-int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id);
-/* Finds slice in UL with given slice_id and returns slice index */
-int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id);
-/* Remove slice in UL */
-int flexran_remove_ul_slice(mid_t mod_id, int slice_idx);
-
-/* Get the ID of a slice in UL */
-slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx);
-/* Set the ID of a slice in UL */
-void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id);
-
-/* Get the RB share a slice in UL, value 0-100 */
-int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx);
-/* Set the RB share a slice in UL, value 0-100 */
-void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage);
-
-/* TODO Whether a slice in UL is isolated */
-/*int flexran_get_ul_slice_isolation(mid_t mod_id, int slice_idx);*/
-/* TODO Set whether a slice in UL is isolated */
-/*void flexran_set_ul_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated);*/
-
-/* TODO Get the priority of a slice in UL */
-/*int flexran_get_ul_slice_priority(mid_t mod_id, int slice_idx);*/
-/* TODO Set the priority of a slice in UL */
-/*void flexran_set_ul_slice_priority(mid_t mod_id, int slice_idx, int priority);*/
-
-/* Get the first RB for allocation in a slice in UL */
-int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx);
-/* Set the first RB for allocation in a slice in UL */
-void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb);
-
-/* TODO Get the number of RB for the allocation in a slice in UL */
-/*int flexran_get_ul_slice_length_rb(mid_t mod_id, int slice_idx);*/
-/* TODO Set the of number of RB for the allocation in a slice in UL */
-/*void flexran_set_ul_slice_length_rb(mid_t mod_id, int slice_idx, int poshigh);*/
-
-/* Get the maximum MCS for slice in UL */
-int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx);
-/* Set the maximum MCS for slice in UL */
-void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs);
-
-/* TODO Get the sorting order of a slice in UL, return value is number of elements
- * in sorting_list */
-/*int flexran_get_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting **sorting_list);*/
-/* TODO Set the sorting order of a slice in UL */
-/*void flexran_set_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting *sorting_list, int n);*/
-
-/* TODO Get the accounting policy for a slice in UL */
-/*Protocol__UlAccountingPolicy flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx);*/
-/* TODO Set the accounting policy for a slice in UL */
-/*void flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__UlAccountingPolicy accountin);*/
-
-/* Get the scheduler name for a slice in UL */
-char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx);
-/* Set the scheduler name for a slice in UL */
-int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name);
+/* Get the name of/Set the UL scheduler algorithm. Same applies as for the DL
+ * case */
+char *flexran_get_ul_scheduler_name(mid_t mod_id);
+int flexran_set_ul_scheduler(mid_t mod_id, char *sched);
/************************** S1AP **************************/
/* Get the number of MMEs to be connected */
@@ -832,6 +742,15 @@ int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apM
/* Get the S1AP UE conf */
int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf);
+/* Add MMEs and re-issue S1AP Registration Request */
+int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4);
+
+/* Remove MMEs and and cut SCTP to MME */
+int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4);
+
+/* Set a new PLMN configuration */
+int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__FlexPlmn **plmn_id);
+
/********************* general information *****************/
/* get an ID for this BS (or part of a BS) */
uint64_t flexran_get_bs_id(mid_t mod_id);
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c
index a64f2d529b..789ce4c715 100644
--- a/openair2/F1AP/f1ap_cu_ue_context_management.c
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.c
@@ -226,7 +226,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
ie->value.choice.ResourceCoordinationTransferContainer.buf = malloc(4);
ie->value.choice.ResourceCoordinationTransferContainer.size = 4;
- strncpy((char *)ie->value.choice.ResourceCoordinationTransferContainer.buf, "123", 3);
+ strncpy((char *)ie->value.choice.ResourceCoordinationTransferContainer.buf, "123", 4);
OCTET_STRING_fromBuf(&ie->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as",
diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h
index 4c5da80764..bc4c4cf9d9 100644
--- a/openair2/GNB_APP/RRC_nr_paramsvalues.h
+++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h
@@ -133,7 +133,8 @@
#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR "prach_RootSequenceIndex_PR"
#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX "prach_RootSequenceIndex"
#define GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING "msg1_SubcarrierSpacing"
-#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG "restrictedSetConfig"
+#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG "restrictedSetConfig"
+#define GNB_CONFIG_STRING_MSG3TRANSFPREC "msg3_transformPrecoder"
#define GNB_CONFIG_STRING_PUSCHTIMEDOMAINALLOCATIONLIST "puschTimeDomainAllocationList"
#define GNB_CONFIG_STRING_MSG3DELTAPREABMLE "msg3_DeltaPreamble"
#define GNB_CONFIG_STRING_P0NOMINALWITHGRANT "p0_NominalWithGrant"
@@ -246,7 +247,7 @@
{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:-1,TYPE_INT64,0/*17*/},\
{GNB_CONFIG_STRING_INITIALDLBWPK0_1,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->k0,defint64val:-1,TYPE_INT64,0/*18*/},\
{GNB_CONFIG_STRING_INITIALDLBWPMAPPINGTYPE_1,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA,TYPE_INT64,0/*19*/},\
-{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*20*/}, \
+{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_1,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*20*/}, \
{GNB_CONFIG_STRING_INITIALDLBWPK0_2,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->k0,defint64val:-1,TYPE_INT64,0/*21*/},\
{GNB_CONFIG_STRING_INITIALDLBWPMAPPINGTYPE_2,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA,TYPE_INT64,0/*22*/},\
{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_2,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->startSymbolAndLength,defint64val:54,TYPE_INT64,0/*23*/},\
@@ -311,11 +312,12 @@
{GNB_CONFIG_STRING_RSRPTHRESHOLDSSB,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB,defint64val:19,TYPE_INT64,0/*82*/},\
{GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR,NULL,0,uptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present,defuintval:NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139,TYPE_UINT,0/*83*/},\
{GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139,defint64val:0,TYPE_INT64,0/*84*/},\
-{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig,defintval:NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet,TYPE_INT64,0/*85*/}, \
-{GNB_CONFIG_STRING_INITIALULBWPK2_0,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2,defint64val:-1,TYPE_INT64,0/*86*/},\
-{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,/*87*/},\
-{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:55,TYPE_INT64,0/*88*/},\
-{GNB_CONFIG_STRING_INITIALULBWPK2_1,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2,defint64val:-1,TYPE_INT64,0/*89*/}, \
+{GNB_CONFIG_STRING_RESTRICTEDSETCONFIG,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig,defintval:NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet,TYPE_INT64,0/*85*/}, \
+{GNB_CONFIG_STRING_MSG3TRANSFPREC,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder,defintval:1,TYPE_INT64,0/*86*/}, \
+{GNB_CONFIG_STRING_INITIALULBWPK2_0,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2,defint64val:-1,TYPE_INT64,0/*87*/},\
+{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,/*88*/},\
+{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:55,TYPE_INT64,0/*89*/},\
+{GNB_CONFIG_STRING_INITIALULBWPK2_1,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2,defint64val:-1,TYPE_INT64,0/*90*/}, \
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_1,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_1,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_2,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->k2,defint64val:-1,TYPE_INT64,0},\
@@ -325,7 +327,7 @@
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_3,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_3,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_4,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->k2,defint64val:-1,TYPE_INT64,0},\
-{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*99*/}, \
+{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*100*/}, \
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_5,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_5,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
@@ -335,7 +337,7 @@
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_6,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[6]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_7,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
-{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*109*/}, \
+{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*110*/}, \
{GNB_CONFIG_STRING_INITIALULBWPK2_8,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_8,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_8,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
@@ -345,7 +347,7 @@
{GNB_CONFIG_STRING_INITIALULBWPK2_10,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_10,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_10,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
-{GNB_CONFIG_STRING_INITIALULBWPK2_11,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->k2,defint64val:-1,TYPE_INT64,0/*119*/}, \
+{GNB_CONFIG_STRING_INITIALULBWPK2_11,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->k2,defint64val:-1,TYPE_INT64,0/*120*/}, \
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_11,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_11,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_12,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[12]->k2,defint64val:-1,TYPE_INT64,0},\
@@ -355,7 +357,7 @@
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_13,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_13,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_14,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->k2,defint64val:-1,TYPE_INT64,0},\
-{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*129*/}, \
+{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*130*/}, \
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_15,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_15,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
@@ -365,7 +367,7 @@
{GNB_CONFIG_STRING_PUCCHGROUPHOPPING, NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_GroupHopping,defint64val:NR_PUCCH_ConfigCommon__pucch_GroupHopping_neither,TYPE_INT64,0},\
{GNB_CONFIG_STRING_HOPPINGID, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId,defint64val:40,TYPE_INT64,0},\
{GNB_CONFIG_STRING_P0NOMINAL, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal,defint64val:1,TYPE_INT64,0},\
-{GNB_CONFIG_STRING_SSBPOSITIONSINBURSTPR,NULL,0,uptr:&scc->ssb_PositionsInBurst->present,defuintval:NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap,TYPE_UINT,0/*139*/}, \
+{GNB_CONFIG_STRING_SSBPOSITIONSINBURSTPR,NULL,0,uptr:&scc->ssb_PositionsInBurst->present,defuintval:NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap,TYPE_UINT,0/*140*/}, \
{GNB_CONFIG_STRING_SSBPOSITIONSINBURST,NULL,0,u64ptr:&ssb_bitmap,defintval:0xff,TYPE_UINT64,0}, \
{GNB_CONFIG_STRING_REFERENCESUBCARRIERSPACING,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing,defint64val:NR_SubcarrierSpacing_kHz30,TYPE_INT64,0},\
{GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity,defint64val:NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms0p5,TYPE_INT64,0},\
@@ -379,7 +381,7 @@
{GNB_CONFIG_STRING_NROFUPLINKSLOTS2,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSlots,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSymbols,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,i64ptr:&scc->ss_PBCH_BlockPower,defint64val:20,TYPE_INT64,0}, \
-{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,defintval:-1,TYPE_INT64,0/*86*/}}
+{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,defintval:-1,TYPE_INT64,0}}
diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c
index f11e302771..9bdd709262 100644
--- a/openair2/GNB_APP/gnb_app.c
+++ b/openair2/GNB_APP/gnb_app.c
@@ -71,30 +71,30 @@ static void configure_nr_rrc(uint32_t gnb_id)
/*------------------------------------------------------------------------------*/
-/*
+
static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties)
{
uint32_t gnb_id;
- MessageDef *msg_p;
+ //MessageDef *msg_p;
uint32_t register_gnb_pending = 0;
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
{
- s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse
+ //s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse
// note: there is an implicit relationship between the data structure and the message name
- msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse
+ /*msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse
- RCconfig_NR_S1(msg_p, gnb_id);
+ RCconfig_NR_S1(msg_p, gnb_id);*/
if (gnb_id == 0) RCconfig_nr_gtpu();
- s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse
- LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);
+ /*s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse
+ LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);*/
LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id));
- itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
+ //itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
register_gnb_pending++;
}
@@ -102,7 +102,7 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//,
return register_gnb_pending;
}
-*/
+
/*------------------------------------------------------------------------------*/
static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) {
@@ -131,7 +131,7 @@ void *gNB_app_task(void *args_p)
uint32_t gnb_nb = RC.nb_nr_inst;
uint32_t gnb_id_start = 0;
uint32_t gnb_id_end = gnb_id_start + gnb_nb;
- uint32_t x2_register_gnb_pending = 0;
+
uint32_t gnb_id;
MessageDef *msg_p = NULL;
const char *msg_name = NULL;
@@ -170,13 +170,13 @@ void *gNB_app_task(void *args_p)
if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type)
LOG_I(X2AP, "X2AP enabled \n");
- x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
+ __attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
}
if (EPC_MODE_ENABLED) {
/* Try to register each gNB */
//registered_gnb = 0;
- //register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
+ __attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
} else {
/* Start L2L1 task */
msg_p = itti_alloc_new_message(TASK_GNB_APP, INITIALIZE_MESSAGE);
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index e7fd2f3cf8..61aa10e47b 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -54,7 +54,8 @@
#include "common/config/config_userapi.h"
//#include "RRC_config_tools.h"
#include "gnb_paramdef.h"
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_gNB/mac_proto.h"
+
#include "NR_asn_constant.h"
#include "executables/thread-common.h"
#include "NR_SCS-SpecificCarrier.h"
@@ -254,10 +255,9 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA = NULL;
}
- // fix libconfig (asn1c uses long)
- scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower-=((long)1<<32);
- *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->p0_NominalWithGrant-=((long)1<<32);
- *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal-=((long)1<<32);
+ // default value for msg3 precoder is NULL (0 means enabled)
+ if (*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder!=0)
+ scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NULL;
// fix DL and UL Allocation lists
@@ -714,10 +714,14 @@ int RCconfig_nr_gtpu(void ) {
if (address) {
MessageDef *message;
AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, GTPV1U_ENB_S1_REQ))!=NULL,"");
- IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
- LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
- GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
- itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
+ // IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
+ // LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
+
+
+ IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
+ LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
+ GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
+ itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
} else
LOG_E(GTPU,"invalid address for S1U\n");
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index 7621994ab2..1f99f50ece 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -573,10 +573,7 @@ schedule_ue_spec(module_id_t module_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,
VCD_FUNCTION_IN);
start_meas(&eNB->schedule_dlsch_preprocessor);
- dlsch_scheduler_pre_processor(module_idP,
- CC_id,
- frameP,
- subframeP);
+ eNB->pre_processor_dl.dl(module_idP, CC_id, frameP, subframeP);
stop_meas(&eNB->schedule_dlsch_preprocessor);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,
VCD_FUNCTION_OUT);
@@ -588,6 +585,7 @@ schedule_ue_spec(module_id_t module_idP,
UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
UE_TEMPLATE *ue_template = &UE_info->UE_template[CC_id][UE_id];
eNB_UE_STATS *eNB_UE_stats = &UE_info->eNB_UE_stats[CC_id][UE_id];
+ eNB_UE_stats->TBS = 0;
const rnti_t rnti = ue_template->rnti;
// If TDD
@@ -679,15 +677,15 @@ schedule_ue_spec(module_id_t module_idP,
const uint32_t rbc = allocate_prbs_sub(
nb_rb, N_RB_DL, N_RBG, ue_sched_ctrl->rballoc_sub_UE[CC_id]);
- if (nb_rb > ue_sched_ctrl->pre_nb_available_rbs[CC_id]) {
- LOG_D(MAC,
- "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
+ if (nb_rb > ue_sched_ctrl->pre_nb_available_rbs[CC_id])
+ LOG_W(MAC,
+ "[eNB %d] %d.%d CC_id %d : should not schedule UE %d, its "
+ "retransmission takes more resources than we have\n",
module_idP,
frameP,
+ subframeP,
CC_id,
UE_id);
- continue;
- }
/* CDRX */
ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer
@@ -799,6 +797,7 @@ schedule_ue_spec(module_id_t module_idP,
eNB_UE_stats->rbs_used_retx = nb_rb;
eNB_UE_stats->total_rbs_used_retx += nb_rb;
eNB_UE_stats->dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1;
+ eNB_UE_stats->TBS = TBS;
} else {
// Now check RLC information to compute number of required RBs
// get maximum TBS size for RLC request
@@ -842,13 +841,18 @@ schedule_ue_spec(module_id_t module_idP,
if (ue_sched_ctrl->dl_lc_bytes[i] == 0) // no data in this LC!
continue;
- LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, LC%d->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
+ const uint32_t data =
+ min(ue_sched_ctrl->dl_lc_bytes[i],
+ TBS - ta_len - header_length_total - sdu_length_total - 3);
+ LOG_D(MAC,
+ "[eNB %d] SFN/SF %d.%d, LC%d->DLSCH CC_id %d, Requesting %d "
+ "bytes from RLC (RRC message)\n",
module_idP,
frameP,
subframeP,
lcid,
CC_id,
- TBS - ta_len - header_length_total - sdu_length_total - 3);
+ data);
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
rnti,
@@ -857,7 +861,7 @@ schedule_ue_spec(module_id_t module_idP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
- TBS - ta_len - header_length_total - sdu_length_total - 3,
+ data,
(char *)&dlsch_buffer[sdu_length_total],
0,
0
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 78d6f6a3d7..89c2ecc83d 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -2131,33 +2131,36 @@ dump_ue_list(UE_list_t *listP) {
* Add a UE to UE_list listP
*/
inline void add_ue_list(UE_list_t *listP, int UE_id) {
- if (listP->head == -1) {
- listP->head = UE_id;
- listP->next[UE_id] = -1;
- } else {
- int i = listP->head;
- while (listP->next[i] >= 0)
- i = listP->next[i];
- listP->next[i] = UE_id;
- listP->next[UE_id] = -1;
- }
+ int *cur = &listP->head;
+ while (*cur >= 0)
+ cur = &listP->next[*cur];
+ *cur = UE_id;
}
//------------------------------------------------------------------------------
/*
- * Remove a UE from the UE_list listP, return the previous element
+ * Remove a UE from the UE_list listP
*/
inline int remove_ue_list(UE_list_t *listP, int UE_id) {
- listP->next[UE_id] = -1;
- if (listP->head == UE_id) {
- listP->head = listP->next[UE_id];
- return -1;
- }
+ int *cur = &listP->head;
+ while (*cur != -1 && *cur != UE_id)
+ cur = &listP->next[*cur];
+ if (*cur == -1)
+ return 0;
+ int *next = &listP->next[*cur];
+ *cur = listP->next[*cur];
+ *next = -1;
+ return 1;
+}
- int previous = prev(listP, UE_id);
- if (previous != -1)
- listP->next[previous] = listP->next[UE_id];
- return previous;
+//------------------------------------------------------------------------------
+/*
+ * Initialize the UE_list listP
+ */
+inline void init_ue_list(UE_list_t *listP) {
+ listP->head = -1;
+ for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i)
+ listP->next[i] = -1;
}
//------------------------------------------------------------------------------
@@ -2196,6 +2199,12 @@ add_new_ue(module_id_t mod_idP,
UE_info->active[UE_id] = TRUE;
add_ue_list(&UE_info->list, UE_id);
dump_ue_list(&UE_info->list);
+ pp_impl_param_t* dl = &RC.mac[mod_idP]->pre_processor_dl;
+ if (dl->slices) // inform slice implementation about new UE
+ dl->add_UE(dl->slices, UE_id);
+ pp_impl_param_t* ul = &RC.mac[mod_idP]->pre_processor_ul;
+ if (ul->slices) // inform slice implementation about new UE
+ ul->add_UE(ul->slices, UE_id);
if (IS_SOFTMODEM_IQPLAYER)// not specific to record/playback ?
UE_info->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0;
UE_info->UE_template[cc_idP][UE_id].rach_resource_type = rach_resource_type;
@@ -2259,6 +2268,12 @@ rrc_mac_remove_ue(module_id_t mod_idP,
UE_info->num_UEs--;
remove_ue_list(&UE_info->list, UE_id);
+ pp_impl_param_t* dl = &RC.mac[mod_idP]->pre_processor_dl;
+ if (dl->slices) // inform slice implementation about new UE
+ dl->remove_UE(dl->slices, UE_id);
+ pp_impl_param_t* ul = &RC.mac[mod_idP]->pre_processor_ul;
+ if (ul->slices) // inform slice implementation about new UE
+ ul->remove_UE(ul->slices, UE_id);
/* Clear all remaining pending transmissions */
memset(&UE_info->UE_template[pCC_id][UE_id], 0, sizeof(UE_TEMPLATE));
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 3062e5c964..2de45db856 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -1301,11 +1301,11 @@ schedule_ulsch_rnti(module_id_t module_idP,
/*
* ULSCH preprocessor: set UE_template->
- * pre_allocated_nb_rb_ul[slice_idx]
+ * pre_allocated_nb_rb_ul
* pre_assigned_mcs_ul
* pre_allocated_rb_table_index_ul
*/
- ulsch_scheduler_pre_processor(module_idP, CC_id, frameP, subframeP, sched_frame, sched_subframeP);
+ mac->pre_processor_ul.ul(module_idP, CC_id, frameP, subframeP, sched_frame, sched_subframeP);
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
if (UE_info->UE_template[CC_id][UE_id].rach_resource_type > 0)
diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index 329e262c82..faefc481f6 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -155,9 +155,6 @@
/*!\brief minimum MAC data needed for transmitting 1 min RLC PDU size + 1 byte MAC subHeader */
#define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE)
-/*!\brief maximum number of slices / groups */
-#define MAX_NUM_SLICES 10
-
#define U_PLANE_INACTIVITY_VALUE 0 /* defined 10ms order (zero means infinity) */
@@ -543,7 +540,6 @@ typedef enum {
SCHED_MODE_FAIR_RR /// fair raund robin
} SCHEDULER_MODES;
-
/*! \brief temporary struct for ULSCH sched */
typedef struct {
rnti_t rnti;
@@ -1150,9 +1146,6 @@ typedef struct {
UE_list_t list;
int num_UEs;
boolean_t active[MAX_MOBILES_PER_ENB];
-
- /// Sorting criteria for the UE list in the MAC preprocessor
- uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM];
} UE_info_t;
/*! \brief deleting control information*/
@@ -1171,101 +1164,6 @@ typedef struct {
int tail_freelist; ///the tail position of the delete list
} UE_free_list_t;
-/**
- * slice specific scheduler for the DL
- */
-typedef void (*slice_scheduler_dl)(module_id_t mod_id,
- int slice_idx,
- frame_t frame,
- sub_frame_t subframe,
- int *mbsfn_flag);
-
-typedef struct {
- slice_id_t id;
-
- /// RB share for each slice
- float pct;
-
- /// whether this slice is isolated from the others
- int isol;
-
- int prio;
-
- /// Frequency ranges for slice positioning
- int pos_low;
- int pos_high;
-
- // max mcs for each slice
- int maxmcs;
-
- /// criteria for sorting policies of the slices
- uint32_t sorting;
-
- /// Accounting policy (just greedy(1) or fair(0) setting for now)
- int accounting;
-
- /// name of available scheduler
- char *sched_name;
-
- /// pointer to the slice specific scheduler in DL
- slice_scheduler_dl sched_cb;
-
-} slice_sched_conf_dl_t;
-
-typedef void (*slice_scheduler_ul)(module_id_t mod_id,
- int slice_idx,
- frame_t frame,
- sub_frame_t subframe,
- unsigned char sched_subframe,
- uint16_t *first_rb);
-
-typedef struct {
- slice_id_t id;
-
- /// RB share for each slice
- float pct;
-
- // MAX MCS for each slice
- int maxmcs;
-
- /// criteria for sorting policies of the slices
- uint32_t sorting;
-
- /// starting RB (RB offset) of UL scheduling
- int first_rb;
-
- /// name of available scheduler
- char *sched_name;
-
- /// pointer to the slice specific scheduler in UL
- slice_scheduler_ul sched_cb;
-
-} slice_sched_conf_ul_t;
-
-
-typedef struct {
- /// counter used to indicate when all slices have pre-allocated UEs
- //int slice_counter;
-
- /// indicates whether remaining RBs after first intra-slice allocation will
- /// be allocated to UEs of the same slice
- int intraslice_share_active;
- /// indicates whether remaining RBs after slice allocation will be
- /// allocated to UEs of another slice. Isolated slices will be ignored
- int interslice_share_active;
-
- /// number of active DL slices
- int n_dl;
- slice_sched_conf_dl_t dl[MAX_NUM_SLICES];
-
- /// number of active UL slices
- int n_ul;
- slice_sched_conf_ul_t ul[MAX_NUM_SLICES];
-
- /// common rb allocation list between slices
- uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX];
-} slice_info_t;
-
/**
* describes contiguous RBs
*/
@@ -1274,6 +1172,82 @@ typedef struct {
int length;
} contig_rbs_t;
+/**
+ * definition of a scheduling algorithm implementation used in the
+ * default DL scheduler
+ */
+typedef struct {
+ char *name;
+ void *(*setup)(void);
+ void (*unset)(void **);
+ int (*run)(
+ module_id_t, int, int, int, UE_list_t *, int, int, uint8_t *, void *);
+ void *data;
+} default_sched_dl_algo_t;
+
+/**
+ * definition of a scheduling algorithm implementation used in the
+ * default UL scheduler
+ */
+typedef struct {
+ char *name;
+ void *(*setup)(void);
+ void (*unset)(void **);
+ int (*run)(
+ module_id_t, int, int, int, int, int, UE_list_t *, int, int, contig_rbs_t *, void *);
+ void *data;
+} default_sched_ul_algo_t;
+
+typedef void (*pp_impl_dl)(module_id_t mod_id,
+ int CC_id,
+ frame_t frame,
+ sub_frame_t subframe);
+typedef void (*pp_impl_ul)(module_id_t mod_id,
+ int CC_id,
+ frame_t frame,
+ sub_frame_t subframe,
+ frame_t sched_frame,
+ sub_frame_t sched_subframe);
+
+struct slice_info_s;
+typedef struct {
+ int algorithm;
+
+ /// inform the slice algorithm about a new UE
+ void (*add_UE)(struct slice_info_s *s, int UE_id);
+ /// inform the slice algorithm about a UE that disconnected
+ void (*remove_UE)(struct slice_info_s *s, int UE_id);
+ /// move a UE to a slice in DL/UL, -1 means don't move (no-op).
+ void (*move_UE)(struct slice_info_s *s, int UE_id, int idx);
+
+ /// Adds a new slice through admission control. slice_params are
+ /// algorithm-specific parameters. sched is either a default_sched_ul_algo_t
+ /// or default_sched_dl_algo_t, depending on whether this implementation
+ /// handles UL/DL. If slice at index exists, updates existing
+ /// slice. Returns index of new slice or -1 on failure.
+ int (*addmod_slice)(struct slice_info_s *s,
+ int id,
+ char *label,
+ void *sched,
+ void *slice_params);
+ /// Returns slice through slice_idx. 1 if successful, 0 if not.
+ int (*remove_slice)(struct slice_info_s *s, uint8_t slice_idx);
+
+ union {
+ pp_impl_dl dl;
+ pp_impl_ul ul;
+ };
+
+ union {
+ default_sched_ul_algo_t ul_algo;
+ default_sched_dl_algo_t dl_algo;
+ };
+
+ void (*destroy)(struct slice_info_s **s);
+
+ struct slice_info_s *slices;
+} pp_impl_param_t;
+
/*! \brief eNB common channels */
typedef struct {
int physCellId;
@@ -1395,9 +1369,6 @@ typedef struct eNB_MAC_INST_s {
uint32_t ul_handle;
UE_info_t UE_info;
- /// slice-related configuration
- slice_info_t slice_info;
-
///subband bitmap configuration
SBMAP_CONF sbmap_conf;
/// CCE table used to build DCI scheduling information
@@ -1432,6 +1403,11 @@ typedef struct eNB_MAC_INST_s {
UE_free_list_t UE_free_list;
/// for scheduling selection
SCHEDULER_MODES scheduler_mode;
+ /// Default scheduler: Pre-processor implementation. Algorithms for UL/DL
+ /// are called by ULSCH/DLSCH, respectively. Pro-processor implementation can
+ /// encapsulate slicing.
+ pp_impl_param_t pre_processor_dl;
+ pp_impl_param_t pre_processor_ul;
int32_t puSch10xSnr;
int32_t puCch10xSnr;
diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h
index 2cb86c25af..9d49fdffd5 100644
--- a/openair2/LAYER2/MAC/mac_proto.h
+++ b/openair2/LAYER2/MAC/mac_proto.h
@@ -187,8 +187,6 @@ void add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP,
void init_UE_info(UE_info_t *UE_info);
-void init_slice_info(slice_info_t *sli);
-
int mac_top_init(int eMBMS_active, char *uecap_xer,
uint8_t cba_group_active, uint8_t HO_active);
@@ -661,6 +659,7 @@ int prev(UE_list_t *listP, int nodeP);
void add_ue_list(UE_list_t *listP, int UE_id);
int remove_ue_list(UE_list_t *listP, int UE_id);
void dump_ue_list(UE_list_t *listP);
+void init_ue_list(UE_list_t *listP);
int UE_num_active_CC(UE_info_t *listP, int ue_idP);
int UE_PCCID(module_id_t mod_idP, int ue_idP);
rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP);
@@ -675,10 +674,10 @@ void set_ul_DAI(int module_idP,
void ulsch_scheduler_pre_processor(module_id_t module_idP,
int CC_id,
- int frameP,
+ frame_t frameP,
sub_frame_t subframeP,
- int sched_frameP,
- unsigned char sched_subframeP);
+ frame_t sched_frameP,
+ sub_frame_t sched_subframeP);
int phy_stats_exist(module_id_t Mod_id, int rnti);
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index 1a88623a1f..af6d1a7ac3 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -45,11 +45,8 @@ extern RAN_CONTEXT_t RC;
void init_UE_info(UE_info_t *UE_info)
{
- int list_el;
UE_info->num_UEs = 0;
- UE_info->list.head = -1;
- for (list_el = 0; list_el < MAX_MOBILES_PER_ENB; list_el++)
- UE_info->list.next[list_el] = -1;
+ init_ue_list(&UE_info->list);
memset(UE_info->DLSCH_pdu, 0, sizeof(UE_info->DLSCH_pdu));
memset(UE_info->UE_template, 0, sizeof(UE_info->UE_template));
memset(UE_info->eNB_UE_stats, 0, sizeof(UE_info->eNB_UE_stats));
@@ -57,32 +54,6 @@ void init_UE_info(UE_info_t *UE_info)
memset(UE_info->active, 0, sizeof(UE_info->active));
}
-void init_slice_info(slice_info_t *sli)
-{
- sli->intraslice_share_active = 1;
- sli->interslice_share_active = 1;
-
- sli->n_dl = 1;
- memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES);
- sli->dl[0].pct = 1.0;
- sli->dl[0].prio = 10;
- sli->dl[0].pos_high = N_RBG_MAX;
- sli->dl[0].maxmcs = 28;
- sli->dl[0].sorting = 0x012345;
- sli->dl[0].sched_name = "schedule_ue_spec";
- sli->dl[0].sched_cb = dlsym(NULL, sli->dl[0].sched_name);
- AssertFatal(sli->dl[0].sched_cb, "DLSCH scheduler callback is NULL\n");
-
- sli->n_ul = 1;
- memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES);
- sli->ul[0].pct = 1.0;
- sli->ul[0].maxmcs = 20;
- sli->ul[0].sorting = 0x0123;
- sli->ul[0].sched_name = "schedule_ulsch_rnti";
- sli->ul[0].sched_cb = dlsym(NULL, sli->ul[0].sched_name);
- AssertFatal(sli->ul[0].sched_cb, "ULSCH scheduler callback is NULL\n");
-}
-
void mac_top_init_eNB(void)
{
module_id_t i, j;
@@ -129,8 +100,23 @@ void mac_top_init_eNB(void)
mac[i]->if_inst = IF_Module_init(i);
+ mac[i]->pre_processor_dl.algorithm = 0;
+ mac[i]->pre_processor_dl.dl = dlsch_scheduler_pre_processor;
+ char *s = "round_robin_dl";
+ void *d = dlsym(NULL, s);
+ AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s);
+ mac[i]->pre_processor_dl.dl_algo = *(default_sched_dl_algo_t *) d;
+ mac[i]->pre_processor_dl.dl_algo.data = mac[i]->pre_processor_dl.dl_algo.setup();
+
+ mac[i]->pre_processor_ul.algorithm = 0;
+ mac[i]->pre_processor_ul.ul = ulsch_scheduler_pre_processor;
+ s = "round_robin_ul";
+ d = dlsym(NULL, s);
+ AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s);
+ mac[i]->pre_processor_ul.ul_algo = *(default_sched_ul_algo_t *) d;
+ mac[i]->pre_processor_ul.ul_algo.data = mac[i]->pre_processor_ul.ul_algo.setup();
+
init_UE_info(&mac[i]->UE_info);
- init_slice_info(&mac[i]->slice_info);
}
RC.mac = mac;
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index 8569d8f166..6477d60021 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -69,31 +69,367 @@ int get_rbg_size_last(module_id_t Mod_id, int CC_id) {
return RBGsize;
}
-int g_start_ue_dl = -1;
-int round_robin_dl(module_id_t Mod_id,
- int CC_id,
- int frame,
- int subframe,
- UE_list_t *UE_list,
- int max_num_ue,
- int n_rbg_sched,
- uint8_t *rbgalloc_mask) {
+void *rr_dl_setup(void) {
+ void *data = malloc(sizeof(int));
+ *(int *) data = 0;
+ AssertFatal(data, "could not allocate data in %s()\n", __func__);
+ return data;
+}
+void rr_dl_unset(void **data) {
+ if (*data)
+ free(*data);
+ *data = NULL;
+}
+int rr_dl_run(module_id_t Mod_id,
+ int CC_id,
+ int frame,
+ int subframe,
+ UE_list_t *UE_list,
+ int max_num_ue,
+ int n_rbg_sched,
+ uint8_t *rbgalloc_mask,
+ void *data) {
DevAssert(UE_list->head >= 0);
DevAssert(n_rbg_sched > 0);
const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
const int RBGsize = get_min_rb_unit(Mod_id, CC_id);
const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id);
- int num_ue_req = 0;
UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
- int rb_required[MAX_MOBILES_PER_ENB]; // how much UEs request
- memset(rb_required, 0, sizeof(rb_required));
-
int rbg = 0;
for (; !rbgalloc_mask[rbg]; rbg++)
; /* fast-forward to first allowed RBG */
- // Calculate the amount of RBs every UE wants to send.
+ /* just start with the UE after the one we had last time. If it does not
+ * exist, this will start at the head */
+ int *start_ue = data;
+ *start_ue = next_ue_list_looped(UE_list, *start_ue);
+
+ int UE_id = *start_ue;
+ UE_list_t UE_sched;
+ int *cur_UE = &UE_sched.head;
+ // Allocate retransmissions, and mark UEs with new transmissions
+ do {
+ // check whether there are HARQ retransmissions
+ const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id];
+ const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe);
+ UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+ const uint8_t round = ue_ctrl->round[CC_id][harq_pid];
+ if (round != 8) { // retransmission: allocate
+ const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid];
+ if (nb_rb == 0)
+ goto skip_ue;
+ int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize;
+ // needs more RBGs than we can allocate
+ if (nb_rbg > n_rbg_sched) {
+ LOG_D(MAC,
+ "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n",
+ UE_id, nb_rbg, n_rbg_sched);
+ goto skip_ue;
+ }
+ // ensure that the number of RBs can be contained by the RBGs (!), i.e.
+ // if we allocate the last RBG this one should have the full RBGsize
+ if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched
+ && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) {
+ LOG_D(MAC,
+ "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n",
+ UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize);
+ goto skip_ue;
+ }
+ const uint8_t cqi = ue_ctrl->dl_cqi[CC_id];
+ const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi);
+ if (idx < 0)
+ goto skip_ue; // cannot allocate CCE
+ ue_ctrl->pre_dci_dl_pdu_idx = idx;
+ // retransmissions: directly allocate
+ n_rbg_sched -= nb_rbg;
+ ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb;
+ for (; nb_rbg > 0; rbg++) {
+ if (!rbgalloc_mask[rbg])
+ continue;
+ ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
+ rbgalloc_mask[rbg] = 0;
+ nb_rbg--;
+ }
+ LOG_D(MAC,
+ "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d "
+ "round %d retx nb_rb %d pre_nb_available_rbs %d\n",
+ frame, subframe, n_rbg_sched, UE_id, round,
+ UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid],
+ ue_ctrl->pre_nb_available_rbs[CC_id]);
+ /* if there are no more RBG to give, return */
+ if (n_rbg_sched <= 0)
+ return 0;
+ max_num_ue--;
+ /* if there are no UEs that can be allocated anymore, return */
+ if (max_num_ue == 0)
+ return n_rbg_sched;
+ for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
+ } else {
+ if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total > 0) {
+ *cur_UE = UE_id;
+ cur_UE = &UE_sched.next[UE_id];
+ }
+ }
+
+skip_ue:
+ UE_id = next_ue_list_looped(UE_list, UE_id);
+ } while (UE_id != *start_ue);
+ *cur_UE = -1; // mark end
+
+ if (UE_sched.head < 0)
+ return n_rbg_sched; // no UE has a transmission
+
+ // after allocating retransmissions: pre-allocate CCE, compute number of
+ // requested RBGs
+ max_num_ue = min(max_num_ue, n_rbg_sched);
+ int rb_required[MAX_MOBILES_PER_ENB]; // how much UEs request
+ cur_UE = &UE_sched.head;
+ while (*cur_UE >= 0 && max_num_ue > 0) {
+ const int UE_id = *cur_UE;
+ cur_UE = &UE_sched.next[UE_id]; // go to next
+ const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id];
+ const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi);
+ if (idx < 0) {
+ LOG_D(MAC, "cannot allocate CCE for UE %d, skipping\n", UE_id);
+ continue;
+ }
+ UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx;
+ const int mcs = cqi_to_mcs[cqi];
+ UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs;
+ const uint32_t B = UE_info->UE_template[CC_id][UE_id].dl_buffer_total;
+ rb_required[UE_id] = find_nb_rb_DL(mcs, B, n_rbg_sched * RBGsize, RBGsize);
+ max_num_ue--;
+ }
+ *cur_UE = -1; // not all UEs might be allocated, mark end
+
+ /* for one UE after the next: allocate resources */
+ cur_UE = &UE_sched.head;
+ while (*cur_UE >= 0) {
+ const int UE_id = *cur_UE;
+ UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+ ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
+ rbgalloc_mask[rbg] = 0;
+ const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize;
+ ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG;
+ rb_required[UE_id] -= sRBG;
+ if (rb_required[UE_id] <= 0) {
+ *cur_UE = UE_sched.next[*cur_UE];
+ if (*cur_UE < 0)
+ cur_UE = &UE_sched.head;
+ } else {
+ cur_UE = UE_sched.next[*cur_UE] < 0 ? &UE_sched.head : &UE_sched.next[*cur_UE];
+ }
+ n_rbg_sched--;
+ if (n_rbg_sched <= 0)
+ break;
+ for (rbg++; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
+ }
+
+ return n_rbg_sched;
+}
+default_sched_dl_algo_t round_robin_dl = {
+ .name = "round_robin_dl",
+ .setup = rr_dl_setup,
+ .unset = rr_dl_unset,
+ .run = rr_dl_run,
+ .data = NULL
+};
+
+
+void *pf_dl_setup(void) {
+ void *data = calloc(MAX_MOBILES_PER_ENB, sizeof(float));
+ for (int i = 0; i < MAX_MOBILES_PER_ENB; i++)
+ *(float *) data = 0.0f;
+ AssertFatal(data, "could not allocate data in %s()\n", __func__);
+ return data;
+}
+void pf_dl_unset(void **data) {
+ if (*data)
+ free(*data);
+ *data = NULL;
+}
+int pf_wbcqi_dl_run(module_id_t Mod_id,
+ int CC_id,
+ int frame,
+ int subframe,
+ UE_list_t *UE_list,
+ int max_num_ue,
+ int n_rbg_sched,
+ uint8_t *rbgalloc_mask,
+ void *data) {
+ DevAssert(UE_list->head >= 0);
+ DevAssert(n_rbg_sched > 0);
+ const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
+ const int RBGsize = get_min_rb_unit(Mod_id, CC_id);
+ const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id);
+ UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
+
+ int rbg = 0;
+ for (; !rbgalloc_mask[rbg]; rbg++)
+ ; /* fast-forward to first allowed RBG */
+
+ UE_list_t UE_sched; // UEs that could be scheduled
+ int *uep = &UE_sched.head;
+ float *thr_ue = data;
+ float coeff_ue[MAX_MOBILES_PER_ENB];
+
+ for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
+ const float a = 0.0005f; // corresponds to 200ms window
+ const uint32_t b = UE_info->eNB_UE_stats[CC_id][UE_id].TBS;
+ thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b;
+
+ // check whether there are HARQ retransmissions
+ const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id];
+ const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe);
+ UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+ const uint8_t round = ue_ctrl->round[CC_id][harq_pid];
+ if (round != 8) { // retransmission: allocate
+ const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid];
+ if (nb_rb == 0)
+ continue;
+ int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize;
+ // needs more RBGs than we can allocate
+ if (nb_rbg > n_rbg_sched) {
+ LOG_D(MAC,
+ "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n",
+ UE_id, nb_rbg, n_rbg_sched);
+ continue;
+ }
+ // ensure that the number of RBs can be contained by the RBGs (!), i.e.
+ // if we allocate the last RBG this one should have the full RBGsize
+ if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched
+ && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) {
+ LOG_D(MAC,
+ "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n",
+ UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize);
+ continue;
+ }
+ const uint8_t cqi = ue_ctrl->dl_cqi[CC_id];
+ const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi);
+ if (idx < 0)
+ continue; // cannot allocate CCE
+ ue_ctrl->pre_dci_dl_pdu_idx = idx;
+ // retransmissions: directly allocate
+ n_rbg_sched -= nb_rbg;
+ ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb;
+ for (; nb_rbg > 0; rbg++) {
+ if (!rbgalloc_mask[rbg])
+ continue;
+ ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
+ rbgalloc_mask[rbg] = 0;
+ nb_rbg--;
+ }
+ LOG_D(MAC,
+ "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d "
+ "round %d retx nb_rb %d pre_nb_available_rbs %d\n",
+ frame, subframe, n_rbg_sched, UE_id, round,
+ UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid],
+ ue_ctrl->pre_nb_available_rbs[CC_id]);
+ /* if there are no more RBG to give, return */
+ if (n_rbg_sched <= 0)
+ return 0;
+ max_num_ue--;
+ /* if there are no UEs that can be allocated anymore, return */
+ if (max_num_ue == 0)
+ return n_rbg_sched;
+ for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
+ } else {
+ if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total == 0)
+ continue;
+
+ const int mcs = cqi_to_mcs[UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
+ const uint32_t tbs = get_TBS_DL(mcs, RBGsize);
+ coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id];
+ //LOG_I(MAC, " pf UE %d: old TBS %d thr %f MCS %d TBS %d coeff %f\n",
+ // UE_id, b, thr_ue[UE_id], mcs, tbs, coeff_ue[UE_id]);
+ *uep = UE_id;
+ uep = &UE_sched.next[UE_id];
+ }
+ }
+ *uep = -1;
+
+ while (max_num_ue > 0 && n_rbg_sched > 0 && UE_sched.head >= 0) {
+ int *max = &UE_sched.head; /* assume head is max */
+ int *p = &UE_sched.next[*max];
+ while (*p >= 0) {
+ /* if the current one has larger coeff, save for later */
+ if (coeff_ue[*p] > coeff_ue[*max])
+ max = p;
+ p = &UE_sched.next[*p];
+ }
+ /* remove the max one */
+ const int UE_id = *max;
+ p = &UE_sched.next[*max];
+ *max = UE_sched.next[*max];
+ *p = -1;
+
+ const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id];
+ const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi);
+ if (idx < 0)
+ continue;
+ UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx;
+
+ max_num_ue--;
+
+ /* allocate as much as possible */
+ const int mcs = cqi_to_mcs[cqi];
+ UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs;
+ int req = find_nb_rb_DL(mcs,
+ UE_info->UE_template[CC_id][UE_id].dl_buffer_total,
+ n_rbg_sched * RBGsize,
+ RBGsize);
+ UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+ while (req > 0 && n_rbg_sched > 0) {
+ ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
+ rbgalloc_mask[rbg] = 0;
+ const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize;
+ ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG;
+ req -= sRBG;
+ n_rbg_sched--;
+ for (rbg++; n_rbg_sched > 0 && !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
+ }
+ }
+
+ return n_rbg_sched;
+}
+default_sched_dl_algo_t proportional_fair_wbcqi_dl = {
+ .name = "proportional_fair_wbcqi_dl",
+ .setup = pf_dl_setup,
+ .unset = pf_dl_unset,
+ .run = pf_wbcqi_dl_run,
+ .data = NULL
+};
+
+void *mt_dl_setup(void) {
+ return NULL;
+}
+void mt_dl_unset(void **data) {
+ *data = NULL;
+}
+int mt_wbcqi_dl_run(module_id_t Mod_id,
+ int CC_id,
+ int frame,
+ int subframe,
+ UE_list_t *UE_list,
+ int max_num_ue,
+ int n_rbg_sched,
+ uint8_t *rbgalloc_mask,
+ void *data) {
+ DevAssert(UE_list->head >= 0);
+ DevAssert(n_rbg_sched > 0);
+ const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
+ const int RBGsize = get_min_rb_unit(Mod_id, CC_id);
+ const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id);
+ UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
+
+ int rbg = 0;
+ for (; !rbgalloc_mask[rbg]; rbg++)
+ ; /* fast-forward to first allowed RBG */
+
+ UE_list_t UE_sched; // UEs that could be scheduled
+ int *uep = &UE_sched.head;
+
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
// check whether there are HARQ retransmissions
const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id];
@@ -133,6 +469,7 @@ int round_robin_dl(module_id_t Mod_id,
if (!rbgalloc_mask[rbg])
continue;
ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
+ rbgalloc_mask[rbg] = 0;
nb_rbg--;
}
LOG_D(MAC,
@@ -150,90 +487,69 @@ int round_robin_dl(module_id_t Mod_id,
return n_rbg_sched;
for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
} else {
- const int dlsch_mcs1 = cqi_to_mcs[UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
- UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = dlsch_mcs1;
- rb_required[UE_id] =
- find_nb_rb_DL(dlsch_mcs1,
- UE_info->UE_template[CC_id][UE_id].dl_buffer_total,
- n_rbg_sched * RBGsize,
- RBGsize);
- if (rb_required[UE_id] > 0)
- num_ue_req++;
- LOG_D(MAC,
- "%d/%d UE_id %d rb_required %d n_rbg_sched %d\n",
- frame,
- subframe,
- UE_id,
- rb_required[UE_id],
- n_rbg_sched);
+ if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total == 0)
+ continue;
+ *uep = UE_id;
+ uep = &UE_sched.next[UE_id];
}
}
+ *uep = -1;
- if (num_ue_req == 0)
- return n_rbg_sched; // no UE has a transmission
+ while (max_num_ue > 0 && n_rbg_sched > 0 && UE_sched.head >= 0) {
+ int *max = &UE_sched.head; /* assume head is max */
+ int *p = &UE_sched.next[*max];
+ while (*p >= 0) {
+ /* if the current one has better CQI, or the same and more data */
+ const uint8_t maxCqi = UE_info->UE_sched_ctrl[*max].dl_cqi[CC_id];
+ const uint32_t maxB = UE_info->UE_template[CC_id][*max].dl_buffer_total;
+ const uint8_t pCqi = UE_info->UE_sched_ctrl[*p].dl_cqi[CC_id];
+ const uint32_t pB = UE_info->UE_template[CC_id][*p].dl_buffer_total;
+ if (pCqi > maxCqi || (pCqi == maxCqi && pB > maxB))
+ max = p;
+ p = &UE_sched.next[*p];
+ }
+ /* remove the max one */
+ const int UE_id = *max;
+ p = &UE_sched.next[*max];
+ *max = UE_sched.next[*max];
+ *p = -1;
- // after allocating retransmissions: build list of UE to allocate.
- // if start_UE does not exist anymore (detach etc), start at first UE
- if (g_start_ue_dl == -1)
- g_start_ue_dl = UE_list->head;
- int UE_id = g_start_ue_dl;
- UE_list_t UE_sched;
- int rb_required_total = 0;
- int num_ue_sched = 0;
- max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched);
- int *cur_UE = &UE_sched.head;
- while (num_ue_sched < max_num_ue) {
- while (rb_required[UE_id] == 0)
- UE_id = next_ue_list_looped(UE_list, UE_id);
const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id];
const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi);
- if (idx < 0) {
- LOG_D(MAC, "cannot allocate CCE for UE %d, skipping\n", UE_id);
- num_ue_req--;
- max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched);
- UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate
+ if (idx < 0)
continue;
- }
UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx;
- *cur_UE = UE_id;
- cur_UE = &UE_sched.next[UE_id];
- rb_required_total += rb_required[UE_id];
- num_ue_sched++;
- UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate
- }
- *cur_UE = -1;
- /* for one UE after the next: allocate resources */
- for (int UE_id = UE_sched.head; UE_id >= 0;
- UE_id = next_ue_list_looped(&UE_sched, UE_id)) {
- if (rb_required[UE_id] <= 0)
- continue;
+ max_num_ue--;
+
+ /* allocate as much as possible */
+ const int mcs = cqi_to_mcs[cqi];
+ UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs;
+ int req = find_nb_rb_DL(mcs,
+ UE_info->UE_template[CC_id][UE_id].dl_buffer_total,
+ n_rbg_sched * RBGsize,
+ RBGsize);
UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id];
- ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
- const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize;
- ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG;
- rb_required[UE_id] -= sRBG;
- rb_required_total -= sRBG;
- if (rb_required_total <= 0)
- break;
- n_rbg_sched--;
- if (n_rbg_sched <= 0)
- break;
- for (rbg++; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
- }
-
- /* if not all UEs could be allocated in this round */
- if (num_ue_req > max_num_ue) {
- /* go to the first one we missed */
- for (int i = 0; i < max_num_ue; ++i)
- g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl);
- } else {
- /* else, just start with the next UE next time */
- g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl);
+ while (req > 0 && n_rbg_sched > 0) {
+ ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
+ rbgalloc_mask[rbg] = 0;
+ const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize;
+ ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG;
+ req -= sRBG;
+ n_rbg_sched--;
+ for (rbg++; n_rbg_sched > 0 && !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
+ }
}
return n_rbg_sched;
}
+default_sched_dl_algo_t maximum_throughput_wbcqi_dl = {
+ .name = "maximum_throughput_wbcqi_dl",
+ .setup = mt_dl_setup,
+ .unset = mt_dl_unset,
+ .run = mt_wbcqi_dl_run,
+ .data = NULL
+};
// This function stores the downlink buffer for all the logical channels
void
@@ -295,6 +611,18 @@ store_dlsch_buffer(module_id_t Mod_id,
#endif
}
+ /* hack: in schedule_ue_spec, 3 bytes are "reserved" (this should be
+ * done better). An RLC AM entity may ask for only 2 bytes for
+ * ACKing and get a TBS of 32 bits and due to these 3 reserved bytes we may
+ * end up with only 1 byte left for RLC, which is not enough. This hack
+ * prevents the problem. To be done better at some point. If the function
+ * schedule_ue_spec is (has been) reworked, this hack can be removed.
+ * Dig for "TBS - ta_len - header_length_total - sdu_length_total - 3"
+ * in schedule_ue_spec.
+ */
+ if (UE_template->dl_buffer_total > 0 && UE_template->dl_buffer_total <= 2)
+ UE_template->dl_buffer_total += 3;
+
if (UE_template->dl_buffer_total > 0)
LOG_D(MAC,
"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n",
@@ -311,19 +639,18 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
int CC_id,
frame_t frameP,
sub_frame_t subframeP) {
- UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
- const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
+ eNB_MAC_INST *mac = RC.mac[Mod_id];
+ UE_info_t *UE_info = &mac->UE_info;
+ const int N_RBG = to_rbg(mac->common_channels[CC_id].mib->message.dl_Bandwidth);
const int RBGsize = get_min_rb_unit(Mod_id, CC_id);
store_dlsch_buffer(Mod_id, CC_id, frameP, subframeP);
UE_list_t UE_to_sched;
- UE_to_sched.head = -1;
for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i)
UE_to_sched.next[i] = -1;
+ int *cur = &UE_to_sched.head;
- int first = 1;
- int last_UE_id = -1;
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
const UE_TEMPLATE *ue_template = &UE_info->UE_template[CC_id][UE_id];
@@ -356,20 +683,15 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
}
/* define UEs to schedule */
- if (first) {
- first = 0;
- UE_to_sched.head = UE_id;
- } else {
- UE_to_sched.next[last_UE_id] = UE_id;
- }
- UE_to_sched.next[UE_id] = -1;
- last_UE_id = UE_id;
+ *cur = UE_id;
+ cur = &UE_to_sched.next[UE_id];
}
+ *cur = -1;
if (UE_to_sched.head < 0)
return;
- uint8_t *vrb_map = RC.mac[Mod_id]->common_channels[CC_id].vrb_map;
+ uint8_t *vrb_map = mac->common_channels[CC_id].vrb_map;
uint8_t rbgalloc_mask[N_RBG_MAX];
int n_rbg_sched = 0;
for (int i = 0; i < N_RBG; i++) {
@@ -381,14 +703,15 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
n_rbg_sched += rbgalloc_mask[i];
}
- round_robin_dl(Mod_id,
- CC_id,
- frameP,
- subframeP,
- &UE_to_sched,
- 4, // max_num_ue
- n_rbg_sched,
- rbgalloc_mask);
+ mac->pre_processor_dl.dl_algo.run(Mod_id,
+ CC_id,
+ frameP,
+ subframeP,
+ &UE_to_sched,
+ 4, // max_num_ue
+ n_rbg_sched,
+ rbgalloc_mask,
+ mac->pre_processor_dl.dl_algo.data);
// the following block is meant for validation of the pre-processor to check
// whether all UE allocations are non-overlapping and is not necessary for
@@ -500,17 +823,28 @@ int pp_find_rb_table_index(int approximate) {
return p + 1;
}
-int g_start_ue_ul = -1;
-int round_robin_ul(module_id_t Mod_id,
- int CC_id,
- int frame,
- int subframe,
- int sched_frame,
- int sched_subframe,
- UE_list_t *UE_list,
- int max_num_ue,
- int num_contig_rb,
- contig_rbs_t *rbs) {
+void *rr_ul_setup(void) {
+ void *data = malloc(sizeof(int));
+ *(int *) data = 0;
+ AssertFatal(data, "could not allocate data in %s()\n", __func__);
+ return data;
+}
+void rr_ul_unset(void **data) {
+ if (*data)
+ free(*data);
+ *data = NULL;
+}
+int rr_ul_run(module_id_t Mod_id,
+ int CC_id,
+ int frame,
+ int subframe,
+ int sched_frame,
+ int sched_subframe,
+ UE_list_t *UE_list,
+ int max_num_ue,
+ int num_contig_rb,
+ contig_rbs_t *rbs,
+ void *data) {
AssertFatal(num_contig_rb <= 2, "cannot handle more than two contiguous RB regions\n");
UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
const int max_rb = num_contig_rb > 1 ? MAX(rbs[0].length, rbs[1].length) : rbs[0].length;
@@ -650,9 +984,10 @@ int round_robin_ul(module_id_t Mod_id,
end = la > lb ? 2 : -1;
}
- if (g_start_ue_ul == -1)
- g_start_ue_ul = UE_list->head;
- int sUE_id = g_start_ue_ul;
+ int *start_ue = data;
+ if (*start_ue == -1)
+ *start_ue = UE_list->head;
+ int sUE_id = *start_ue;
int rb_idx_given[MAX_MOBILES_PER_ENB];
memset(rb_idx_given, 0, sizeof(rb_idx_given));
@@ -730,35 +1065,35 @@ int round_robin_ul(module_id_t Mod_id,
}
}
- /* if not all UEs could be allocated in this round */
- if (num_ue_req > max_num_ue) {
- /* go to the first one we missed */
- for (int i = 0; i < max_num_ue; ++i)
- g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul);
- } else {
- /* else, just start with the next UE next time */
- g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul);
- }
+ /* just start with the next UE next time */
+ *start_ue = next_ue_list_looped(UE_list, *start_ue);
return rbs[0].length + (num_contig_rb > 1 ? rbs[1].length : 0);
}
+default_sched_ul_algo_t round_robin_ul = {
+ .name = "round_robin_ul",
+ .setup = rr_ul_setup,
+ .unset = rr_ul_unset,
+ .run = rr_ul_run,
+ .data = NULL
+};
void ulsch_scheduler_pre_processor(module_id_t Mod_id,
int CC_id,
- int frameP,
+ frame_t frameP,
sub_frame_t subframeP,
- int sched_frameP,
- unsigned char sched_subframeP) {
- UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
- const int N_RB_UL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].ul_Bandwidth);
- COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id];
+ frame_t sched_frameP,
+ sub_frame_t sched_subframeP) {
+ eNB_MAC_INST *mac = RC.mac[Mod_id];
+ UE_info_t *UE_info = &mac->UE_info;
+ const int N_RB_UL = to_prb(mac->common_channels[CC_id].ul_Bandwidth);
+ COMMON_channels_t *cc = &mac->common_channels[CC_id];
UE_list_t UE_to_sched;
- UE_to_sched.head = -1;
for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i)
UE_to_sched.next[i] = -1;
+ int *cur = &UE_to_sched.head;
- int last_UE_id = -1;
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id];
UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
@@ -781,13 +1116,10 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id,
continue;
/* define UEs to schedule */
- if (UE_to_sched.head < 0)
- UE_to_sched.head = UE_id;
- else
- UE_to_sched.next[last_UE_id] = UE_id;
- UE_to_sched.next[UE_id] = -1;
- last_UE_id = UE_id;
+ *cur = UE_id;
+ cur = &UE_to_sched.next[UE_id];
}
+ *cur = -1;
if (UE_to_sched.head < 0)
return;
@@ -808,16 +1140,17 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id,
}
}
- round_robin_ul(Mod_id,
- CC_id,
- frameP,
- subframeP,
- sched_frameP,
- sched_subframeP,
- &UE_to_sched,
- 4, // max_num_ue
- n_contig,
- rbs);
+ mac->pre_processor_ul.ul_algo.run(Mod_id,
+ CC_id,
+ frameP,
+ subframeP,
+ sched_frameP,
+ sched_subframeP,
+ &UE_to_sched,
+ 4, // max_num_ue
+ n_contig,
+ rbs,
+ mac->pre_processor_ul.ul_algo.data);
// the following block is meant for validation of the pre-processor to check
// whether all UE allocations are non-overlapping and is not necessary for
@@ -836,7 +1169,7 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id,
continue;
print = 1;
- uint8_t harq_pid = subframe2harqpid(&RC.mac[Mod_id]->common_channels[CC_id],
+ uint8_t harq_pid = subframe2harqpid(&mac->common_channels[CC_id],
sched_frameP, sched_subframeP);
LOG_D(MAC, "%4d.%d UE%d %d RBs (index %d) at start %d, pre MCS %d %s\n",
frameP,
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index 5801fabcfb..d8583167dd 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
@@ -24,8 +24,8 @@
* \author R. Knopp, K.H. HSU, G. Casati
* \date 2019
* \version 0.1
- * \company Eurecom / NTUST / Fraunhofer IIS
- * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr, guido.casati@iis.fraunhofer.de
+ * \company Eurecom / NTUST / Fraunhofer IIS
+ * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note
* \warning
*/
@@ -41,6 +41,10 @@
#define NR_BCCH_BCH 5 // MIB
+#define CCCH_PAYLOAD_SIZE_MAX 128
+
+#define RAR_PAYLOAD_SIZE_MAX 128
+
// For both DL/UL-SCH
// Except:
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
@@ -67,36 +71,234 @@
// R: Reserved bit, set to zero.
typedef struct {
- uint8_t LCID:6; // octet 1 [5:0]
- uint8_t F:1; // octet 1 [6]
- uint8_t R:1; // octet 1 [7]
- uint8_t L:8; // octet 2 [7:0]
+ uint8_t LCID: 6; // octet 1 [5:0]
+ uint8_t F: 1; // octet 1 [6]
+ uint8_t R: 1; // octet 1 [7]
+ uint8_t L: 8; // octet 2 [7:0]
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_SHORT;
typedef struct {
- uint8_t LCID:6; // octet 1 [5:0]
- uint8_t F:1; // octet 1 [6]
- uint8_t R:1; // octet 1 [7]
- uint8_t L1:8; // octet 2 [7:0]
- uint8_t L2:8; // octet 3 [7:0]
+ uint8_t LCID: 6; // octet 1 [5:0]
+ uint8_t F: 1; // octet 1 [6]
+ uint8_t R: 1; // octet 1 [7]
+ uint8_t L1: 8; // octet 2 [7:0]
+ uint8_t L2: 8; // octet 3 [7:0]
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_LONG;
typedef struct {
- uint8_t LCID:6; // octet 1 [5:0]
- uint8_t R:2; // octet 1 [7:6]
+ uint8_t LCID: 6; // octet 1 [5:0]
+ uint8_t R: 2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
+// BSR MAC CEs
+// TS 38.321 ch. 6.1.3.1
+// Short BSR for a specific logical channel group ID
+typedef struct {
+ uint8_t Buffer_size: 5; // octet 1 LSB
+ uint8_t LcgID: 3; // octet 1 MSB
+} __attribute__ ((__packed__)) NR_BSR_SHORT;
+
+typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED;
+
+// Long BSR for all logical channel group ID
+typedef struct {
+ uint8_t Buffer_size7: 8;
+ uint8_t Buffer_size6: 8;
+ uint8_t Buffer_size5: 8;
+ uint8_t Buffer_size4: 8;
+ uint8_t Buffer_size3: 8;
+ uint8_t Buffer_size2: 8;
+ uint8_t Buffer_size1: 8;
+ uint8_t Buffer_size0: 8;
+ uint8_t LcgID0: 1;
+ uint8_t LcgID1: 1;
+ uint8_t LcgID2: 1;
+ uint8_t LcgID3: 1;
+ uint8_t LcgID4: 1;
+ uint8_t LcgID5: 1;
+ uint8_t LcgID6: 1;
+ uint8_t LcgID7: 1;
+} __attribute__ ((__packed__)) NR_BSR_LONG;
+
+typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED;
+
// 38.321 ch. 6.1.3.4
typedef struct {
- uint8_t TA_COMMAND:6; // octet 1 [5:0]
- uint8_t TAGID:2; // octet 1 [7:6]
+ uint8_t TA_COMMAND: 6; // octet 1 [5:0]
+ uint8_t TAGID: 2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_CE_TA;
+// single Entry PHR MAC CE
+// TS 38.321 ch. 6.1.3.8
+typedef struct {
+ uint8_t PH: 6;
+ uint8_t R1: 2;
+ uint8_t PCMAX: 6;
+ uint8_t R2: 6;
+} __attribute__ ((__packed__)) NR_SINGLE_ENTRY_PHR_MAC_CE;
+
+
+// SP ZP CSI-RS Resource Set Activation/Deactivation MAC CE
+// 38.321 ch. 6.1.3.19
+typedef struct {
+ uint8_t BWPID: 2; // octet 1 [1:0]
+ uint8_t CELLID: 5; // octet 1 [6:2]
+ uint8_t A_D: 1; // octet 1 [7]
+ uint8_t CSIRS_RSC_ID: 4; // octet 2 [3:0]
+ uint8_t R: 4; // octet 2 [7:4]
+} __attribute__ ((__packed__)) NR_MAC_CE_SP_ZP_CSI_RS_RES_SET;
+
+//TS 38.321 Sec 6.1.3.15, TCI State indicaton for UE-Specific PDCCH MAC CE
+typedef struct {
+ uint8_t CoresetId1: 3; //Octect 1 [2:0]
+ uint8_t ServingCellId: 5; //Octect 1 [7:3]
+ uint8_t TciStateId: 7; //Octect 2 [6:0]
+ uint8_t CoresetId2: 1; //Octect 2 [7]
+} __attribute__ ((__packed__)) NR_TCI_PDCCH;
+
+//TS 38.321 Sec 6.1.3.14, TCI State activation/deactivation for UE Specific PDSCH MAC CE
+typedef struct {
+ uint8_t BWP_Id: 2; //Octect 1 [1:0]
+ uint8_t ServingCellId: 5; //Octect 1 [6:2]
+ uint8_t R: 1; //Octect 1 [7]
+ uint8_t T[]; //Octects 2 to MAX TCI States/8
+} __attribute__ ((__packed__)) NR_TCI_PDSCH_APERIODIC_CSI;
+
+//TS 6.1.3.16, SP CSI reporting on PUCCH Activation/Deactivation MAC CE
+typedef struct {
+ uint8_t BWP_Id: 2; //Octect 1 [1:0]
+ uint8_t ServingCellId: 5; //Octect 1 [6:2]
+ uint8_t R1: 1; //Octect 1 [7]
+ uint8_t S0: 1; //Octect 2 [0]
+ uint8_t S1: 1; //Octect 2 [1]
+ uint8_t S2: 1; //Octect 2 [2]
+ uint8_t S3: 1; //Octect 2 [3]
+ uint8_t R2: 4; //Octect 2 [7:4]
+} __attribute__ ((__packed__)) NR_PUCCH_CSI_REPORTING;
+
+
+//TS 38.321 sec 6.1.3.12
+//SP CSI-RS / CSI-IM Resource Set Activation/Deactivation MAC CE
+typedef struct {
+ uint8_t BWP_ID: 2;
+ uint8_t SCID: 5;
+ uint8_t A_D: 1;
+ uint8_t SP_CSI_RSID: 6;
+ uint8_t IM: 1;
+ uint8_t R1: 1;
+ uint8_t SP_CSI_IMID: 6;
+ uint8_t R2: 2;
+ struct TCI_S {
+ uint8_t TCI_STATE_ID: 6;
+ uint8_t R: 2;
+ } __attribute__ ((__packed__)) TCI_STATE;
+} __attribute__ ((__packed__)) CSI_RS_CSI_IM_ACT_DEACT_MAC_CE;
+
+
+//* RAR MAC subheader // TS 38.321 ch. 6.1.5, 6.2.2 *//
+// - E: The Extension field is a flag indicating if the MAC subPDU including this MAC subheader is the last MAC subPDU or not in the MAC PDU
+// - T: The Type field is a flag indicating whether the MAC subheader contains a Random Access Preamble ID or a Backoff Indicator (0, BI) (1, RAPID)
+// - R: Reserved bit, set to "0"
+// - BI: The Backoff Indicator field identifies the overload condition in the cell.
+// - RAPID: The Random Access Preamble IDentifier field identifies the transmitted Random Access Preamble
+
+/*!\brief RAR MAC subheader with RAPID */
+typedef struct {
+ uint8_t RAPID: 6;
+ uint8_t T: 1;
+ uint8_t E: 1;
+} __attribute__ ((__packed__)) NR_RA_HEADER_RAPID;
+
+/*!\brief RAR MAC subheader with Backoff Indicator */
+typedef struct {
+ uint8_t BI: 4;
+ uint8_t R: 2;
+ uint8_t T: 1;
+ uint8_t E: 1;
+} __attribute__ ((__packed__)) NR_RA_HEADER_BI;
+
+// TS 38.321 ch. 6.2.3
+typedef struct {
+ uint8_t TA1: 7; // octet 1 [6:0]
+ uint8_t R: 1; // octet 1 [7]
+ uint8_t UL_GRANT_1: 3; // octet 2 [2:0]
+ uint8_t TA2: 5; // octet 2 [7:3]
+ uint8_t UL_GRANT_2: 8; // octet 3 [7:0]
+ uint8_t UL_GRANT_3: 8; // octet 4 [7:0]
+ uint8_t UL_GRANT_4: 8; // octet 5 [7:0]
+ uint8_t TCRNTI_1: 8; // octet 6 [7:0]
+ uint8_t TCRNTI_2: 8; // octet 7 [7:0]
+} __attribute__ ((__packed__)) NR_MAC_RAR;
+
+// DCI pdu structures. Used by both gNB and UE.
+typedef struct {
+ uint16_t val;
+ uint8_t nbits;
+} dci_field_t;
+
+typedef struct {
+
+ uint8_t format_indicator; //1 bit
+ uint8_t ra_preamble_index; //6 bits
+ uint8_t ss_pbch_index; //6 bits
+ uint8_t prach_mask_index; //4 bits
+ uint8_t mcs; //5 bits
+ uint8_t ndi; //1 bit
+ uint8_t rv; //2 bits
+ uint8_t harq_pid; //4 bits
+ uint8_t tpc; //2 bits
+ uint8_t short_messages_indicator; //2 bits
+ uint8_t short_messages; //8 bits
+ uint8_t tb_scaling; //2 bits
+ uint8_t pucch_resource_indicator; //3 bits
+ uint8_t system_info_indicator; //1 bit
+ uint8_t ulsch_indicator;
+ uint8_t slot_format_indicator_count;
+ uint8_t *slot_format_indicators;
+
+ uint8_t pre_emption_indication_count;
+ uint16_t *pre_emption_indications; //14 bit each
+
+ uint8_t block_number_count;
+ uint8_t *block_numbers;
+ uint8_t padding;
+
+ dci_field_t mcs2; //variable
+ dci_field_t ndi2; //variable
+ dci_field_t rv2; //variable
+ dci_field_t frequency_domain_assignment; //variable
+ dci_field_t time_domain_assignment; //variable
+ dci_field_t frequency_hopping_flag; //variable
+ dci_field_t vrb_to_prb_mapping; //variable
+ dci_field_t dai[2]; //variable
+ dci_field_t pdsch_to_harq_feedback_timing_indicator; //variable
+ dci_field_t carrier_indicator; //variable
+ dci_field_t bwp_indicator; //variable
+ dci_field_t prb_bundling_size_indicator; //variable
+ dci_field_t rate_matching_indicator; //variable
+ dci_field_t zp_csi_rs_trigger; //variable
+ dci_field_t transmission_configuration_indication; //variable
+ dci_field_t srs_request; //variable
+ dci_field_t cbgti; //variable
+ dci_field_t cbgfi; //variable
+ dci_field_t srs_resource_indicator; //variable
+ dci_field_t precoding_information; //variable
+ dci_field_t csi_request; //variable
+ dci_field_t ptrs_dmrs_association; //variable
+ dci_field_t beta_offset_indicator; //variable
+ dci_field_t cloded_loop_indicator; //variable
+ dci_field_t ul_sul_indicator; //variable
+ dci_field_t antenna_ports; //variable
+ dci_field_t dmrs_sequence_initialization;
+ dci_field_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
+
+} dci_pdu_rel15_t;
+
// 38.321 ch6.2.1, 38.331
#define DL_SCH_LCID_CCCH 0x00
#define DL_SCH_LCID_DCCH 0x01
#define DL_SCH_LCID_DCCH1 0x02
-#define DL_SCH_LCID_DTCH 0x03
+#define DL_SCH_LCID_DTCH 0x04
#define DL_SCH_LCID_RECOMMENDED_BITRATE 0x2F
#define DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT 0x30
#define DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT 0x31
@@ -105,7 +307,7 @@ typedef struct {
#define DL_SCH_LCID_TCI_STATE_IND_UE_SPEC_PDCCH 0x34
#define DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH 0x35
#define DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL 0x36
-#define DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT 0X37
+#define DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT 0X37
#define DL_SCH_LCID_DUPLICATION_ACT 0X38
#define DL_SCH_LCID_SCell_ACT_4_OCT 0X39
#define DL_SCH_LCID_SCell_ACT_1_OCT 0X3A
@@ -118,8 +320,8 @@ typedef struct {
#define UL_SCH_LCID_CCCH 0x00
#define UL_SCH_LCID_SRB1 0x01
#define UL_SCH_LCID_SRB2 0x02
-#define UL_SCH_LCID_DTCH 0x03
-#define UL_SCH_LCID_SRB3 0x04
+#define UL_SCH_LCID_SRB3 0x03
+#define UL_SCH_LCID_DTCH 0x04
#define UL_SCH_LCID_CCCH_MSG3 0x21
#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35
#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36
@@ -133,9 +335,9 @@ typedef struct {
#define UL_SCH_LCID_L_BSR 0x3E
#define UL_SCH_LCID_PADDING 0x3F
-#define NR_MAX_NUM_LCID 32
-#define NR_MAX_NUM_LCGID 8
-#define MAX_RLC_SDU_SUBHEADER_SIZE 3
+#define NR_MAX_NUM_LCID 32
+#define NR_MAX_NUM_LCGID 8
+#define MAX_RLC_SDU_SUBHEADER_SIZE 3
#endif /*__LAYER2_MAC_H__ */
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index cfde40daad..f40d822b6b 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -31,6 +31,1169 @@
*/
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include
+
+const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
+
+// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
+uint16_t NCS_unrestricted_delta_f_RA_125[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419};
+uint16_t NCS_restricted_TypeA_delta_f_RA_125[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case set Type A
+uint16_t NCS_restricted_TypeB_delta_f_RA_125[13] = {15,18,22,26,32,38,46,55,68,82,100,118,137}; // high-speed case set Type B
+
+// Table 6.3.3.1-6 (38.211) NCS for preamble formats with delta_f_RA = 5 KHz
+uint16_t NCS_unrestricted_delta_f_RA_5[16] = {0,13,26,33,38,41,49,55,64,76,93,119,139,209,279,419};
+uint16_t NCS_restricted_TypeA_delta_f_RA_5[16] = {36,57,72,81,89,94,103,112,121,132,137,152,173,195,216,237}; // high-speed case set Type A
+uint16_t NCS_restricted_TypeB_delta_f_RA_5[14] = {36,57,60,63,65,68,71,77,81,85,97,109,122,137}; // high-speed case set Type B
+
+// Table 6.3.3.1-7 (38.211) NCS for preamble formats with delta_f_RA = 15 * 2mu KHz where mu = {0,1,2,3}
+uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69};
+
+const char *prachfmt[]={"A1","A2","A3","B1","B2","B3","B4","C0","C2"};
+const char *prachfmt03[]={"0","1","2","3"};
+
+uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) {
+
+ LOG_D(MAC,"get_NCS: indx %d,format0 %d, restriced_set_config %d\n",
+ index,format0,restricted_set_config);
+
+ if (format0 < 3) {
+ switch(restricted_set_config){
+ case 0:
+ return(NCS_unrestricted_delta_f_RA_125[index]);
+ case 1:
+ return(NCS_restricted_TypeA_delta_f_RA_125[index]);
+ case 2:
+ return(NCS_restricted_TypeB_delta_f_RA_125[index]);
+ default:
+ AssertFatal(1==0,"Invalid restricted set config value %d",restricted_set_config);
+ }
+ }
+ else {
+ if (format0 == 3) {
+ switch(restricted_set_config){
+ case 0:
+ return(NCS_unrestricted_delta_f_RA_5[index]);
+ case 1:
+ return(NCS_restricted_TypeA_delta_f_RA_5[index]);
+ case 2:
+ return(NCS_restricted_TypeB_delta_f_RA_5[index]);
+ default:
+ AssertFatal(1==0,"Invalid restricted set config value %d",restricted_set_config);
+ }
+ }
+ else
+ return(NCS_unrestricted_delta_f_RA_15[index]);
+ }
+}
+
+
+// Table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
+// the column 5, (SFN_nbr is a bitmap where we set bit to '1' in the position of the subframe where the RACH can be sent.
+// E.g. in row 4, and column 5 we have set value 512 ('1000000000') which means RACH can be sent at subframe 9.
+// E.g. in row 20 and column 5 we have set value 66 ('0001000010') which means RACH can be sent at subframe 1 or 6
+int64_t table_6_3_3_2_2_prachConfig_Index [256][9] = {
+//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
+{0, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{0, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{0, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{0, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{0, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{0, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{0, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{0, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{0, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{0, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{0, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{0, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
+{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
+{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
+{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
+{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
+{0, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
+{0, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
+{0, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9
+{0, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8
+{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9
+{0, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{1, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{1, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{1, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{1, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{1, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{1, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{1, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{1, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{1, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{1, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{1, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{1, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{1, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{1, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
+{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
+{1, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
+{1, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
+{1, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
+{1, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
+{1, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
+{1, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3,6,9
+{2, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{2, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{2, -1, 4, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{2, -1, 2, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{2, -1, 2, 0, 32, 0, -1, -1, 0}, // (subframe number) 5
+{2, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{2, -1, 1, 0, 32, 0, -1, -1, 0}, // (subframe number) 5
+{3, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{3, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{3, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{3, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{3, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{3, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{3, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{3, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{3, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{3, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{3, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{3, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
+{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
+{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
+{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
+{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
+{3, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
+{3, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
+{3, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9
+{3, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8
+{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9
+{3, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xa1, -1, 16, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 16, 1, 16, 0, 2, 6, 2}, // (subframe number) 4
+{0xa1, -1, 8, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 8, 1, 16, 0, 2, 6, 2}, // (subframe number) 4
+{0xa1, -1, 4, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 4, 1, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 4, 0, 16, 0, 2, 6, 2}, // (subframe number) 4
+{0xa1, -1, 2, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 2, 0, 2, 0, 2, 6, 2}, // (subframe number) 1
+{0xa1, -1, 2, 0, 16, 0, 2, 6, 2}, // (subframe number) 4
+{0xa1, -1, 2, 0, 128, 0, 2, 6, 2}, // (subframe number) 7
+{0xa1, -1, 1, 0, 16, 0, 1, 6, 2}, // (subframe number) 4
+{0xa1, -1, 1, 0, 66, 0, 1, 6, 2}, // (subframe number) 1,6
+{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 1, 0, 2, 0, 2, 6, 2}, // (subframe number) 1
+{0xa1, -1, 1, 0, 128, 0, 2, 6, 2}, // (subframe number) 7
+{0xa1, -1, 1, 0, 132, 0, 2, 6, 2}, // (subframe number) 2,7
+{0xa1, -1, 1, 0, 146, 0, 2, 6, 2}, // (subframe number) 1,4,7
+{0xa1, -1, 1, 0, 341, 0, 2, 6, 2}, // (subframe number) 0,2,4,6,8
+{0xa1, -1, 1, 0, 1023, 0, 2, 6, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xa1, -1, 1, 0, 682, 0, 2, 6, 2}, // (subframe number) 1,3,5,7,9
+{0xa1, 0xb1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xa1, 0xb1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xa1, 0xb1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
+{0xa1, 0xb1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
+{0xa1, 0xb1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xa1, 0xb1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
+{0xa1, 0xb1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
+{0xa1, 0xb1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
+{0xa1, 0xb1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
+{0xa2, -1, 16, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
+{0xa2, -1, 16, 1, 16, 0, 2, 3, 4}, // (subframe number) 4
+{0xa2, -1, 8, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
+{0xa2, -1, 8, 1, 16, 0, 2, 3, 4}, // (subframe number) 4
+{0xa2, -1, 4, 0, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
+{0xa2, -1, 4, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
+{0xa2, -1, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
+{0xa2, -1, 2, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
+{0xa2, -1, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
+{0xa2, -1, 2, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
+{0xa2, -1, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4
+{0xa2, -1, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6
+{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9
+{0xa2, -1, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
+{0xa2, -1, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
+{0xa2, -1, 1, 0, 132, 0, 2, 3, 4}, // (subframe number) 2,7
+{0xa2, -1, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7
+{0xa2, -1, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8
+{0xa2, -1, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xa2, -1, 1, 0, 682, 0, 2, 3, 4}, // (subframe number) 1,3,5,7,9
+{0xa2, 0xb2, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
+{0xa2, 0xb2, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
+{0xa2, 0xb2, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4
+{0xa2, 0xb2, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6
+{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9
+{0xa2, 0xb2, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
+{0xa2, 0xb2, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
+{0xa2, 0xb2, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7
+{0xa2, 0xb2, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8
+{0xa2, 0xb2, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xa3, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xa3, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xa3, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xa3, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xa3, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xa3, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xa3, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
+{0xa3, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
+{0xa3, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xa3, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
+{0xa3, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
+{0xa3, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
+{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xa3, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
+{0xa3, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
+{0xa3, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7
+{0xa3, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
+{0xa3, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
+{0xa3, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xa3, -1, 1, 0, 682, 0, 2, 2, 6}, // (subframe number) 1,3,5,7,9
+{0xa3, 0xb3, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
+{0xa3, 0xb3, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xa3, 0xb3, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
+{0xa3, 0xb3, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
+{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xa3, 0xb3, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
+{0xa3, 0xb3, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
+{0xa3, 0xb3, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
+{0xa3, 0xb3, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
+{0xa3, 0xb3, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xb1, -1, 16, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 16, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xb1, -1, 8, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xb1, -1, 4, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xb1, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
+{0xb1, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xb1, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
+{0xb1, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
+{0xb1, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
+{0xb1, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
+{0xb1, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
+{0xb1, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7
+{0xb1, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
+{0xb1, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
+{0xb1, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xb1, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9
+{0xb4, -1, 16, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 16, 1, 16, 0, 2, 1, 12}, // (subframe number) 4
+{0xb4, -1, 8, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 8, 1, 16, 0, 2, 1, 12}, // (subframe number) 4
+{0xb4, -1, 4, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 4, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
+{0xb4, -1, 4, 1, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 2, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 2, 0, 2, 0, 2, 1, 12}, // (subframe number) 1
+{0xb4, -1, 2, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
+{0xb4, -1, 2, 0, 128, 0, 2, 1, 12}, // (subframe number) 7
+{0xb4, -1, 1, 0, 2, 0, 2, 1, 12}, // (subframe number) 1
+{0xb4, -1, 1, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
+{0xb4, -1, 1, 0, 128, 0, 2, 1, 12}, // (subframe number) 7
+{0xb4, -1, 1, 0, 66, 0, 2, 1, 12}, // (subframe number) 1,6
+{0xb4, -1, 1, 0, 132, 0, 2, 1, 12}, // (subframe number) 2,7
+{0xb4, -1, 1, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 1, 0, 146, 0, 2, 1, 12}, // (subframe number) 1,4,7
+{0xb4, -1, 1, 0, 341, 0, 2, 1, 12}, // (subframe number) 0,2,4,6,8
+{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xb4, -1, 1, 0, 682, 0, 2, 1, 12}, // (subframe number) 1,3,5,7,9
+{0xc0, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xc0, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xc0, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xc0, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xc0, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
+{0xc0, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xc0, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
+{0xc0, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
+{0xc0, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
+{0xc0, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xc0, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
+{0xc0, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
+{0xc0, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7
+{0xc0, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
+{0xc0, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
+{0xc0, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xc0, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9
+{0xc2, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xc2, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xc2, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xc2, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xc2, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xc2, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xc2, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
+{0xc2, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
+{0xc2, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xc2, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
+{0xc2, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
+{0xc2, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
+{0xc2, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xc2, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
+{0xc2, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
+{0xc2, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7
+{0xc2, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
+{0xc2, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
+{0xc2, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xc2, -1, 1, 0, 682, 0, 2, 2, 6} // (subframe number) 1,3,5,7,9
+};
+// Table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum
+int64_t table_6_3_3_2_3_prachConfig_Index [256][9] = {
+//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
+{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
+{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4)
+{0, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8)
+{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
+{0, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6)
+{0, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5)
+{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
+{0, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3)
+{0, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2)
+{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6)
+{0, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6)
+{0, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9)
+{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8)
+{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7)
+{0, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9)
+{0, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9)
+{0, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9)
+{0, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9)
+{0, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9)
+{0, -1, 1, 0, 960, 0, -1, -1, 0}, // (subrame number 6,7,8,9)
+{0, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9)
+{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9)
+{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
+{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
+{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
+{1, -1, 2, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
+{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
+{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
+{2, -1, 16, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
+{2, -1, 8, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
+{2, -1, 4, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
+{2, -1, 2, 0, 64, 7, -1, -1, 0}, // (subrame number 6)
+{2, -1, 2, 1, 64, 7, -1, -1, 0}, // (subrame number 6)
+{2, -1, 1, 0, 64, 7, -1, -1, 0}, // (subrame number 6)
+{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
+{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4)
+{3, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8)
+{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
+{3, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6)
+{3, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5)
+{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
+{3, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3)
+{3, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2)
+{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6)
+{3, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6)
+{3, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9)
+{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8)
+{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7)
+{3, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9)
+{3, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9)
+{3, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9)
+{3, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9)
+{3, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9)
+{3, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9)
+{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9)
+{0xa1, -1, 16, 1, 512, 0, 2, 6, 2}, // (subrame number 9)
+{0xa1, -1, 8, 1, 512, 0, 2, 6, 2}, // (subrame number 9)
+{0xa1, -1, 4, 1, 512, 0, 1, 6, 2}, // (subrame number 9)
+{0xa1, -1, 2, 1, 512, 0, 1, 6, 2}, // (subrame number 9)
+{0xa1, -1, 2, 1, 528, 7, 1, 3, 2}, // (subrame number 4,9)
+{0xa1, -1, 2, 1, 640, 7, 1, 3, 2}, // (subrame number 7,9)
+{0xa1, -1, 2, 1, 640, 0, 1, 6, 2}, // (subrame number 7,9)
+{0xa1, -1, 2, 1, 768, 0, 2, 6, 2}, // (subrame number 8,9)
+{0xa1, -1, 2, 1, 528, 0, 2, 6, 2}, // (subrame number 4,9)
+{0xa1, -1, 2, 1, 924, 0, 1, 6, 2}, // (subrame number 2,3,4,7,8,9)
+{0xa1, -1, 1, 0, 512, 0, 2, 6, 2}, // (subrame number 9)
+{0xa1, -1, 1, 0, 512, 7, 1, 3, 2}, // (subrame number 9)
+{0xa1, -1, 1, 0, 512, 0, 1, 6, 2}, // (subrame number 9)
+{0xa1, -1, 1, 0, 768, 0, 2, 6, 2}, // (subrame number 8,9)
+{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subrame number 4,9)
+{0xa1, -1, 1, 0, 640, 7, 1, 3, 2}, // (subrame number 7,9)
+{0xa1, -1, 1, 0, 792, 0, 1, 6, 2}, // (subrame number 3,4,8,9)
+{0xa1, -1, 1, 0, 792, 0, 2, 6, 2}, // (subrame number 3,4,8,9)
+{0xa1, -1, 1, 0, 682, 0, 1, 6, 2}, // (subrame number 1,3,5,7,9)
+{0xa1, -1, 1, 0, 1023, 7, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xa2, -1, 16, 1, 512, 0, 2, 3, 4}, // (subrame number 9)
+{0xa2, -1, 8, 1, 512, 0, 2, 3, 4}, // (subrame number 9)
+{0xa2, -1, 4, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
+{0xa2, -1, 2, 1, 640, 0, 1, 3, 4}, // (subrame number 7,9)
+{0xa2, -1, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9)
+{0xa2, -1, 2, 1, 640, 9, 1, 1, 4}, // (subrame number 7,9)
+{0xa2, -1, 2, 1, 528, 9, 1, 1, 4}, // (subrame number 4,9)
+{0xa2, -1, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9)
+{0xa2, -1, 16, 1, 924, 0, 1, 3, 4}, // (subrame number 2,3,4,7,8,9)
+{0xa2, -1, 1, 0, 4, 0, 1, 3, 4}, // (subrame number 2)
+{0xa2, -1, 1, 0, 128, 0, 1, 3, 4}, // (subrame number 7)
+{0xa2, -1, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
+{0xa2, -1, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9)
+{0xa2, -1, 1, 0, 512, 9, 1, 1, 4}, // (subrame number 9)
+{0xa2, -1, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9)
+{0xa2, -1, 1, 0, 132, 0, 1, 3, 4}, // (subrame number 2,7)
+{0xa2, -1, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9)
+{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9)
+{0xa2, -1, 1, 0, 640, 9, 1, 1, 4}, // (subrame number 7,9)
+{0xa2, -1, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9)
+{0xa2, -1, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9)
+{0xa2, -1, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9)
+{0xa2, -1, 1, 0, 1023, 9, 1, 1, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xa3, -1, 16, 1, 512, 0, 2, 2, 6}, // (subrame number 9)
+{0xa3, -1, 8, 1, 512, 0, 2, 2, 6}, // (subrame number 9)
+{0xa3, -1, 4, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
+{0xa3, -1, 2, 1, 528, 7, 1, 1, 6}, // (subrame number 4,9)
+{0xa3, -1, 2, 1, 640, 7, 1, 1, 6}, // (subrame number 7,9)
+{0xa3, -1, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9)
+{0xa3, -1, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9)
+{0xa3, -1, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9)
+{0xa3, -1, 2, 1, 924, 0, 1, 2, 6}, // (subrame number 2,3,4,7,8,9)
+{0xa3, -1, 1, 0, 4, 0, 1, 2, 6}, // (subrame number 2)
+{0xa3, -1, 1, 0, 128, 0, 1, 2, 6}, // (subrame number 7)
+{0xa3, -1, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
+{0xa3, -1, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9)
+{0xa3, -1, 1, 0, 512, 7, 1, 1, 6}, // (subrame number 9)
+{0xa3, -1, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9)
+{0xa3, -1, 1, 0, 132, 0, 1, 2, 6}, // (subrame number 2,7)
+{0xa3, -1, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9)
+{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9)
+{0xa3, -1, 1, 0, 640, 7, 1, 1, 6}, // (subrame number 7,9)
+{0xa3, -1, 1, 0, 792, 0, 1, 2, 6}, // (subrame number 3,4,8,9)
+{0xa3, -1, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9)
+{0xa3, -1, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9)
+{0xa3, -1, 1, 0, 1023, 7, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xb1, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xb1, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xb1, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
+{0xb1, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
+{0xb1, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
+{0xb1, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
+{0xb1, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
+{0xb1, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xb1, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
+{0xb1, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
+{0xb1, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
+{0xb1, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
+{0xb4, -1, 16, 1, 512, 0, 2, 1, 12}, // (subrame number 9)
+{0xb4, -1, 8, 1, 512, 0, 2, 1, 12}, // (subrame number 9)
+{0xb4, -1, 4, 1, 512, 2, 1, 1, 12}, // (subrame number 9)
+{0xb4, -1, 2, 1, 512, 0, 1, 1, 12}, // (subrame number 9)
+{0xb4, -1, 2, 1, 512, 2, 1, 1, 12}, // (subrame number 9)
+{0xb4, -1, 2, 1, 640, 2, 1, 1, 12}, // (subrame number 7,9)
+{0xb4, -1, 2, 1, 528, 2, 1, 1, 12}, // (subrame number 4,9)
+{0xb4, -1, 2, 1, 528, 0, 2, 1, 12}, // (subrame number 4,9)
+{0xb4, -1, 2, 1, 768, 0, 2, 1, 12}, // (subrame number 8,9)
+{0xb4, -1, 2, 1, 924, 0, 1, 1, 12}, // (subrame number 2,3,4,7,8,9)
+{0xb4, -1, 1, 0, 2, 0, 1, 1, 12}, // (subrame number 1)
+{0xb4, -1, 1, 0, 4, 0, 1, 1, 12}, // (subrame number 2)
+{0xb4, -1, 1, 0, 16, 0, 1, 1, 12}, // (subrame number 4)
+{0xb4, -1, 1, 0, 128, 0, 1, 1, 12}, // (subrame number 7)
+{0xb4, -1, 1, 0, 512, 0, 1, 1, 12}, // (subrame number 9)
+{0xb4, -1, 1, 0, 512, 2, 1, 1, 12}, // (subrame number 9)
+{0xb4, -1, 1, 0, 512, 0, 2, 1, 12}, // (subrame number 9)
+{0xb4, -1, 1, 0, 528, 2, 1, 1, 12}, // (subrame number 4,9)
+{0xb4, -1, 1, 0, 640, 2, 1, 1, 12}, // (subrame number 7,9)
+{0xb4, -1, 1, 0, 768, 0, 2, 1, 12}, // (subrame number 8,9)
+{0xb4, -1, 1, 0, 792, 2, 1, 1, 12}, // (subrame number 3,4,8,9)
+{0xb4, -1, 1, 0, 682, 2, 1, 1, 12}, // (subrame number 1,3,5,7,9)
+{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xb4, -1, 1, 0, 1023, 2, 1, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xc0, -1, 16, 1, 512, 2, 2, 6, 2}, // (subrame number 9)
+{0xc0, -1, 8, 1, 512, 2, 2, 6, 2}, // (subrame number 9)
+{0xc0, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xc0, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xc0, -1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9)
+{0xc0, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
+{0xc0, -1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9)
+{0xc0, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
+{0xc0, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
+{0xc0, -1, 2, 1, 924, 2, 1, 6, 2}, // (subrame number 2,3,4,7,8,9)
+{0xc0, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
+{0xc0, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
+{0xc0, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xc0, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
+{0xc0, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
+{0xc0, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
+{0xc0, -1, 1, 0, 792, 2, 1, 6, 2}, // (subrame number 3,4,8,9)
+{0xc0, -1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9)
+{0xc0, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
+{0xc0, -1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xc2, -1, 16, 1, 512, 2, 2, 2, 6}, // (subrame number 9)
+{0xc2, -1, 8, 1, 512, 2, 2, 2, 6}, // (subrame number 9)
+{0xc2, -1, 4, 1, 512, 2, 1, 2, 6}, // (subrame number 9)
+{0xc2, -1, 2, 1, 512, 2, 1, 2, 6}, // (subrame number 9)
+{0xc2, -1, 2, 1, 768, 2, 2, 2, 6}, // (subrame number 8,9)
+{0xc2, -1, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9)
+{0xc2, -1, 2, 1, 640, 8, 1, 1, 6}, // (subrame number 7,9)
+{0xc2, -1, 2, 1, 528, 8, 1, 1, 6}, // (subrame number 4,9)
+{0xc2, -1, 2, 1, 528, 2, 2, 2, 6}, // (subrame number 4,9)
+{0xc2, -1, 2, 1, 924, 2, 1, 2, 6}, // (subrame number 2,3,4,7,8,9)
+{0xc2, -1, 8, 1, 512, 8, 2, 1, 6}, // (subrame number 9)
+{0xc2, -1, 4, 1, 512, 8, 1, 1, 6}, // (subrame number 9)
+{0xc2, -1, 1, 0, 512, 2, 2, 2, 6}, // (subrame number 9)
+{0xc2, -1, 1, 0, 512, 8, 1, 1, 6}, // (subrame number 9)
+{0xc2, -1, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9)
+{0xc2, -1, 1, 0, 768, 2, 2, 2, 6}, // (subrame number 8,9)
+{0xc2, -1, 1, 0, 528, 2, 1, 2, 6}, // (subrame number 4,9)
+{0xc2, -1, 1, 0, 640, 8, 1, 1, 6}, // (subrame number 7,9)
+{0xc2, -1, 1, 0, 792, 2, 1, 2, 6}, // (subrame number 3,4,8,9)
+{0xc2, -1, 1, 0, 792, 2, 2, 2, 6}, // (subrame number 3,4,8,9)
+{0xc2, -1, 1, 0, 682, 2, 1, 2, 6}, // (subrame number 1,3,5,7,9)
+{0xc2, -1, 1, 0, 1023, 8, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xa1, 0xb1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xa1, 0xb1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
+{0xa1, 0xb1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9)
+{0xa1, 0xb1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
+{0xa1, 0xb1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
+{0xa1, 0xb1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9)
+{0xa1, 0xb1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
+{0xa1, 0xb1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
+{0xa1, 0xb1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xa1, 0xb1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
+{0xa1, 0xb1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
+{0xa1, 0xb1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
+{0xa1, 0xb1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9)
+{0xa1, 0xb1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
+{0xa1, 0xb1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xa2, 0xb2, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
+{0xa2, 0xb2, 2, 1, 528, 6, 1, 2, 4}, // (subrame number 4,9)
+{0xa2, 0xb2, 2, 1, 640, 6, 1, 2, 4}, // (subrame number 7,9)
+{0xa2, 0xb2, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9)
+{0xa2, 0xb2, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9)
+{0xa2, 0xb2, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9)
+{0xa2, 0xb2, 1, 0, 512, 6, 1, 2, 4}, // (subrame number 9)
+{0xa2, 0xb2, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9)
+{0xa2, 0xb2, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9)
+{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9)
+{0xa2, 0xb2, 1, 0, 640, 6, 1, 2, 4}, // (subrame number 7,9)
+{0xa2, 0xb2, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9)
+{0xa2, 0xb2, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9)
+{0xa2, 0xb2, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9)
+{0xa2, 0xb2, 1, 0, 1023, 6, 1, 2, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xa3, 0xb3, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
+{0xa3, 0xb3, 2, 1, 528, 2, 1, 2, 6}, // (subrame number 4,9)
+{0xa3, 0xb3, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9)
+{0xa3, 0xb3, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9)
+{0xa3, 0xb3, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9)
+{0xa3, 0xb3, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9)
+{0xa3, 0xb3, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9)
+{0xa3, 0xb3, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9)
+{0xa3, 0xb3, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9)
+{0xa3, 0xb3, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9)
+{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9)
+{0xa3, 0xb3, 1, 0, 640, 2, 1, 2, 6}, // (subrame number 7,9)
+{0xa3, 0xb3, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9)
+{0xa3, 0xb3, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9)
+{0xa3, 0xb3, 1, 0, 1023, 2, 1, 2, 6} // (subrame number 0,1,2,3,4,5,6,7,8,9)
+};
+// Table 6.3.3.2-4: Random access configurations for FR2 and unpaired spectrum
+int64_t table_6_3_3_2_4_prachConfig_Index [256][10] = {
+//format, format, x, y, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
+{0xa1, -1, 16, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 16, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 8, 1, 2, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39)
+{0xa1, -1, 8, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 8, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 4, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 4, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 4, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 2, 1, -1, 551911719040, 0, 2, 6, 2}, // (subframe number :7,15,23,31,39)
+{0xa1, -1, 2, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 2, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 2, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 1, 0, -1, 549756338176, 7, 1, 3, 2}, // (subframe number :19,39)
+{0xa1, -1, 1, 0, -1, 168, 0, 1, 6, 2}, // (subframe number :3,5,7)
+{0xa1, -1, 1, 0, -1, 567489331200, 7, 1, 3, 2}, // (subframe number :24,29,34,39)
+{0xa1, -1, 1, 0, -1, 550293209600, 7, 2, 3, 2}, // (subframe number :9,19,29,39)
+{0xa1, -1, 1, 0, -1, 687195422720, 0, 1, 6, 2}, // (subframe number :17,19,37,39)
+{0xa1, -1, 1, 0, -1, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39)
+{0xa1, -1, 1, 0, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 1, 0, -1, 567489872400, 7, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 1, 0, -1, 10920, 7, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
+{0xa1, -1, 1, 0, -1, 586405642240, 7, 1, 3, 2}, // (subframe number :23,27,31,35,39)
+{0xa1, -1, 1, 0, -1, 551911719040, 0, 1, 6, 2}, // (subframe number :7,15,23,31,39)
+{0xa1, -1, 1, 0, -1, 586405642240, 0, 1, 6, 2}, // (subframe number :23,27,31,35,39)
+{0xa1, -1, 1, 0, -1, 965830828032, 7, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xa1, -1, 1, 0, -1, 586406201480, 7, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 1, 0, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 1, 0, -1, 733007751850, 0, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
+{0xa1, -1, 1, 0, -1, 1099511627775, 7, 1, 3, 2}, // (subframe number :0,1,2,…,39)
+{0xa2, -1, 16, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 16, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 8, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 8, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 8, 1, 2, 550293209600, 0, 2, 3, 4}, // (subframe number :9,19,29,39)
+{0xa2, -1, 4, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 4, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 4, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 2, 1, -1, 551911719040, 0, 2, 3, 4}, // (subframe number :7,15,23,31,39)
+{0xa2, -1, 2, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 2, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 2, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 1, 0, -1, 549756338176, 5, 1, 2, 4}, // (subframe number :19,39)
+{0xa2, -1, 1, 0, -1, 168, 0, 1, 3, 4}, // (subframe number :3,5,7)
+{0xa2, -1, 1, 0, -1, 567489331200, 5, 1, 2, 4}, // (subframe number :24,29,34,39)
+{0xa2, -1, 1, 0, -1, 550293209600, 5, 2, 2, 4}, // (subframe number :9,19,29,39)
+{0xa2, -1, 1, 0, -1, 687195422720, 0, 1, 3, 4}, // (subframe number :17,19,37,39)
+{0xa2, -1, 1, 0, -1, 550293209600, 0, 2, 3, 4}, // (subframe number :9, 19, 29, 39)
+{0xa2, -1, 1, 0, -1, 551911719040, 0, 1, 3, 4}, // (subframe number :7,15,23,31,39)
+{0xa2, -1, 1, 0, -1, 586405642240, 5, 1, 2, 4}, // (subframe number :23,27,31,35,39)
+{0xa2, -1, 1, 0, -1, 586405642240, 0, 1, 3, 4}, // (subframe number :23,27,31,35,39)
+{0xa2, -1, 1, 0, -1, 10920, 5, 1, 2, 4}, // (subframe number :3,5,7,9,11,13)
+{0xa2, -1, 1, 0, -1, 10920, 0, 1, 3, 4}, // (subframe number :3,5,7,9,11,13)
+{0xa2, -1, 1, 0, -1, 567489872400, 5, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 1, 0, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 1, 0, -1, 965830828032, 5, 2, 2, 4}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xa2, -1, 1, 0, -1, 586406201480, 5, 1, 2, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 1, 0, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 1, 0, -1, 733007751850, 0, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39)
+{0xa2, -1, 1, 0, -1, 1099511627775, 5, 1, 2, 4}, // (subframe number :0,1,2,…,39)
+{0xa3, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
+{0xa3, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 1, 0, -1, 549756338176, 7, 1, 1, 6}, // (subframe number :19,39)
+{0xa3, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7)
+{0xa3, -1, 1, 0, -1, 10752, 2, 1, 2, 6}, // (subframe number :9,11,13)
+{0xa3, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39)
+{0xa3, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39)
+{0xa3, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39)
+{0xa3, -1, 1, 0, -1, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
+{0xa3, -1, 1, 0, -1, 551911719040, 0, 1, 2, 6}, // (subframe number :7,15,23,31,39)
+{0xa3, -1, 1, 0, -1, 586405642240, 7, 1, 1, 6}, // (subframe number :23,27,31,35,39)
+{0xa3, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39)
+{0xa3, -1, 1, 0, -1, 10920, 0, 1, 2, 6}, // (subframe number :3,5,7,9,11,13)
+{0xa3, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13)
+{0xa3, -1, 1, 0, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 1, 0, -1, 567489872400, 7, 1, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xa3, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39)
+{0xa3, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39)
+{0xb1, -1, 16, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 8, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 8, 1, 2, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
+{0xb1, -1, 4, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 2, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 2, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb1, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
+{0xb1, -1, 1, 0, -1, 168, 2, 1, 6, 2}, // (subframe number :3,5,7)
+{0xb1, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39)
+{0xb1, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39)
+{0xb1, -1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39)
+{0xb1, -1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
+{0xb1, -1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39)
+{0xb1, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
+{0xb1, -1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39)
+{0xb1, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
+{0xb1, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb1, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xb1, -1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb1, -1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
+{0xb1, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39)
+{0xb4, -1, 16, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 16, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 8, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 8, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 8, 1, 2, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39)
+{0xb4, -1, 4, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 4, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 4, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 2, 1, -1, 551911719040, 2, 2, 1, 12}, // (subframe number :7,15,23,31,39)
+{0xb4, -1, 2, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 2, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 2, 1, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 1, 0, -1, 549756338176, 2, 2, 1, 12}, // (subframe number :19, 39)
+{0xb4, -1, 1, 0, -1, 687195422720, 0, 1, 1, 12}, // (subframe number :17, 19, 37, 39)
+{0xb4, -1, 1, 0, -1, 567489331200, 2, 1, 1, 12}, // (subframe number :24,29,34,39)
+{0xb4, -1, 1, 0, -1, 550293209600, 2, 2, 1, 12}, // (subframe number :9,19,29,39)
+{0xb4, -1, 1, 0, -1, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39)
+{0xb4, -1, 1, 0, -1, 551911719040, 0, 1, 1, 12}, // (subframe number :7,15,23,31,39)
+{0xb4, -1, 1, 0, -1, 551911719040, 0, 2, 1, 12}, // (subframe number :7,15,23,31,39)
+{0xb4, -1, 1, 0, -1, 586405642240, 0, 1, 1, 12}, // (subframe number :23,27,31,35,39)
+{0xb4, -1, 1, 0, -1, 586405642240, 2, 2, 1, 12}, // (subframe number :23,27,31,35,39)
+{0xb4, -1, 1, 0, -1, 698880, 0, 1, 1, 12}, // (subframe number :9,11,13,15,17,19)
+{0xb4, -1, 1, 0, -1, 10920, 2, 1, 1, 12}, // (subframe number :3,5,7,9,11,13)
+{0xb4, -1, 1, 0, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 1, 0, -1, 567489872400, 2, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 1, 0, -1, 965830828032, 2, 2, 1, 12}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xb4, -1, 1, 0, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 1, 0, -1, 586406201480, 2, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 1, 0, -1, 44739240, 2, 1, 1, 12}, // (subframe number :3, 5, 7, …, 23,25)
+{0xb4, -1, 1, 0, -1, 44739240, 0, 2, 1, 12}, // (subframe number :3, 5, 7, …, 23,25)
+{0xb4, -1, 1, 0, -1, 733007751850, 0, 1, 1, 12}, // (subframe number :1,3,5,7,…,37,39)
+{0xb4, -1, 1, 0, -1, 1099511627775, 2, 1, 1, 12}, // (subframe number :0, 1, 2,…, 39)
+{0xc0, -1, 16, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 16, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 8, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 8, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 8, 1, 2, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39)
+{0xc0, -1, 4, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 4, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 4, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 2, 1, -1, 551911719040, 0, 2, 7, 2}, // (subframe number :7,15,23,31,39)
+{0xc0, -1, 2, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 2, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 2, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
+{0xc0, -1, 1, 0, -1, 168, 0, 1, 7, 2}, // (subframe number :3,5,7)
+{0xc0, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39)
+{0xc0, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39)
+{0xc0, -1, 1, 0, -1, 687195422720, 0, 1, 7, 2}, // (subframe number :17,19,37,39)
+{0xc0, -1, 1, 0, -1, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39)
+{0xc0, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
+{0xc0, -1, 1, 0, -1, 551911719040, 0, 1, 7, 2}, // (subframe number :7,15,23,31,39)
+{0xc0, -1, 1, 0, -1, 586405642240, 0, 1, 7, 2}, // (subframe number :23,27,31,35,39)
+{0xc0, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
+{0xc0, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 1, 0, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xc0, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 1, 0, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 1, 0, -1, 733007751850, 0, 1, 7, 2}, // (subframe number :1,3,5,7,…,37,39)
+{0xc0, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39)
+{0xc2, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
+{0xc2, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 2, 1, -1, 551911719040, 2, 2, 2, 6}, // (subframe number :7,15,23,31,39)
+{0xc2, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39)
+{0xc2, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7)
+{0xc2, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39)
+{0xc2, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39)
+{0xc2, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39)
+{0xc2, -1, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39)
+{0xc2, -1, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39)
+{0xc2, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13)
+{0xc2, -1, 1, 0, -1, 586405642240, 7, 2, 1, 6}, // (subframe number :23,27,31,35,39)
+{0xc2, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39)
+{0xc2, -1, 1, 0, -1, 567489872400, 7, 2, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xc2, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39)
+{0xc2, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39)
+{0xa1, 0xb1, 16, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 16, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, 0xb1, 8, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 8, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, 0xb1, 4, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 4, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, 0xb1, 2, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
+{0xa1, 0xb1, 1, 0, -1, 550293209600, 8, 1, 3, 2}, // (subframe number :9,19,29,39)
+{0xa1, 0xb1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39)
+{0xa1, 0xb1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
+{0xa1, 0xb1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
+{0xa1, 0xb1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39)
+{0xa1, 0xb1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39)
+{0xa1, 0xb1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, 0xb1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
+{0xa2, 0xb2, 16, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 16, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, 0xb2, 8, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 8, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, 0xb2, 4, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 4, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, 0xb2, 2, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 1, 0, -1, 549756338176, 6, 1, 2, 4}, // (subframe number :19,39)
+{0xa2, 0xb2, 1, 0, -1, 550293209600, 6, 1, 2, 4}, // (subframe number :9,19,29,39)
+{0xa2, 0xb2, 1, 0, -1, 687195422720, 2, 1, 3, 4}, // (subframe number :17,19,37,39)
+{0xa2, 0xb2, 1, 0, -1, 550293209600, 2, 2, 3, 4}, // (subframe number :9,19,29,39)
+{0xa2, 0xb2, 1, 0, -1, 586405642240, 6, 1, 2, 4}, // (subframe number :23,27,31,35,39)
+{0xa2, 0xb2, 1, 0, -1, 551911719040, 2, 1, 3, 4}, // (subframe number :7,15,23,31,39)
+{0xa2, 0xb2, 1, 0, -1, 586405642240, 2, 1, 3, 4}, // (subframe number :23,27,31,35,39)
+{0xa2, 0xb2, 1, 0, -1, 567489872400, 6, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 1, 0, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 1, 0, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, 0xb2, 1, 0, -1, 733007751850, 2, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39)
+{0xa3, 0xb3, 16, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 16, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, 0xb3, 8, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 8, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, 0xb3, 4, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 4, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, 0xb3, 2, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39)
+{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 1, 2, 6}, // (subframe number :9,19,29,39)
+{0xa3, 0xb3, 1, 0, -1, 687195422720, 2, 1, 2, 6}, // (subframe number :17,19,37,39)
+{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39)
+{0xa3, 0xb3, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39)
+{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 1, 2, 6}, // (subframe number :23,27,31,35,39)
+{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 2, 2, 6}, // (subframe number :23,27,31,35,39)
+{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 1, 0, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, 0xb3, 1, 0, -1, 733007751850, 2, 1, 2, 6} // (subframe number :1,3,5,7,…,37,39)
+};
+
+
+int get_format0(uint8_t index,
+ uint8_t unpaired){
+
+ uint16_t format;
+ if (unpaired)
+ format = table_6_3_3_2_3_prachConfig_Index[index][0];
+ else
+ format = table_6_3_3_2_2_prachConfig_Index[index][0];
+
+ return format;
+}
+
+void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss,
+ uint16_t *slot_period,
+ uint16_t *offset) {
+
+ switch(ss->monitoringSlotPeriodicityAndOffset->present) {
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1:
+ *slot_period = 1;
+ *offset = 0;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2:
+ *slot_period = 2;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl4:
+ *slot_period = 4;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl4;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5:
+ *slot_period = 5;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl5;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl8:
+ *slot_period = 8;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl8;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl10:
+ *slot_period = 10;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl10;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl16:
+ *slot_period = 16;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl16;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl20:
+ *slot_period = 20;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl20;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl40:
+ *slot_period = 40;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl40;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl80:
+ *slot_period = 80;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl80;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl160:
+ *slot_period = 160;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl160;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl320:
+ *slot_period = 320;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl320;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl640:
+ *slot_period = 640;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl640;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1280:
+ *slot_period = 1280;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl1280;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2560:
+ *slot_period = 2560;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2560;
+ break;
+ default:
+ AssertFatal(1==0,"Invalid monitoring slot periodicity and offset value\n");
+ break;
+ }
+}
+
+int get_nr_prach_info_from_index(uint8_t index,
+ int frame,
+ int slot,
+ uint32_t pointa,
+ uint8_t mu,
+ uint8_t unpaired,
+ uint16_t *format,
+ uint8_t *start_symbol,
+ uint8_t *N_t_slot,
+ uint8_t *N_dur) {
+
+ int x,y;
+ int64_t s_map;
+ uint8_t format2 = 0xff;
+
+ if (pointa > 2016666) { //FR2
+ int y2;
+ uint8_t slot_60khz;
+ x = table_6_3_3_2_4_prachConfig_Index[index][2];
+ y = table_6_3_3_2_4_prachConfig_Index[index][3];
+ y2 = table_6_3_3_2_4_prachConfig_Index[index][4];
+ // checking n_sfn mod x = y
+ if ( (frame%x)==y || (frame%x)==y2 ) {
+ slot_60khz = slot >> (mu-2); // in table slots are numbered wrt 60kHz
+ s_map = table_6_3_3_2_4_prachConfig_Index[index][5];
+ if ( ((s_map>>slot_60khz)&0x01) ) {
+ if (mu == 3) {
+ if ( (table_6_3_3_2_4_prachConfig_Index[index][7] == 1) && (slot%2 == 0) )
+ return 0; // no prach in even slots @ 120kHz for 1 prach per 60khz slot
+ }
+ if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
+ *start_symbol = table_6_3_3_2_4_prachConfig_Index[index][6];
+ *N_t_slot = table_6_3_3_2_4_prachConfig_Index[index][8];
+ *N_dur = table_6_3_3_2_4_prachConfig_Index[index][9];
+ if (table_6_3_3_2_4_prachConfig_Index[index][1] != -1)
+ format2 = (uint8_t) table_6_3_3_2_4_prachConfig_Index[index][1];
+ *format = ((uint8_t) table_6_3_3_2_4_prachConfig_Index[index][0]) | (format2<<8);
+ LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame,
+ slot,
+ index,
+ pointa,
+ mu,
+ unpaired,
+ *start_symbol,
+ *N_t_slot,
+ *N_dur);
+ }
+ return 1;
+ }
+ else
+ return 0; // no prach in current slot
+ }
+ else
+ return 0; // no prach in current frame
+ }
+ else {
+ uint8_t subframe;
+ if (unpaired) {
+ x = table_6_3_3_2_3_prachConfig_Index[index][2];
+ y = table_6_3_3_2_3_prachConfig_Index[index][3];
+ if ( (frame%x)==y ) {
+ subframe = slot >> mu;
+ s_map = table_6_3_3_2_3_prachConfig_Index[index][4];
+ if ( (s_map>>subframe)&0x01 ) {
+ if (mu == 1) {
+ if ( (table_6_3_3_2_3_prachConfig_Index[index][6] <= 1) && (slot%2 == 0) )
+ return 0; // no prach in even slots @ 30kHz for 1 prach per subframe
+ }
+ if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
+ *start_symbol = table_6_3_3_2_3_prachConfig_Index[index][5];
+ *N_t_slot = table_6_3_3_2_3_prachConfig_Index[index][7];
+ *N_dur = table_6_3_3_2_3_prachConfig_Index[index][8];
+ if (table_6_3_3_2_3_prachConfig_Index[index][1] != -1)
+ format2 = (uint8_t) table_6_3_3_2_3_prachConfig_Index[index][1];
+ *format = ((uint8_t) table_6_3_3_2_3_prachConfig_Index[index][0]) | (format2<<8);
+ LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d (col 6 %ld) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame,
+ slot,
+ index, table_6_3_3_2_3_prachConfig_Index[index][6],
+ pointa,
+ mu,
+ unpaired,
+ *start_symbol,
+ *N_t_slot,
+ *N_dur);
+ }
+ return 1;
+ }
+ else
+ return 0; // no prach in current slot
+ }
+ else
+ return 0; // no prach in current frame
+ }
+ else { // FDD
+ x = table_6_3_3_2_2_prachConfig_Index[index][2];
+ y = table_6_3_3_2_2_prachConfig_Index[index][3];
+ if ( (frame%x)==y ) {
+ subframe = slot >> mu;
+ s_map = table_6_3_3_2_2_prachConfig_Index[index][4];
+ if ( (s_map>>subframe)&0x01 ) {
+ if (mu == 1) {
+ if ( (table_6_3_3_2_2_prachConfig_Index[index][6] <= 1) && (slot%2 == 0) )
+ return 0; // no prach in even slots @ 30kHz for 1 prach per subframe
+ }
+ if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
+ *start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5];
+ *N_t_slot = table_6_3_3_2_2_prachConfig_Index[index][7];
+ *N_dur = table_6_3_3_2_2_prachConfig_Index[index][8];
+ if (table_6_3_3_2_2_prachConfig_Index[index][1] != -1)
+ format2 = (uint8_t) table_6_3_3_2_2_prachConfig_Index[index][1];
+ *format = ((uint8_t) table_6_3_3_2_2_prachConfig_Index[index][0]) | (format2<<8);
+ LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame,
+ slot,
+ index,
+ pointa,
+ mu,
+ unpaired,
+ *start_symbol,
+ *N_t_slot,
+ *N_dur);
+ }
+ return 1;
+ }
+ else
+ return 0; // no prach in current slot
+ }
+ else
+ return 0; // no prach in current frame
+ }
+ }
+}
+
+//Table 6.3.3.1-3: Mapping from logical index i to sequence number u for preamble formats with L_RA = 839
+uint16_t table_63313[838] = {
+129, 710, 140, 699, 120, 719, 210, 629, 168, 671, 84 , 755, 105, 734, 93 , 746, 70 , 769, 60 , 779,
+2 , 837, 1 , 838, 56 , 783, 112, 727, 148, 691, 80 , 759, 42 , 797, 40 , 799, 35 , 804, 73 , 766,
+146, 693, 31 , 808, 28 , 811, 30 , 809, 27 , 812, 29 , 810, 24 , 815, 48 , 791, 68 , 771, 74 , 765,
+178, 661, 136, 703, 86 , 753, 78 , 761, 43 , 796, 39 , 800, 20 , 819, 21 , 818, 95 , 744, 202, 637,
+190, 649, 181, 658, 137, 702, 125, 714, 151, 688, 217, 622, 128, 711, 142, 697, 122, 717, 203, 636,
+118, 721, 110, 729, 89 , 750, 103, 736, 61 , 778, 55 , 784, 15 , 824, 14 , 825, 12 , 827, 23 , 816,
+34 , 805, 37 , 802, 46 , 793, 207, 632, 179, 660, 145, 694, 130, 709, 223, 616, 228, 611, 227, 612,
+132, 707, 133, 706, 143, 696, 135, 704, 161, 678, 201, 638, 173, 666, 106, 733, 83 , 756, 91 , 748,
+66 , 773, 53 , 786, 10 , 829, 9 , 830, 7 , 832, 8 , 831, 16 , 823, 47 , 792, 64 , 775, 57 , 782,
+104, 735, 101, 738, 108, 731, 208, 631, 184, 655, 197, 642, 191, 648, 121, 718, 141, 698, 149, 690,
+216, 623, 218, 621, 152, 687, 144, 695, 134, 705, 138, 701, 199, 640, 162, 677, 176, 663, 119, 720,
+158, 681, 164, 675, 174, 665, 171, 668, 170, 669, 87 , 752, 169, 670, 88 , 751, 107, 732, 81 , 758,
+82 , 757, 100, 739, 98 , 741, 71 , 768, 59 , 780, 65 , 774, 50 , 789, 49 , 790, 26 , 813, 17 , 822,
+13 , 826, 6 , 833, 5 , 834, 33 , 806, 51 , 788, 75 , 764, 99 , 740, 96 , 743, 97 , 742, 166, 673,
+172, 667, 175, 664, 187, 652, 163, 676, 185, 654, 200, 639, 114, 725, 189, 650, 115, 724, 194, 645,
+195, 644, 192, 647, 182, 657, 157, 682, 156, 683, 211, 628, 154, 685, 123, 716, 139, 700, 212, 627,
+153, 686, 213, 626, 215, 624, 150, 689, 225, 614, 224, 615, 221, 618, 220, 619, 127, 712, 147, 692,
+124, 715, 193, 646, 205, 634, 206, 633, 116, 723, 160, 679, 186, 653, 167, 672, 79 , 760, 85 , 754,
+77 , 762, 92 , 747, 58 , 781, 62 , 777, 69 , 770, 54 , 785, 36 , 803, 32 , 807, 25 , 814, 18 , 821,
+11 , 828, 4 , 835, 3 , 836, 19 , 820, 22 , 817, 41 , 798, 38 , 801, 44 , 795, 52 , 787, 45 , 794,
+63 , 776, 67 , 772, 72 , 767, 76 , 763, 94 , 745, 102, 737, 90 , 749, 109, 730, 165, 674, 111, 728,
+209, 630, 204, 635, 117, 722, 188, 651, 159, 680, 198, 641, 113, 726, 183, 656, 180, 659, 177, 662,
+196, 643, 155, 684, 214, 625, 126, 713, 131, 708, 219, 620, 222, 617, 226, 613, 230, 609, 232, 607,
+262, 577, 252, 587, 418, 421, 416, 423, 413, 426, 411, 428, 376, 463, 395, 444, 283, 556, 285, 554,
+379, 460, 390, 449, 363, 476, 384, 455, 388, 451, 386, 453, 361, 478, 387, 452, 360, 479, 310, 529,
+354, 485, 328, 511, 315, 524, 337, 502, 349, 490, 335, 504, 324, 515, 323, 516, 320, 519, 334, 505,
+359, 480, 295, 544, 385, 454, 292, 547, 291, 548, 381, 458, 399, 440, 380, 459, 397, 442, 369, 470,
+377, 462, 410, 429, 407, 432, 281, 558, 414, 425, 247, 592, 277, 562, 271, 568, 272, 567, 264, 575,
+259, 580, 237, 602, 239, 600, 244, 595, 243, 596, 275, 564, 278, 561, 250, 589, 246, 593, 417, 422,
+248, 591, 394, 445, 393, 446, 370, 469, 365, 474, 300, 539, 299, 540, 364, 475, 362, 477, 298, 541,
+312, 527, 313, 526, 314, 525, 353, 486, 352, 487, 343, 496, 327, 512, 350, 489, 326, 513, 319, 520,
+332, 507, 333, 506, 348, 491, 347, 492, 322, 517, 330, 509, 338, 501, 341, 498, 340, 499, 342, 497,
+301, 538, 366, 473, 401, 438, 371, 468, 408, 431, 375, 464, 249, 590, 269, 570, 238, 601, 234, 605,
+257, 582, 273, 566, 255, 584, 254, 585, 245, 594, 251, 588, 412, 427, 372, 467, 282, 557, 403, 436,
+396, 443, 392, 447, 391, 448, 382, 457, 389, 450, 294, 545, 297, 542, 311, 528, 344, 495, 345, 494,
+318, 521, 331, 508, 325, 514, 321, 518, 346, 493, 339, 500, 351, 488, 306, 533, 289, 550, 400, 439,
+378, 461, 374, 465, 415, 424, 270, 569, 241, 598, 231, 608, 260, 579, 268, 571, 276, 563, 409, 430,
+398, 441, 290, 549, 304, 535, 308, 531, 358, 481, 316, 523, 293, 546, 288, 551, 284, 555, 368, 471,
+253, 586, 256, 583, 263, 576, 242, 597, 274, 565, 402, 437, 383, 456, 357, 482, 329, 510, 317, 522,
+307, 532, 286, 553, 287, 552, 266, 573, 261, 578, 236, 603, 303, 536, 356, 483, 355, 484, 405, 434,
+404, 435, 406, 433, 235, 604, 267, 572, 302, 537, 309, 530, 265, 574, 233, 606, 367, 472, 296, 543,
+336, 503, 305, 534, 373, 466, 280, 559, 279, 560, 419, 420, 240, 599, 258, 581, 229, 610
+};
+
+uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
+ uint8_t nb_preambles,
+ uint8_t unpaired) {
+
+ uint8_t config_index = rach_config->rach_ConfigGeneric.prach_ConfigurationIndex;
+ uint8_t ncs_index = rach_config->rach_ConfigGeneric.zeroCorrelationZoneConfig;
+ uint16_t format0 = get_format0(config_index, unpaired);
+ uint16_t NCS = get_NCS(ncs_index, format0, rach_config->restrictedSetConfig);
+ uint16_t L_ra = (rach_config->prach_RootSequenceIndex.present==NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139) ? 139 : 839;
+ uint16_t r,u,index,q,d_u,n_shift_ra,n_shift_ra_bar,d_start;
+ uint32_t w;
+ uint8_t found_preambles = 0;
+ uint8_t found_sequences = 0;
+
+ if (rach_config->restrictedSetConfig == 0) {
+ if (NCS == 0) return nb_preambles;
+ else {
+ r = L_ra/NCS;
+ printf(" found_sequences %u\n", (nb_preambles/r));
+ return (nb_preambles/r);
+ }
+ }
+ else{
+ index = rach_config->prach_RootSequenceIndex.choice.l839;
+ while (found_preambles < nb_preambles) {
+ u = table_63313[index%(L_ra-1)];
+
+ q = 0;
+ while (((q*u)%L_ra) != 1) q++;
+ if (q < 420) d_u = q;
+ else d_u = L_ra - q;
+
+ uint16_t n_group_ra = 0;
+ if (rach_config->restrictedSetConfig == 1) {
+ if ( (d_u<280) && (d_u>=NCS) ) {
+ n_shift_ra = d_u/NCS;
+ d_start = (d_u<<1) + (n_shift_ra * NCS);
+ n_group_ra = L_ra/d_start;
+ n_shift_ra_bar = max(0,(L_ra-(d_u<<1)-(n_group_ra*d_start))/L_ra);
+ } else if ( (d_u>=280) && (d_u<=((L_ra - NCS)>>1)) ) {
+ n_shift_ra = (L_ra - (d_u<<1))/NCS;
+ d_start = L_ra - (d_u<<1) + (n_shift_ra * NCS);
+ n_group_ra = d_u/d_start;
+ n_shift_ra_bar = min(n_shift_ra,max(0,(d_u- (n_group_ra*d_start))/NCS));
+ } else {
+ n_shift_ra = 0;
+ n_shift_ra_bar = 0;
+ }
+ w = n_shift_ra*n_group_ra + n_shift_ra_bar;
+ found_preambles += w;
+ found_sequences++;
+ }
+ else {
+ AssertFatal(1==0,"Procedure to find nb of sequences for restricted type B not implemented yet");
+ }
+ }
+ printf(" found_sequences %u\n", found_sequences);
+ return found_sequences;
+ }
+}
+
nr_bandentry_t nr_bandtable[] = {
{1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100},
@@ -373,13 +1536,23 @@ int32_t get_nr_uldl_offset(int nr_bandP)
void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
- int x_overhead) {
+ int x_overhead,
+ uint8_t numdmrscdmgroupnodata,
+ uint8_t tb_scaling) {
LOG_D(MAC, "TBS calculation\n");
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_rel15 = &pdsch_pdu->pdsch_pdu_rel15;
uint16_t N_PRB_oh = x_overhead;
- uint8_t N_PRB_DMRS = (pdsch_rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000
+ uint8_t N_PRB_DMRS;
+ if (pdsch_rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) {
+ // if no data in dmrs cdm group is 1 only even REs have no data
+ // if no data in dmrs cdm group is 2 both odd and even REs have no data
+ N_PRB_DMRS = numdmrscdmgroupnodata*6;
+ }
+ else {
+ N_PRB_DMRS = numdmrscdmgroupnodata*4;
+ }
uint8_t N_sh_symb = pdsch_rel15->NrOfSymbols;
uint8_t Imcs = pdsch_rel15->mcsIndex[0];
uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh;
@@ -401,8 +1574,9 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
R,
pdsch_rel15->rbSize,
N_sh_symb,
- N_PRB_DMRS,
+ N_PRB_DMRS, // FIXME // This should be multiplied by the number of dmrs symbols
N_PRB_oh,
+ tb_scaling,
pdsch_rel15->nrOfLayers)>>3;
pdsch_rel15->targetCodeRate[0] = R;
@@ -558,6 +1732,48 @@ int get_num_dmrs(uint16_t dmrs_mask ) {
return(num_dmrs);
}
+// Table 5.1.2.2.1-1 38.214
+uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config) {
+
+ AssertFatal(bwp_size<276,"BWP Size > 275\n");
+
+ if (bwp_size < 37) return (rbg_size_config ? 4 : 2);
+ if (bwp_size < 73) return (rbg_size_config ? 8 : 4);
+ if (bwp_size < 145) return (rbg_size_config ? 16 : 8);
+ else return 16;
+}
+
+uint8_t getNRBG(uint16_t bwp_size, uint16_t bwp_start, long rbg_size_config) {
+
+ uint8_t rbg_size = getRBGSize(bwp_size,rbg_size_config);
+
+ return (uint8_t)ceil((bwp_size+(bwp_start % rbg_size))/rbg_size);
+}
+
+uint8_t getAntPortBitWidth(NR_SetupRelease_DMRS_DownlinkConfig_t *typeA, NR_SetupRelease_DMRS_DownlinkConfig_t *typeB) {
+
+ uint8_t nbitsA = 0;
+ uint8_t nbitsB = 0;
+ uint8_t type,length,nbits;
+
+ if (typeA != NULL) {
+ type = (typeA->choice.setup->dmrs_Type==NULL) ? 1:2;
+ length = (typeA->choice.setup->maxLength==NULL) ? 1:2;
+ nbitsA = type + length + 2;
+ if (typeB == NULL) return nbitsA;
+ }
+ if (typeB != NULL) {
+ type = (typeB->choice.setup->dmrs_Type==NULL) ? 1:2;
+ length = (typeB->choice.setup->maxLength==NULL) ? 1:2;
+ nbitsB = type + length + 2;
+ if (typeA == NULL) return nbitsB;
+ }
+
+ nbits = (nbitsA > nbitsB) ? nbitsA : nbitsB;
+ return nbits;
+}
+
+
/*******************************************************************
*
* NAME : get_l0_ul
@@ -664,11 +1880,24 @@ uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) {
return 1;
}
-uint16_t nr_dci_size(nr_dci_format_t format,
+uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc,
+ NR_CellGroupConfig_t *secondaryCellGroup,
+ dci_pdu_rel15_t *dci_pdu,
+ nr_dci_format_t format,
nr_rnti_type_t rnti_type,
- uint16_t N_RB) {
+ uint16_t N_RB,
+ int bwp_id) {
uint16_t size = 0;
+ uint16_t numRBG = 0;
+ long rbg_size_config;
+ int num_entries = 0;
+ int pusch_antenna_ports = 1; // TODO hardcoded number of antenna ports for pusch
+ NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
+ NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
+ NR_PDSCH_Config_t *pdsch_config = bwp->bwp_Dedicated->pdsch_Config->choice.setup;
+ NR_PUSCH_Config_t *pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup;
+ NR_SRS_Config_t *srs_config = ubwp->bwp_Dedicated->srs_Config->choice.setup;
switch(format) {
/*Only sizes for 0_0 and 1_0 are correct at the moment*/
@@ -676,30 +1905,199 @@ uint16_t nr_dci_size(nr_dci_format_t format,
/// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
size += 20;
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated
- size += nr_dci_size(NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB) - size; // Padding to match 1_0 size
+ size += nr_dci_size(scc,secondaryCellGroup,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id) - size; // Padding to match 1_0 size
// UL/SUL indicator assumed to be 0
break;
case NR_UL_DCI_FORMAT_0_1:
- /// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, SRS request 2 --17
- size += 17;
+ /// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, ULSCH indicator 1 --16
+ size += 16;
// Carrier indicator
+ if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) {
+ dci_pdu->carrier_indicator.nbits=3;
+ size += dci_pdu->carrier_indicator.nbits;
+ }
// UL/SUL indicator
+ if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->supplementaryUplink != NULL) {
+ dci_pdu->carrier_indicator.nbits=1;
+ size += dci_pdu->ul_sul_indicator.nbits;
+ }
// BWP Indicator
+ uint8_t n_ul_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
+ if (n_ul_bwp < 2)
+ dci_pdu->bwp_indicator.nbits = n_ul_bwp;
+ else
+ dci_pdu->bwp_indicator.nbits = 2;
+ size += dci_pdu->bwp_indicator.nbits;
// Freq domain assignment
+ if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pusch_Config->choice.setup->rbg_Size != NULL)
+ rbg_size_config = 1;
+ else
+ rbg_size_config = 0;
+ numRBG = getNRBG(NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275),
+ NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275),
+ rbg_size_config);
+ if (pusch_Config->resourceAllocation == 0)
+ dci_pdu->frequency_domain_assignment.nbits = numRBG;
+ else if (pusch_Config->resourceAllocation == 1)
+ dci_pdu->frequency_domain_assignment.nbits = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
+ else
+ dci_pdu->frequency_domain_assignment.nbits = ((int)ceil( log2( (N_RB*(N_RB+1))>>1 ) )>numRBG) ? (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) )+1 : numRBG+1;
+ size += dci_pdu->frequency_domain_assignment.nbits;
// Time domain assignment
- // VRB to PRB mapping
+ if (pusch_Config->pusch_TimeDomainAllocationList==NULL) {
+ if (ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList==NULL)
+ num_entries = 16; // num of entries in default table
+ else
+ num_entries = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count;
+ }
+ else
+ num_entries = pusch_Config->pusch_TimeDomainAllocationList->choice.setup->list.count;
+ dci_pdu->time_domain_assignment.nbits = (int)ceil(log2(num_entries));
+ size += dci_pdu->time_domain_assignment.nbits;
// Frequency Hopping flag
+ if ((pusch_Config->frequencyHopping!=NULL) && (pusch_Config->resourceAllocation != NR_PUSCH_Config__resourceAllocation_resourceAllocationType0)) {
+ dci_pdu->frequency_hopping_flag.nbits = 1;
+ size += 1;
+ }
// 1st DAI
+ if (secondaryCellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook==NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic)
+ dci_pdu->dai[0].nbits = 2;
+ else
+ dci_pdu->dai[0].nbits = 1;
+ size += dci_pdu->dai[0].nbits;
// 2nd DAI
+ if (secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) { //TODO not sure about that
+ dci_pdu->dai[1].nbits = 2;
+ size += dci_pdu->dai[1].nbits;
+ }
// SRS resource indicator
+ if (pusch_Config->txConfig != NULL){
+ int count=0;
+ if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook){
+ for (int i=0; i