Commit 609c2716 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/ldpc_offload_t1_mr' into integration_2022_wk35b

parents 392946f0 2e7533a0
......@@ -21,7 +21,6 @@ The Regents of the University of California: BSD 3-Clause Licence.
Niels Provos <provos@citi.umich.edu>: BSD 2-Clause Licence.
## Credits for source code openair3/GTPV1-U/nw-gtpv1u: ##
Amit Chawre <http://www.amitchawre.net/contact.html>: BSD 2-Clause Licence.
## Credits for source code openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c and nrLDPC_offload.h: ##
Intel Corporation SPDX-License-Identifier: BSD-3-Clause Licence
......@@ -338,6 +338,27 @@ pipeline {
}
}
}
//avra is offline, re-enable once it is available
//stage ("Test T1 Offload") {
// when { expression {doMandatoryTests} }
// steps {
// script {
// triggerSlaveJob ('RAN-T1-Offload-Test', 'Test-T1-Offload')
// }
// }
// post {
// always {
// script {
// finalizeSlaveJob('RAN-T1-Offload-Test')
// }
// }
// failure {
// script {
// currentBuild.result = 'FAILURE'
// }
// }
// }
//}
}
}
stage ("Images Push to Registries") {
......
......@@ -74,7 +74,7 @@ then
IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true`
IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE || true`
IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence|License-Identifier: BSD-2-Clause" $FILE || true`
IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h|openair1/PHY/CODING/crc|openair1/PHY/CODING/types.h" || true`
IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h|openair1/PHY/CODING/types.h|openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c|openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_offload.h" || true`
if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ]
then
if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ]
......@@ -184,7 +184,7 @@ do
IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true`
IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE || true`
IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence|License-Identifier: BSD-2-Clause" $FULLFILE || true`
IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h|openair1/PHY/CODING/crc|openair1/PHY/CODING/types.h" || true`
IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h|openair1/PHY/CODING/types.h|openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c|openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_offload.h" || true`
if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ]
then
if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ]
......
......@@ -56,7 +56,6 @@ class PhySim:
self.__workSpacePath=''
self.__buildLogFile='compile_phy_sim.log'
self.__runLogFile=''
self.__runResults=[]
self.__runLogPath='phy_sim_logs'
......@@ -64,20 +63,20 @@ class PhySim:
#PRIVATE Methods
#-----------------
def __CheckResults_PhySim(self,HTML,CONST,testcase_id):
def __CheckResults_LDPCTest(self,HTML,CONST,testcase_id):
mySSH = sshconnection.SSHConnection()
mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
#retrieve run log file and store it locally$
mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, self.__workSpacePath+self.__runLogFile, '.')
mySSH.close()
#parse results looking for Encoding and Decoding mean values
self.__runResults=[]
runResults=[]
with open(self.__runLogFile) as f:
for line in f:
if 'mean' in line:
self.__runResults.append(line)
runResults.append(line)
#the values are appended for each mean value (2), so we take these 2 values from the list
info=self.__runResults[0]+self.__runResults[1]
info = runResults[0] + runResults[1]
#once parsed move the local logfile to its folder for tidiness
os.system('mv '+self.__runLogFile+' '+ self.__runLogPath+'/.')
......@@ -89,6 +88,38 @@ class PhySim:
HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', 1, html_queue)
return HTML
def __CheckResults_NRulsimTest(self, HTML, CONST, testcase_id):
html_queue = SimpleQueue()
#retrieve run log file and store it locally
mySSH = sshconnection.SSHConnection()
filename = self.__workSpacePath + self.__runLogFile
ret = mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, filename, '.')
if ret != 0:
error_msg = f'could not recover test result file {filename}'
logging.error(error_msg)
html_queue.put(f'<pre style="background-color:white">{error_msg}</pre>')
HTML.CreateHtmlTestRowQueue("could not recover results", 'KO', 1, html_queue)
self.exitStatus = 1
return HTML
PUSCH_OK = False
with open(self.__runLogFile) as f:
PUSCH_OK = 'PUSCH test OK' in f.read()
# once parsed move the local logfile to its folder for tidiness
os.system(f'mv {self.__runLogFile} {self.__runLogPath}/.')
#updating the HTML with results
if PUSCH_OK:
html_queue.put('<pre style="background-color:white">succeeded</pre>')
HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', 1, html_queue)
else:
error_msg = 'error: no "PUSCH test OK"'
logging.error(error_msg)
html_queue.put(f'<pre style="background-color:white">{error_msg}</pre>')
HTML.CreateHtmlTestRowQueue(self.runargs, 'KO', 1, html_queue)
self.exitStatus = 1
return HTML
def __CheckBuild_PhySim(self, HTML, CONST):
self.__workSpacePath=self.eNBSourceCodePath+'/cmake_targets/'
......@@ -100,21 +131,16 @@ class PhySim:
mySSH.command('rm ' + self.__workSpacePath+self.__runLogFile, '\$', 5)
mySSH.close()
#check build result from local compile log file
buildStatus=False
with open(self.__buildLogFile) as f:
#nr_prachsim is the last compile step
if 'nr_prachsim compiled' in f.read():
buildStatus=True
#update HTML based on build status
if buildStatus:
HTML.CreateHtmlTestRow(self.buildargs, 'OK', CONST.ALL_PROCESSES_OK, 'LDPC')
self.exitStatus=0
else:
logging.error('\u001B[1m Building Physical Simulators Failed\u001B[0m')
HTML.CreateHtmlTestRow(self.buildargs, 'KO', CONST.ALL_PROCESSES_OK, 'LDPC')
HTML.CreateHtmlTabFooter(False)
#exitStatus=1 will do a sys.exit in main
self.exitStatus=1
if 'BUILD SHOULD BE SUCCESSFUL' in f.read():
HTML.CreateHtmlTestRow(self.buildargs, 'OK', CONST.ALL_PROCESSES_OK, 'PhySim')
self.exitStatus=0
return HTML
logging.error('\u001B[1m Building Physical Simulators Failed\u001B[0m')
HTML.CreateHtmlTestRow(self.buildargs, 'KO', CONST.ALL_PROCESSES_OK, 'LDPC')
HTML.CreateHtmlTabFooter(False)
#exitStatus=1 will do a sys.exit in main
self.exitStatus = 1
return HTML
......@@ -163,8 +189,7 @@ class PhySim:
mySSH.command('source oaienv', '\$', 5)
mySSH.command('cd cmake_targets', '\$', 5)
mySSH.command('mkdir -p log', '\$', 5)
mySSH.command('chmod 777 log', '\$', 5)
mySSH.command('stdbuf -o0 ./build_oai ' + self.buildargs + ' 2>&1 | stdbuf -o0 tee ' + self.__buildLogFile, 'Bypassing the Tests|build have failed', 1500)
mySSH.command(f'./build_oai {self.buildargs} 2>&1 | tee {self.__buildLogFile}', '\$', 1500)
mySSH.close()
#check build status and update HTML object
......@@ -173,7 +198,8 @@ class PhySim:
return lHTML
def Run_PhySim(self,htmlObj,constObj,testcase_id):
def Run_LDPCTest(self,htmlObj,constObj,testcase_id):
self.__workSpacePath = self.eNBSourceCodePath+'/cmake_targets/'
#create run logs folder locally
os.system('mkdir -p ./'+self.__runLogPath)
#log file is tc_<testcase_id>.log remotely
......@@ -187,5 +213,18 @@ class PhySim:
mySSH.close()
#return updated HTML to main
lHTML = cls_oai_html.HTMLManagement()
lHTML=self.__CheckResults_PhySim(htmlObj,constObj,testcase_id)
lHTML=self.__CheckResults_LDPCTest(htmlObj,constObj,testcase_id)
return lHTML
def Run_NRulsimTest(self, htmlObj, constObj, testcase_id):
self.__workSpacePath=self.eNBSourceCodePath+'/cmake_targets/'
os.system(f'mkdir -p ./{self.__runLogPath}')
self.__runLogFile = f'physim_{testcase_id}.log'
mySSH = sshconnection.SSHConnection()
mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
mySSH.command(f'cd {self.__workSpacePath}', '\$', 5)
mySSH.command(f'sudo {self.__workSpacePath}ran_build/build/nr_ulsim {self.runargs} > {self.__runLogFile} 2>&1', '\$', 30)
mySSH.close()
#return updated HTML to main
lHTML = self.__CheckResults_NRulsimTest(htmlObj, constObj, testcase_id)
return lHTML
......@@ -457,9 +457,18 @@ def GetParametersFromXML(action):
if (string_field is not None):
CONTAINERS.testSvrId = string_field
else: # ie action == 'Run_PhySim':
elif action == 'Run_LDPCTest' or action == 'Run_NRulsimTest':
ldpc.runargs = test.findtext('physim_run_args')
elif action == 'LicenceAndFormattingCheck':
pass
elif action == 'Cppcheck_Analysis':
pass
else:
logging.error(f"unknown action {action}")
#check if given test is in list
#it is in list if one of the strings in 'list' is at the beginning of 'test'
......@@ -914,8 +923,14 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
HTML=ldpc.Build_PhySim(HTML,CONST)
if ldpc.exitStatus==1:
RAN.prematureExit = True
elif action == 'Run_PhySim':
HTML=ldpc.Run_PhySim(HTML,CONST,id)
elif action == 'Run_LDPCTest':
HTML=ldpc.Run_LDPCTest(HTML,CONST,id)
if ldpc.exitStatus==1:
RAN.prematureExit = True
elif action == 'Run_NRulsimTest':
HTML=ldpc.Run_NRulsimTest(HTML,CONST,id)
if ldpc.exitStatus==1:
RAN.prematureExit = True
elif action == 'Build_Image':
CONTAINERS.BuildImage(HTML)
elif action == 'Build_Proxy':
......
- Build_Proxy
- Build_PhySim
- Run_PhySim
- Run_LDPCTest
- Run_NRulsimTest
- Build_eNB
- WaitEndBuild_eNB
- Initialize_eNB
......
......@@ -26,132 +26,125 @@
<htmlTabName>Test-ldpc-GPU</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>000001 000002 000003 000004 000005 000006 000007 000008 000009 000010 000011 000012 000013 000014 000015 000016 000017 000018 000019 000020 000021</TestCaseRequestedList>
<TestCaseRequestedList>000002 000003 000004 000005 000006 000007 000008 000009 000010 000011 000012 000013 000014 000015 000016 000017 000018 000019 000020 000021</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Build_PhySim</class>
<desc>Build for physical simulator</desc>
<physim_build_args>--phy_simulators --ninja --noavx512</physim_build_args>
<forced_workspace_cleanup>FALSE</forced_workspace_cleanup>
</testCase>
<testCase id="000002">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with CPU</desc>
<physim_run_args>-l 3872 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000003">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with GPU</desc>
<physim_run_args>-l 3872 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000004">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with CPU</desc>
<physim_run_args>-l 4224 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000005">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with GPU</desc>
<physim_run_args>-l 4224 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000006">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with CPU</desc>
<physim_run_args>-l 4576 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000007">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with GPU</desc>
<physim_run_args>-l 4576 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000008">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with CPU</desc>
<physim_run_args>-l 4928 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000009">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with GPU</desc>
<physim_run_args>-l 4928 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000010">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with CPU</desc>
<physim_run_args>-l 5280 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000011">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with GPU</desc>
<physim_run_args>-l 5280 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000012">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with CPU</desc>
<physim_run_args>-l 5632 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000013">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with GPU</desc>
<physim_run_args>-l 5632 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000014">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with CPU</desc>
<physim_run_args>-l 6336 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000015">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with GPU</desc>
<physim_run_args>-l 6336 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000016">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with CPU</desc>
<physim_run_args>-l 7040 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000017">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with GPU</desc>
<physim_run_args>-l 7040 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000018">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with CPU</desc>
<physim_run_args>-l 7744 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000019">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with GPU</desc>
<physim_run_args>-l 7744 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000020">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with CPU</desc>
<physim_run_args>-l 8448 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000021">
<class>Run_PhySim</class>
<class>Run_LDPCTest</class>
<desc>Run LDPC Test with GPU</desc>
<physim_run_args>-l 8448 -s10 -n100 -G 1</physim_run_args>
</testCase>
......
<!--
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
-->
<testCaseList>
<htmlTabRef>build-offload</htmlTabRef>
<htmlTabName>Build physical simulators</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>000001</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Build_PhySim</class>
<desc>Build physical simulators</desc>
<physim_build_args>--phy_simulators --ninja --noavx512</physim_build_args>
<forced_workspace_cleanup>FALSE</forced_workspace_cleanup>
</testCase>
</testCaseList>
<!--
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
-->
<testCaseList>
<htmlTabRef>test-t1-offload</htmlTabRef>
<htmlTabName>Test T1 Offload</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>000001 000002 000003 000004</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>Run_NRulsimTest</class>
<desc>Run T1 Offload nr_ulsim</desc>
<physim_run_args>-n2 -s30 -m9 -r50 -R106 -o</physim_run_args>
</testCase>
<testCase id="000002">
<class>Run_NRulsimTest</class>
<desc>Run T1 Offload nr_ulsim</desc>
<physim_run_args>-n2 -s30 -m9 -r106 -R106 -o</physim_run_args>
</testCase>
<testCase id="000003">
<class>Run_NRulsimTest</class>
<desc>Run T1 Offload nr_ulsim</desc>
<physim_run_args>-n2 -s30 -m16 -r106 -R106 -o</physim_run_args>
</testCase>
<testCase id="000004">
<class>Run_NRulsimTest</class>
<desc>Run T1 Offload nr_ulsim</desc>
<physim_run_args>-n2 -s30 -m9 -r273 -R273 -o</physim_run_args>
</testCase>
</testCaseList>
......@@ -828,6 +828,31 @@ TARGET_LINK_LIBRARIES(benetel_5g pthread dl rt m numa)
##########################################################
# LDPC offload library
##########################################################
# there is no generic way to test for T1 Offload, it simply comes with the
# shared object
if (EXISTS "/usr/local/lib64/librte_pmd_hpac_sdfec_pmd.so")
set(T1_OFFLOAD_FOUND TRUE)
else()
set(T1_OFFLOAD_FOUND FALSE)
endif()
if(T1_OFFLOAD_FOUND)
message(STATUS "T1 Offload support detected")
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib64/pkgconfig/")
pkg_search_module(LIBDPDK REQUIRED libdpdk=20.05.0)
add_library(ldpc_offload MODULE ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c)
set_target_properties(ldpc_offload PROPERTIES COMPILE_FLAGS "-DALLOW_EXPERIMENTAL_API")
target_compile_options(ldpc_offload PRIVATE ${LIBDPDK_CFLAGS})
target_link_libraries(ldpc_offload ${LIBDPDK_LDFLAGS} rte_pmd_hpac_sdfec_pmd "-Wl,-rpath /usr/local/lib64")
else()
message(STATUS "No T1 Offload support detected")
endif ()
##########################################################
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
Message("DEADLINE_SCHEDULER flag is ${DEADLINE_SCHEDULER}")
......@@ -2772,7 +2797,11 @@ target_link_libraries (nr-softmodem pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRA
target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES})
target_link_libraries (nr-softmodem ${T_LIB})
add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc)
if(T1_OFFLOAD_FOUND)
add_dependencies( nr-softmodem ldpc_offload)
endif ()
# nr-uesoftmodem is UE implementation
#######################################
......@@ -2818,6 +2847,7 @@ if (CUDA_FOUND)
add_dependencies( nr-uesoftmodem ldpc_cuda)
add_dependencies( nr-softmodem ldpc_cuda)
endif (CUDA_FOUND)
###################################"
# Addexecutables for tests
####################################
......@@ -2981,6 +3011,11 @@ add_executable(nr_ulsim
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
if(T1_OFFLOAD_FOUND)
add_dependencies( nr_ulsim ldpc_offload)
endif ()
target_link_libraries(nr_ulsim
-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_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl
......
......@@ -536,7 +536,9 @@ void init_eNB_afterRU(void) {
RC.nb_nr_inst = 1;
for (inst=0; inst<RC.nb_nr_inst; inst++) {
LOG_I(PHY,"RC.nb_nr_CC[inst:%d]:%p\n", inst, RC.gNB[inst]);
gNB = RC.gNB[inst];
gNB->ldpc_offload_flag = ldpc_offload_flag;
phy_init_nr_gNB(gNB,0,0);
......
......@@ -97,7 +97,7 @@
#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_LDPC_OFFLOAD "enable LDPC offload\n"
#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n"
#define CONFIG_HLP_FLOG "Enable online log \n"
......
......@@ -29,6 +29,7 @@
{"D" , CONFIG_HLP_DLBM_PHYTEST,0, u64ptr:&dlsch_slot_bitmap, defintval:0, TYPE_UINT64, 0}, \
{"U" , CONFIG_HLP_ULBM_PHYTEST,0, u64ptr:&ulsch_slot_bitmap, defintval:0, TYPE_UINT64, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"ldpc-offload-enable", CONFIG_HLP_LDPC_OFFLOAD, 0, iptr:&ldpc_offload_flag, defstrval:0, TYPE_INT, 0}, \
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, strptr:&uecap_file, defstrval:"./uecap.xml", TYPE_STRING, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
}
......@@ -44,6 +45,7 @@ extern uint32_t target_ul_bw;
extern uint64_t dlsch_slot_bitmap;
extern uint64_t ulsch_slot_bitmap;
extern char *uecap_file;
extern int ldpc_offload_flag;
// In nr-gnb.c
extern void init_gNB(int single_thread_flag,int wait_for_sync);
......
......@@ -447,7 +447,7 @@ int main( int argc, char **argv ) {
init_opt() ;
load_nrLDPClib(NULL);
if (ouput_vcd) {
vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd");
}
......
......@@ -46,7 +46,7 @@ static softmodem_params_t softmodem_params;
char *parallel_config=NULL;
char *worker_config=NULL;
int usrp_tx_thread = 0;
int ldpc_offload_flag=0;
uint8_t nfapi_mode=0;
static mapping softmodem_funcs[] = MAPPING_SOFTMODEM_FUNCTIONS;
......
......@@ -283,6 +283,7 @@ extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern int usrp_tx_thread;
extern uint16_t sl_ahead;
extern uint16_t sf_ahead;
extern int ldpc_offload_flag;
extern int oai_exit;
void tx_func(void *param);
......
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2017 Intel Corporation
*/
/*!\file nrLDPC_decoder_offload.c
* \brief Defines the LDPC decoder
* \author openairinterface
* \date 12-06-2021
* \version 1.0
* \note: based on testbbdev test_bbdev_perf.c functions. Harq buffer offset added.
* \mbuf and mempool allocated at the init step, LDPC parameters updated from OAI.
* \warning
*/
#include <stdint.h>
#include <immintrin.h>
#include "nrLDPCdecoder_defs.h"
#include "nrLDPC_types.h"
#include "nrLDPC_init.h"
#include "nrLDPC_mPass.h"
#include "nrLDPC_cnProc.h"
#include "nrLDPC_bnProc.h"
#include <common/utils/LOG/log.h>
#define NR_LDPC_ENABLE_PARITY_CHECK
#ifdef NR_LDPC_DEBUG_MODE
#include "nrLDPC_tools/nrLDPC_debug.h"
#endif
#include <getopt.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <rte_eal.h>
#include <rte_common.h>
#include <rte_string_fns.h>
#include <rte_cycles.h>
#include <rte_lcore.h>
#include "nrLDPC_offload.h"
#include <math.h>
#include <rte_dev.h>
#include <rte_launch.h>
#include <rte_bbdev.h>
#include <rte_malloc.h>
#include <rte_random.h>
#include <rte_hexdump.h>
#include <rte_interrupts.h>
#define GET_SOCKET(socket_id) (((socket_id) == SOCKET_ID_ANY) ? 0 : (socket_id))
#define MAX_QUEUES RTE_MAX_LCORE
#define TEST_REPETITIONS 1
#ifdef RTE_LIBRTE_PMD_BBDEV_FPGA_LTE_FEC
#include <fpga_lte_fec.h>
#define FPGA_LTE_PF_DRIVER_NAME ("intel_fpga_lte_fec_pf")
#define FPGA_LTE_VF_DRIVER_NAME ("intel_fpga_lte_fec_vf")
#define VF_UL_4G_QUEUE_VALUE 4
#define VF_DL_4G_QUEUE_VALUE 4
#define UL_4G_BANDWIDTH 3
#define DL_4G_BANDWIDTH 3
#define UL_4G_LOAD_BALANCE 128
#define DL_4G_LOAD_BALANCE 128
#define FLR_4G_TIMEOUT 610
#endif
#ifdef RTE_LIBRTE_PMD_BBDEV_FPGA_5GNR_FEC
#include <rte_pmd_fpga_5gnr_fec.h>
#define FPGA_5GNR_PF_DRIVER_NAME ("intel_fpga_5gnr_fec_pf")
#define FPGA_5GNR_VF_DRIVER_NAME ("intel_fpga_5gnr_fec_vf")
#define VF_UL_5G_QUEUE_VALUE 4
#define VF_DL_5G_QUEUE_VALUE 4
#define UL_5G_BANDWIDTH 3
#define DL_5G_BANDWIDTH 3
#define UL_5G_LOAD_BALANCE 128
#define DL_5G_LOAD_BALANCE 128
#define FLR_5G_TIMEOUT 610
#endif
#define OPS_CACHE_SIZE 256U
#define OPS_POOL_SIZE_MIN 511U /* 0.5K per queue */
#define SYNC_WAIT 0
#define SYNC_START 1
#define INVALID_OPAQUE -1
#define INVALID_QUEUE_ID -1
/* Increment for next code block in external HARQ memory */
#define HARQ_INCR 32768
/* Headroom for filler LLRs insertion in HARQ buffer */
#define FILLER_HEADROOM 1024
/* Switch between PMD and Interrupt for throughput TC */
static bool intr_enabled;
/* Represents tested active devices */
struct active_device {
const char *driver_name;
uint8_t dev_id;
uint16_t supported_ops;
uint16_t queue_ids[MAX_QUEUES];
uint16_t nb_queues;
struct rte_mempool *ops_mempool;
struct rte_mempool *in_mbuf_pool;
struct rte_mempool *hard_out_mbuf_pool;
struct rte_mempool *soft_out_mbuf_pool;
struct rte_mempool *harq_in_mbuf_pool;
struct rte_mempool *harq_out_mbuf_pool;
} active_devs[RTE_BBDEV_MAX_DEVS];
static uint8_t nb_active_devs;
/* Data buffers used by BBDEV ops */
struct test_buffers {
struct rte_bbdev_op_data *inputs;
struct rte_bbdev_op_data *hard_outputs;
struct rte_bbdev_op_data *soft_outputs;
struct rte_bbdev_op_data *harq_inputs;
struct rte_bbdev_op_data *harq_outputs;
};
/* Operation parameters specific for given test case */
struct test_op_params {
struct rte_mempool *mp;
struct rte_bbdev_dec_op *ref_dec_op;
struct rte_bbdev_enc_op *ref_enc_op;
uint16_t burst_sz;
uint16_t num_to_process;
uint16_t num_lcores;
int vector_mask;
rte_atomic16_t sync;
struct test_buffers q_bufs[RTE_MAX_NUMA_NODES][MAX_QUEUES];
};
/* Contains per lcore params */
struct thread_params {
uint8_t dev_id;
uint16_t queue_id;
uint32_t lcore_id;
uint64_t start_time;
double ops_per_sec;
double mbps;
uint8_t iter_count;
double iter_average;
double bler;
struct nrLDPCoffload_params *p_offloadParams;
int8_t* p_out;
uint8_t r;
uint8_t harq_pid;
uint8_t ulsch_id;
rte_atomic16_t nb_dequeued;
rte_atomic16_t processing_status;
rte_atomic16_t burst_sz;
struct test_op_params *op_params;
struct rte_bbdev_dec_op *dec_ops[MAX_BURST];
struct rte_bbdev_enc_op *enc_ops[MAX_BURST];
};
#ifdef RTE_BBDEV_OFFLOAD_COST
/* Stores time statistics */
struct test_time_stats {
/* Stores software enqueue total working time */
uint64_t enq_sw_total_time;
/* Stores minimum value of software enqueue working time */
uint64_t enq_sw_min_time;
/* Stores maximum value of software enqueue working time */
uint64_t enq_sw_max_time;
/* Stores turbo enqueue total working time */
uint64_t enq_acc_total_time;
/* Stores minimum value of accelerator enqueue working time */
uint64_t enq_acc_min_time;
/* Stores maximum value of accelerator enqueue working time */
uint64_t enq_acc_max_time;
/* Stores dequeue total working time */
uint64_t deq_total_time;
/* Stores minimum value of dequeue working time */
uint64_t deq_min_time;
/* Stores maximum value of dequeue working time */
uint64_t deq_max_time;
};
#endif
typedef int (test_case_function)(struct active_device *ad,
struct test_op_params *op_params);
static inline void
mbuf_reset(struct rte_mbuf *m)
{
m->pkt_len = 0;
do {
m->data_len = 0;
m = m->next;
} while (m != NULL);
}
/* Read flag value 0/1 from bitmap */
static inline bool
check_bit(uint32_t bitmap, uint32_t bitmask)
{
return bitmap & bitmask;
}
static inline void
set_avail_op(struct active_device *ad, enum rte_bbdev_op_type op_type)
{
ad->supported_ops |= (1 << op_type);
}
static inline bool
is_avail_op(struct active_device *ad, enum rte_bbdev_op_type op_type)
{
return ad->supported_ops & (1 << op_type);
}
static inline bool
flags_match(uint32_t flags_req, uint32_t flags_present)
{
return (flags_req & flags_present) == flags_req;
}
static int
check_dev_cap(const struct rte_bbdev_info *dev_info)
{
unsigned int i;
const struct rte_bbdev_op_cap *op_cap = dev_info->drv.capabilities;
for (i = 0; op_cap->type != RTE_BBDEV_OP_NONE; ++i, ++op_cap) {
if (op_cap->type != RTE_BBDEV_OP_LDPC_DEC)
continue;
if (op_cap->type == RTE_BBDEV_OP_LDPC_DEC) {
const struct rte_bbdev_op_cap_ldpc_dec *cap =
&op_cap->cap.ldpc_dec;
if (!flags_match(RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE,
cap->capability_flags)){
printf("Flag Mismatch\n");
return TEST_FAILED;
}
return TEST_SUCCESS;
}
}
return TEST_FAILED;
}
/* calculates optimal mempool size not smaller than the val */
static unsigned int
optimal_mempool_size(unsigned int val)
{
return rte_align32pow2(val + 1) - 1;
}
/* allocates mbuf mempool for inputs and outputs */
static struct rte_mempool *
create_mbuf_pool(uint32_t length, uint8_t dev_id,
int socket_id, unsigned int mbuf_pool_size,
const char *op_type_str)
{
uint32_t max_seg_sz = 0;
char pool_name[RTE_MEMPOOL_NAMESIZE];
/* find max input segment size */
//for (i = 0; i < entries->nb_segments; ++i)
if (length > max_seg_sz)
max_seg_sz = length;
snprintf(pool_name, sizeof(pool_name), "%s_pool_%u", op_type_str,
dev_id);
return rte_pktmbuf_pool_create(pool_name, mbuf_pool_size, 0, 0,
RTE_MAX(max_seg_sz + RTE_PKTMBUF_HEADROOM
+ FILLER_HEADROOM,
(unsigned int)RTE_MBUF_DEFAULT_BUF_SIZE), socket_id);
}
static int
create_mempools(struct active_device *ad, int socket_id,
enum rte_bbdev_op_type org_op_type, uint16_t num_ops, t_nrLDPCoffload_params *p_offloadParams)
{
struct rte_mempool *mp;
unsigned int ops_pool_size, mbuf_pool_size = 0;
char pool_name[RTE_MEMPOOL_NAMESIZE];
const char *op_type_str;
enum rte_bbdev_op_type op_type = org_op_type;
uint8_t nb_segments = 1;
uint32_t data_len;
/* allocate ops mempool */
ops_pool_size = optimal_mempool_size(RTE_MAX(
/* Ops used plus 1 reference op */
RTE_MAX((unsigned int)(ad->nb_queues * num_ops + 1),
/* Minimal cache size plus 1 reference op */
(unsigned int)(1.5 * rte_lcore_count() *
OPS_CACHE_SIZE + 1)),
OPS_POOL_SIZE_MIN));
if (org_op_type == RTE_BBDEV_OP_NONE)
op_type = RTE_BBDEV_OP_TURBO_ENC;
op_type_str = rte_bbdev_op_type_str(op_type);
TEST_ASSERT_NOT_NULL(op_type_str, "Invalid op type: %u", op_type);
snprintf(pool_name, sizeof(pool_name), "%s_pool_%u", op_type_str,
ad->dev_id);
mp = rte_bbdev_op_pool_create(pool_name, op_type,
ops_pool_size, OPS_CACHE_SIZE, socket_id);
TEST_ASSERT_NOT_NULL(mp,
"ERROR Failed to create %u items ops pool for dev %u on socket %u.",
ops_pool_size,
ad->dev_id,
socket_id);
ad->ops_mempool = mp;
/* Do not create inputs and outputs mbufs for BaseBand Null Device */
if (org_op_type == RTE_BBDEV_OP_NONE)
return TEST_SUCCESS;
data_len = (p_offloadParams->BG==1)?(22*p_offloadParams->Z):(10*p_offloadParams->Z);
/* Inputs */
if (nb_segments > 0) {
mbuf_pool_size = optimal_mempool_size(ops_pool_size *
nb_segments);
mp = create_mbuf_pool(p_offloadParams->E, ad->dev_id, socket_id,
mbuf_pool_size, "in");
TEST_ASSERT_NOT_NULL(mp,
"ERROR Failed to create %u items input pktmbuf pool for dev %u on socket %u.",
mbuf_pool_size,
ad->dev_id,
socket_id);
ad->in_mbuf_pool = mp;
}
/* Hard outputs */
if (nb_segments > 0) {
mbuf_pool_size = optimal_mempool_size(ops_pool_size *
nb_segments);
mp = create_mbuf_pool(data_len, ad->dev_id, socket_id,
mbuf_pool_size,
"hard_out");
TEST_ASSERT_NOT_NULL(mp,
"ERROR Failed to create %u items hard output pktmbuf pool for dev %u on socket %u.",
mbuf_pool_size,
ad->dev_id,
socket_id);
ad->hard_out_mbuf_pool = mp;
}
return TEST_SUCCESS;
}
static int
add_dev(uint8_t dev_id, struct rte_bbdev_info *info)
{
int ret;
unsigned int queue_id;
struct rte_bbdev_queue_conf qconf;
struct active_device *ad = &active_devs[nb_active_devs];
unsigned int nb_queues;
enum rte_bbdev_op_type op_type = RTE_BBDEV_OP_LDPC_DEC;
/* Configure fpga lte fec with PF & VF values
* if '-i' flag is set and using fpga device
*/
#ifdef RTE_LIBRTE_PMD_BBDEV_FPGA_LTE_FEC
if ((get_init_device() == true) &&
(!strcmp(info->drv.driver_name, FPGA_LTE_PF_DRIVER_NAME))) {
struct fpga_lte_fec_conf conf;
unsigned int i;
printf("Configure FPGA LTE FEC Driver %s with default values\n",
info->drv.driver_name);
/* clear default configuration before initialization */
memset(&conf, 0, sizeof(struct fpga_lte_fec_conf));
/* Set PF mode :
* true if PF is used for data plane
* false for VFs
*/
conf.pf_mode_en = true;
for (i = 0; i < FPGA_LTE_FEC_NUM_VFS; ++i) {
/* Number of UL queues per VF (fpga supports 8 VFs) */
conf.vf_ul_queues_number[i] = VF_UL_4G_QUEUE_VALUE;
/* Number of DL queues per VF (fpga supports 8 VFs) */
conf.vf_dl_queues_number[i] = VF_DL_4G_QUEUE_VALUE;
}
/* UL bandwidth. Needed for schedule algorithm */
conf.ul_bandwidth = UL_4G_BANDWIDTH;
/* DL bandwidth */
conf.dl_bandwidth = DL_4G_BANDWIDTH;
/* UL & DL load Balance Factor to 64 */
conf.ul_load_balance = UL_4G_LOAD_BALANCE;
conf.dl_load_balance = DL_4G_LOAD_BALANCE;
/**< FLR timeout value */
conf.flr_time_out = FLR_4G_TIMEOUT;
/* setup FPGA PF with configuration information */
ret = fpga_lte_fec_configure(info->dev_name, &conf);
TEST_ASSERT_SUCCESS(ret,
"Failed to configure 4G FPGA PF for bbdev %s",
info->dev_name);
}
#endif
#ifdef RTE_LIBRTE_PMD_BBDEV_FPGA_5GNR_FEC
if ((get_init_device() == true) &&
(!strcmp(info->drv.driver_name, FPGA_5GNR_PF_DRIVER_NAME))) {
struct fpga_5gnr_fec_conf conf;
unsigned int i;
printf("Configure FPGA 5GNR FEC Driver %s with default values\n",
info->drv.driver_name);
/* clear default configuration before initialization */
memset(&conf, 0, sizeof(struct fpga_5gnr_fec_conf));
/* Set PF mode :
* true if PF is used for data plane
* false for VFs
*/
conf.pf_mode_en = true;
for (i = 0; i < FPGA_5GNR_FEC_NUM_VFS; ++i) {
/* Number of UL queues per VF (fpga supports 8 VFs) */
conf.vf_ul_queues_number[i] = VF_UL_5G_QUEUE_VALUE;
/* Number of DL queues per VF (fpga supports 8 VFs) */
conf.vf_dl_queues_number[i] = VF_DL_5G_QUEUE_VALUE;
}
/* UL bandwidth. Needed for schedule algorithm */
conf.ul_bandwidth = UL_5G_BANDWIDTH;
/* DL bandwidth */
conf.dl_bandwidth = DL_5G_BANDWIDTH;
/* UL & DL load Balance Factor to 64 */
conf.ul_load_balance = UL_5G_LOAD_BALANCE;
conf.dl_load_balance = DL_5G_LOAD_BALANCE;
/**< FLR timeout value */
conf.flr_time_out = FLR_5G_TIMEOUT;
/* setup FPGA PF with configuration information */
ret = fpga_5gnr_fec_configure(info->dev_name, &conf);
TEST_ASSERT_SUCCESS(ret,
"Failed to configure 5G FPGA PF for bbdev %s",
info->dev_name);
}
#endif
nb_queues = RTE_MIN(rte_lcore_count(), info->drv.max_num_queues);
nb_queues = RTE_MIN(nb_queues, (unsigned int) MAX_QUEUES);
/* setup device */
ret = rte_bbdev_setup_queues(dev_id, nb_queues, info->socket_id);
if (ret < 0) {
printf("rte_bbdev_setup_queues(%u, %u, %d) ret %i\n",
dev_id, nb_queues, info->socket_id, ret);
return TEST_FAILED;
}
/* configure interrupts if needed */
if (intr_enabled) {
ret = rte_bbdev_intr_enable(dev_id);
if (ret < 0) {
printf("rte_bbdev_intr_enable(%u) ret %i\n", dev_id,
ret);
return TEST_FAILED;
}
}
/* setup device queues */
qconf.socket = info->socket_id;
qconf.queue_size = info->drv.default_queue_conf.queue_size;
qconf.priority = 0;
qconf.deferred_start = 0;
qconf.op_type = op_type;
for (queue_id = 0; queue_id < nb_queues; ++queue_id) {
ret = rte_bbdev_queue_configure(dev_id, queue_id, &qconf);
if (ret != 0) {
printf(
"Allocated all queues (id=%u) at prio%u on dev%u\n",
queue_id, qconf.priority, dev_id);
qconf.priority++;
ret = rte_bbdev_queue_configure(ad->dev_id, queue_id,
&qconf);
}
if (ret != 0) {
printf("All queues on dev %u allocated: %u\n",
dev_id, queue_id);
break;
}
ad->queue_ids[queue_id] = queue_id;
}
TEST_ASSERT(queue_id != 0,
"ERROR Failed to configure any queues on dev %u",
dev_id);
ad->nb_queues = queue_id;
set_avail_op(ad, op_type);
return TEST_SUCCESS;
}
static int
add_active_device(uint8_t dev_id, struct rte_bbdev_info *info)
{
int ret;
active_devs[nb_active_devs].driver_name = info->drv.driver_name;
active_devs[nb_active_devs].dev_id = dev_id;
ret = add_dev(dev_id, info);
if (ret == TEST_SUCCESS)
++nb_active_devs;
return ret;
}
static uint8_t
populate_active_devices(void)
{
int ret;
uint8_t dev_id;
uint8_t nb_devs_added = 0;
struct rte_bbdev_info info;
RTE_BBDEV_FOREACH(dev_id) {
rte_bbdev_info_get(dev_id, &info);
if (check_dev_cap(&info)) {
printf(
"Device %d (%s) does not support specified capabilities\n",
dev_id, info.dev_name);
continue;
}
ret = add_active_device(dev_id, &info);
if (ret != 0) {
printf("Adding active bbdev %s skipped\n",
info.dev_name);
continue;
}
nb_devs_added++;
}
return nb_devs_added;
}
static int
device_setup(void)
{
if (populate_active_devices() == 0) {
printf("No suitable devices found!\n");
return TEST_SKIPPED;
}
return TEST_SUCCESS;
}
static void
testsuite_teardown(void)
{
uint8_t dev_id;
/* Unconfigure devices */
RTE_BBDEV_FOREACH(dev_id)
rte_bbdev_close(dev_id);
/* Clear active devices structs. */
memset(active_devs, 0, sizeof(active_devs));
nb_active_devs = 0;
/* Disable interrupts */
intr_enabled = false;
}
static int
ut_setup(void)
{
uint8_t i, dev_id;
for (i = 0; i < nb_active_devs; i++) {
dev_id = active_devs[i].dev_id;
/* reset bbdev stats */
TEST_ASSERT_SUCCESS(rte_bbdev_stats_reset(dev_id),
"Failed to reset stats of bbdev %u", dev_id);
/* start the device */
TEST_ASSERT_SUCCESS(rte_bbdev_start(dev_id),
"Failed to start bbdev %u", dev_id);
}
return TEST_SUCCESS;
}
static void
ut_teardown(void)
{
uint8_t i, dev_id;
struct rte_bbdev_stats stats;
for (i = 0; i < nb_active_devs; i++) {
dev_id = active_devs[i].dev_id;
/* read stats and print */
rte_bbdev_stats_get(dev_id, &stats);
/* Stop the device */
rte_bbdev_stop(dev_id);
}
}
static int
init_op_data_objs(struct rte_bbdev_op_data *bufs,
int8_t* p_llr, uint32_t data_len,
struct rte_mbuf *m_head,
struct rte_mempool *mbuf_pool, const uint16_t n,
enum op_data_type op_type, uint16_t min_alignment)
{
int ret;
unsigned int i, j;
bool large_input = false;
uint8_t nb_segments = 1;
//uint64_t start_time=rte_rdtsc_precise();
//uint64_t start_time1; //=rte_rdtsc_precise();
//uint64_t total_time=0, total_time1=0;
for (i = 0; i < n; ++i) {
char *data;
if (data_len > RTE_BBDEV_LDPC_E_MAX_MBUF) {
/*
* Special case when DPDK mbuf cannot handle
* the required input size
*/
printf("Warning: Larger input size than DPDK mbuf %d\n",
data_len);
large_input = true;
}
bufs[i].data = m_head;
bufs[i].offset = 0;
bufs[i].length = 0;
if ((op_type == DATA_INPUT) || (op_type == DATA_HARQ_INPUT)) {
if ((op_type == DATA_INPUT) && large_input) {
/* Allocate a fake overused mbuf */
data = rte_malloc(NULL, data_len, 0);
memcpy(data, p_llr, data_len);
m_head->buf_addr = data;
m_head->buf_iova = rte_malloc_virt2iova(data);
m_head->data_off = 0;
m_head->data_len = data_len;
} else {
rte_pktmbuf_reset(m_head);
data = rte_pktmbuf_append(m_head, data_len);
/*total_time = rte_rdtsc_precise() - start_time;
if (total_time > 10*3000)
LOG_E(PHY," init op first: %u\n",(uint) (total_time/3000));
start_time1 = rte_rdtsc_precise();
*/
TEST_ASSERT_NOT_NULL(data,
"Couldn't append %u bytes to mbuf from %d data type mbuf pool",
data_len, op_type);
TEST_ASSERT(data == RTE_PTR_ALIGN(
data, min_alignment),
"Data addr in mbuf (%p) is not aligned to device min alignment (%u)",
data, min_alignment);
rte_memcpy(data, p_llr, data_len);
/*total_time1 = rte_rdtsc_precise() - start_time;
if (total_time1 > 10*3000)
LOG_E(PHY,"init op second: %u\n",(uint) (total_time1/3000));*/
}
bufs[i].length += data_len;
for (j = 1; j < nb_segments; ++j) {
struct rte_mbuf *m_tail =
rte_pktmbuf_alloc(mbuf_pool);
TEST_ASSERT_NOT_NULL(m_tail,
"Not enough mbufs in %d data type mbuf pool (needed %u, available %u)",
op_type,
n * nb_segments,
mbuf_pool->size);
//seg += 1;
data = rte_pktmbuf_append(m_tail, data_len);
TEST_ASSERT_NOT_NULL(data,
"Couldn't append %u bytes to mbuf from %d data type mbuf pool",
data_len, op_type);
TEST_ASSERT(data == RTE_PTR_ALIGN(data,
min_alignment),
"Data addr in mbuf (%p) is not aligned to device min alignment (%u)",
data, min_alignment);
rte_memcpy(data, p_llr, data_len);
bufs[i].length += data_len;
ret = rte_pktmbuf_chain(m_head, m_tail);
TEST_ASSERT_SUCCESS(ret,
"Couldn't chain mbufs from %d data type mbuf pool",
op_type);
}
} else {
/* allocate chained-mbuf for output buffer */
/*for (j = 1; j < nb_segments; ++j) {
struct rte_mbuf *m_tail =
rte_pktmbuf_alloc(mbuf_pool);
TEST_ASSERT_NOT_NULL(m_tail,
"Not enough mbufs in %d data type mbuf pool (needed %u, available %u)",
op_type,
n * nb_segments,
mbuf_pool->size);
ret = rte_pktmbuf_chain(m_head, m_tail);
TEST_ASSERT_SUCCESS(ret,
"Couldn't chain mbufs from %d data type mbuf pool",
op_type);
}*/
}
}
return 0;
}
static int
allocate_buffers_on_socket(struct rte_bbdev_op_data **buffers, const int len,
const int socket)
{
int i;
*buffers = rte_zmalloc_socket(NULL, len, 0, socket);
if (*buffers == NULL) {
printf("WARNING: Failed to allocate op_data on socket %d\n",
socket);
/* try to allocate memory on other detected sockets */
for (i = 0; i < socket; i++) {
*buffers = rte_zmalloc_socket(NULL, len, 0, i);
if (*buffers != NULL)
break;
}
}
return (*buffers == NULL) ? TEST_FAILED : TEST_SUCCESS;
}
static void
free_buffers(struct active_device *ad, struct test_op_params *op_params)
{
unsigned int i, j;
rte_mempool_free(ad->ops_mempool);
rte_mempool_free(ad->in_mbuf_pool);
rte_mempool_free(ad->hard_out_mbuf_pool);
rte_mempool_free(ad->soft_out_mbuf_pool);
rte_mempool_free(ad->harq_in_mbuf_pool);
rte_mempool_free(ad->harq_out_mbuf_pool);
for (i = 0; i < rte_lcore_count(); ++i) {
for (j = 0; j < RTE_MAX_NUMA_NODES; ++j) {
rte_free(op_params->q_bufs[j][i].inputs);
rte_free(op_params->q_bufs[j][i].hard_outputs);
rte_free(op_params->q_bufs[j][i].soft_outputs);
rte_free(op_params->q_bufs[j][i].harq_inputs);
rte_free(op_params->q_bufs[j][i].harq_outputs);
}
}
}
static inline double
maxstar(double A, double B)
{
if (fabs(A - B) > 5)
return RTE_MAX(A, B);
else
return RTE_MAX(A, B) + log1p(exp(-fabs(A - B)));
}
static void
set_ldpc_dec_op(struct rte_bbdev_dec_op **ops, unsigned int n,
unsigned int start_idx,
struct rte_bbdev_op_data *inputs,
struct rte_bbdev_op_data *hard_outputs,
struct rte_bbdev_op_data *soft_outputs,
struct rte_bbdev_op_data *harq_inputs,
struct rte_bbdev_op_data *harq_outputs,
struct rte_bbdev_dec_op *ref_op,
uint8_t r,
uint8_t harq_pid,
uint8_t ulsch_id,
t_nrLDPCoffload_params *p_offloadParams)
{
unsigned int i;
//struct rte_bbdev_op_ldpc_dec *ldpc_dec = &ref_op->ldpc_dec;
for (i = 0; i < n; ++i) {
/* if (ldpc_dec->code_block_mode == 0) {
ops[i]->ldpc_dec.tb_params.ea =
ldpc_dec->tb_params.ea;
ops[i]->ldpc_dec.tb_params.eb =
ldpc_dec->tb_params.eb;
ops[i]->ldpc_dec.tb_params.c =
ldpc_dec->tb_params.c;
ops[i]->ldpc_dec.tb_params.cab =
ldpc_dec->tb_params.cab;
ops[i]->ldpc_dec.tb_params.r =
ldpc_dec->tb_params.r;
printf("code block ea %d eb %d c %d cab %d r %d\n",ldpc_dec->tb_params.ea,ldpc_dec->tb_params.eb,ldpc_dec->tb_params.c, ldpc_dec->tb_params.cab, ldpc_dec->tb_params.r);
} else { */
ops[i]->ldpc_dec.cb_params.e = p_offloadParams->E;
//}
ops[i]->ldpc_dec.basegraph = p_offloadParams->BG;
ops[i]->ldpc_dec.z_c = p_offloadParams->Z;
ops[i]->ldpc_dec.q_m = p_offloadParams->Qm;
ops[i]->ldpc_dec.n_filler = p_offloadParams->F;
ops[i]->ldpc_dec.n_cb = p_offloadParams->n_cb;
ops[i]->ldpc_dec.iter_max = 20;
ops[i]->ldpc_dec.rv_index = p_offloadParams->rv;
ops[i]->ldpc_dec.op_flags = RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE|RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE|RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE; //|RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP;
ops[i]->ldpc_dec.code_block_mode = 1; //ldpc_dec->code_block_mode;
//printf("set ldpc ulsch_id %d\n",ulsch_id);
ops[i]->ldpc_dec.harq_combined_input.offset = ulsch_id*(32*1024*1024)+harq_pid*(2*1024*1024)+r*(1024*32);
ops[i]->ldpc_dec.harq_combined_output.offset = ulsch_id*(32*1024*1024)+harq_pid*(2*1024*1024)+r*(1024*32);
if (hard_outputs != NULL)
ops[i]->ldpc_dec.hard_output =
hard_outputs[start_idx + i];
if (inputs != NULL)
ops[i]->ldpc_dec.input =
inputs[start_idx + i];
if (soft_outputs != NULL)
ops[i]->ldpc_dec.soft_output =
soft_outputs[start_idx + i];
if (harq_inputs != NULL)
ops[i]->ldpc_dec.harq_combined_input =
harq_inputs[start_idx + i];
if (harq_outputs != NULL)
ops[i]->ldpc_dec.harq_combined_output =
harq_outputs[start_idx + i];
}
}
/*static int
check_dec_status_and_ordering(struct rte_bbdev_dec_op *op,
unsigned int order_idx, const int expected_status)
{
int status = op->status;
if (get_iter_max() >= 10) {
if (!(expected_status & (1 << RTE_BBDEV_SYNDROME_ERROR)) &&
(status & (1 << RTE_BBDEV_SYNDROME_ERROR))) {
printf("WARNING: Ignore Syndrome Check mismatch\n");
status -= (1 << RTE_BBDEV_SYNDROME_ERROR);
}
if ((expected_status & (1 << RTE_BBDEV_SYNDROME_ERROR)) &&
!(status & (1 << RTE_BBDEV_SYNDROME_ERROR))) {
printf("WARNING: Ignore Syndrome Check mismatch\n");
status += (1 << RTE_BBDEV_SYNDROME_ERROR);
}
}
TEST_ASSERT(status == expected_status,
"op_status (%d) != expected_status (%d)",
op->status, expected_status);
TEST_ASSERT((void *)(uintptr_t)order_idx == op->opaque_data,
"Ordering error, expected %p, got %p",
(void *)(uintptr_t)order_idx, op->opaque_data);
return TEST_SUCCESS;
}
static int
check_enc_status_and_ordering(struct rte_bbdev_enc_op *op,
unsigned int order_idx, const int expected_status)
{
TEST_ASSERT(op->status == expected_status,
"op_status (%d) != expected_status (%d)",
op->status, expected_status);
if (op->opaque_data != (void *)(uintptr_t)INVALID_OPAQUE)
TEST_ASSERT((void *)(uintptr_t)order_idx == op->opaque_data,
"Ordering error, expected %p, got %p",
(void *)(uintptr_t)order_idx, op->opaque_data);
return TEST_SUCCESS;
}
*/
static int
retrieve_ldpc_dec_op(struct rte_bbdev_dec_op **ops, const uint16_t n,
struct rte_bbdev_dec_op *ref_op, const int vector_mask,
int8_t* p_out)
{
unsigned int i;
//int ret;
struct rte_bbdev_op_ldpc_dec *ops_td;
struct rte_bbdev_op_data *hard_output;
//struct rte_bbdev_op_ldpc_dec *ref_td = &ref_op->ldpc_dec;
struct rte_mbuf *m;
char *data;
for (i = 0; i < n; ++i) {
ops_td = &ops[i]->ldpc_dec;
hard_output = &ops_td->hard_output;
m = hard_output->data;
/* ret = check_dec_status_and_ordering(ops[i], i, ref_op->status);
TEST_ASSERT_SUCCESS(ret,
"Checking status and ordering for decoder failed");
if (vector_mask & TEST_BBDEV_VF_EXPECTED_ITER_COUNT)
TEST_ASSERT(ops_td->iter_count <= ref_td->iter_count,
"Returned iter_count (%d) > expected iter_count (%d)",
ops_td->iter_count, ref_td->iter_count);
*/
uint16_t offset = hard_output->offset;
uint16_t data_len = rte_pktmbuf_data_len(m) - offset;
data = m->buf_addr;
memcpy(p_out, data+m->data_off, data_len);
}
return TEST_SUCCESS;
}
/*static int
validate_ldpc_enc_op(struct rte_bbdev_enc_op **ops, const uint16_t n,
struct rte_bbdev_enc_op *ref_op)
{
unsigned int i;
int ret;
struct op_data_entries *hard_data_orig =
&test_vector.entries[DATA_HARD_OUTPUT];
for (i = 0; i < n; ++i) {
ret = check_enc_status_and_ordering(ops[i], i, ref_op->status);
TEST_ASSERT_SUCCESS(ret,
"Checking status and ordering for encoder failed");
TEST_ASSERT_SUCCESS(validate_op_chain(
&ops[i]->ldpc_enc.output,
hard_data_orig),
"Output buffers (CB=%u) are not equal",
i);
}
return TEST_SUCCESS;
}
*/
static void
create_reference_ldpc_dec_op(struct rte_bbdev_dec_op *op, t_nrLDPCoffload_params *p_offloadParams)
{
// unsigned int i;
//for (i = 0; i < entry->nb_segments; ++i)
op->ldpc_dec.input.length = p_offloadParams->E;
op->ldpc_dec.basegraph = p_offloadParams->BG;
op->ldpc_dec.z_c = p_offloadParams->Z;
op->ldpc_dec.n_filler = p_offloadParams->F;
op->ldpc_dec.code_block_mode = 1;
op->ldpc_dec.op_flags = RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE|RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE|RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE|RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP;
}
/*
static uint32_t
calc_ldpc_dec_TB_size(struct rte_bbdev_dec_op *op)
{
uint8_t i;
uint32_t c, r, tb_size = 0;
uint16_t sys_cols = (op->ldpc_dec.basegraph == 1) ? 22 : 10;
if (op->ldpc_dec.code_block_mode) {
tb_size = sys_cols * op->ldpc_dec.z_c - op->ldpc_dec.n_filler;
//printf("calc tb sys cols %d tb_size %d\n",sys_cols,tb_size);
} else {
c = op->ldpc_dec.tb_params.c;
r = op->ldpc_dec.tb_params.r;
for (i = 0; i < c-r; i++)
tb_size += sys_cols * op->ldpc_dec.z_c
- op->ldpc_dec.n_filler;
printf("calc tb c %d r %d sys cols %d tb_size %d\n",c,r,sys_cols,tb_size);
}
return tb_size;
}
*/
static int
init_test_op_params(struct test_op_params *op_params,
enum rte_bbdev_op_type op_type, const int expected_status,
const int vector_mask, struct rte_mempool *ops_mp,
uint16_t burst_sz, uint16_t num_to_process, uint16_t num_lcores)
{
int ret = 0;
if (op_type == RTE_BBDEV_OP_TURBO_DEC ||
op_type == RTE_BBDEV_OP_LDPC_DEC)
ret = rte_bbdev_dec_op_alloc_bulk(ops_mp,
&op_params->ref_dec_op, 1);
else
ret = rte_bbdev_enc_op_alloc_bulk(ops_mp,
&op_params->ref_enc_op, 1);
TEST_ASSERT_SUCCESS(ret, "rte_bbdev_op_alloc_bulk() failed");
op_params->mp = ops_mp;
op_params->burst_sz = burst_sz;
op_params->num_to_process = num_to_process;
op_params->num_lcores = num_lcores;
op_params->vector_mask = vector_mask;
if (op_type == RTE_BBDEV_OP_TURBO_DEC ||
op_type == RTE_BBDEV_OP_LDPC_DEC)
op_params->ref_dec_op->status = expected_status;
else if (op_type == RTE_BBDEV_OP_TURBO_ENC
|| op_type == RTE_BBDEV_OP_LDPC_ENC)
op_params->ref_enc_op->status = expected_status;
return 0;
}
static int
pmd_lcore_ldpc_dec(void *arg)
{
struct thread_params *tp = arg;
uint16_t enq, deq;
//uint64_t total_time = 0, start_time;
const uint16_t queue_id = tp->queue_id;
const uint16_t burst_sz = tp->op_params->burst_sz;
const uint16_t num_ops = tp->op_params->num_to_process;
struct rte_bbdev_dec_op *ops_enq[num_ops];
struct rte_bbdev_dec_op *ops_deq[num_ops];
struct rte_bbdev_dec_op *ref_op = tp->op_params->ref_dec_op;
uint8_t r= tp->r;
uint8_t harq_pid = tp->harq_pid;
uint8_t ulsch_id = tp->ulsch_id;
struct test_buffers *bufs = NULL;
int i, j, ret;
struct rte_bbdev_info info;
uint16_t num_to_enq;
int8_t *p_out = tp->p_out;
t_nrLDPCoffload_params *p_offloadParams = tp->p_offloadParams;
//struct rte_bbdev_op_data *hard_output;
//bool extDdr = check_bit(ldpc_cap_flags,
// RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE);
//start_time = rte_rdtsc_precise();
bool loopback = check_bit(ref_op->ldpc_dec.op_flags,
RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK);
bool hc_out = check_bit(ref_op->ldpc_dec.op_flags,
RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE);
TEST_ASSERT_SUCCESS((burst_sz > MAX_BURST),
"BURST_SIZE should be <= %u", MAX_BURST);
rte_bbdev_info_get(tp->dev_id, &info);
TEST_ASSERT_SUCCESS((num_ops > info.drv.queue_size_lim),
"NUM_OPS cannot exceed %u for this device",
info.drv.queue_size_lim);
bufs = &tp->op_params->q_bufs[GET_SOCKET(info.socket_id)][queue_id];
while (rte_atomic16_read(&tp->op_params->sync) == SYNC_WAIT)
rte_pause();
ret = rte_bbdev_dec_op_alloc_bulk(tp->op_params->mp, ops_enq, num_ops);
TEST_ASSERT_SUCCESS(ret, "Allocation failed for %d ops", num_ops);
/* For throughput tests we need to disable early termination */
if (check_bit(ref_op->ldpc_dec.op_flags,
RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE))
ref_op->ldpc_dec.op_flags -=
RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE;
ref_op->ldpc_dec.iter_max = get_iter_max();
ref_op->ldpc_dec.iter_count = ref_op->ldpc_dec.iter_max;
set_ldpc_dec_op(ops_enq, num_ops, 0, bufs->inputs,
bufs->hard_outputs, bufs->soft_outputs,
bufs->harq_inputs, bufs->harq_outputs, ref_op, r, harq_pid, ulsch_id, p_offloadParams);
/* Set counter to validate the ordering */
for (j = 0; j < num_ops; ++j)
ops_enq[j]->opaque_data = (void *)(uintptr_t)j;
for (i = 0; i < TEST_REPETITIONS; ++i) {
for (j = 0; j < num_ops; ++j) {
if (!loopback)
mbuf_reset(
ops_enq[j]->ldpc_dec.hard_output.data);
if (hc_out || loopback)
mbuf_reset(
ops_enq[j]->ldpc_dec.harq_combined_output.data);
}
// start_time = rte_rdtsc_precise();
for (enq = 0, deq = 0; enq < num_ops;) {
num_to_enq = burst_sz;
if (unlikely(num_ops - enq < num_to_enq))
num_to_enq = num_ops - enq;
enq += rte_bbdev_enqueue_ldpc_dec_ops(tp->dev_id,
queue_id, &ops_enq[enq], num_to_enq);
deq += rte_bbdev_dequeue_ldpc_dec_ops(tp->dev_id,
queue_id, &ops_deq[deq], enq - deq);
//printf("enq %d, deq %d\n",enq,deq);
}
/* dequeue the remaining */
//int trials=0;
while (deq < enq) {
deq += rte_bbdev_dequeue_ldpc_dec_ops(tp->dev_id,
queue_id, &ops_deq[deq], enq - deq);
/*usleep(10);
trials++;
if (trials>=100) {
printf("aborting decoding after 100 dequeue tries\n");
break;
}*/
}
//total_time += rte_rdtsc_precise() - start_time;
}
//total_time = rte_rdtsc_precise() - start_time;
if (deq==enq) {
tp->iter_count = 0;
/* get the max of iter_count for all dequeued ops */
for (i = 0; i < num_ops; ++i) {
tp->iter_count = RTE_MAX(ops_enq[i]->ldpc_dec.iter_count,
tp->iter_count);
}
ret = retrieve_ldpc_dec_op(ops_deq, num_ops, ref_op,
tp->op_params->vector_mask, p_out);
TEST_ASSERT_SUCCESS(ret, "Validation failed!");
}
else {
ret = TEST_FAILED;
}
rte_bbdev_dec_op_free_bulk(ops_enq, num_ops);
/*total_time = rte_rdtsc_precise() - start_time;
if (total_time > 100*3000)
LOG_E(PHY," pmd lcore: %u\n",(uint) (total_time/3000));
double tb_len_bits = calc_ldpc_dec_TB_size(ref_op);
tp->ops_per_sec = ((double)total_time / (double)rte_get_tsc_hz());
//tp->ops_per_sec = ((double)num_ops * TEST_REPETITIONS) /
// ((double)total_time / (double)rte_get_tsc_hz());
tp->mbps = (((double)(num_ops * TEST_REPETITIONS * tb_len_bits)) /
1000000.0) / ((double)total_time /
(double)rte_get_tsc_hz());
*/
return ret;
}
/* Aggregate the performance results over the number of cores used */
static void
print_dec_throughput(struct thread_params *t_params, unsigned int used_cores)
{
unsigned int core_idx = 0;
double total_mops = 0, total_mbps = 0;
uint8_t iter_count = 0;
for (core_idx = 0; core_idx < used_cores; core_idx++) {
printf(
"Throughput for core (%u): %.8lg Ops/s, %.8lg Mbps @ max %u iterations\n",
t_params[core_idx].lcore_id,
t_params[core_idx].ops_per_sec,
t_params[core_idx].mbps,
t_params[core_idx].iter_count);
total_mops += t_params[core_idx].ops_per_sec;
total_mbps += t_params[core_idx].mbps;
iter_count = RTE_MAX(iter_count,
t_params[core_idx].iter_count);
}
printf(
"\nTotal throughput for %u cores: %.8lg MOPS, %.8lg Mbps @ max %u iterations\n",
used_cores, total_mops, total_mbps, iter_count);
}
/*
* Test function that determines how long an enqueue + dequeue of a burst
* takes on available lcores.
*/
int
start_pmd_dec(struct active_device *ad,
struct test_op_params *op_params,
struct thread_params *t_params,
t_nrLDPCoffload_params *p_offloadParams,
uint8_t r,
uint8_t harq_pid,
uint8_t ulsch_id,
int8_t* p_out)
{
int ret;
unsigned int lcore_id, used_cores = 0;
struct thread_params *tp;
//struct rte_bbdev_info info;
uint16_t num_lcores;
//uint64_t start_time, start_time1 ; //= rte_rdtsc_precise();
//uint64_t total_time=0, total_time1=0;
//rte_bbdev_info_get(ad->dev_id, &info);
//start_time = rte_rdtsc_precise();
/*printf("+ ------------------------------------------------------- +\n");
printf("== start pmd dec\ndev: %s, nb_queues: %u, burst size: %u, num ops: %u, num_lcores: %u, itr mode: %s, GHz: %lg\n",
info.dev_name, ad->nb_queues, op_params->burst_sz,
op_params->num_to_process, op_params->num_lcores,
intr_enabled ? "Interrupt mode" : "PMD mode",
(double)rte_get_tsc_hz() / 1000000000.0);
*/
/* Set number of lcores */
num_lcores = (ad->nb_queues < (op_params->num_lcores))
? ad->nb_queues
: op_params->num_lcores;
/* Allocate memory for thread parameters structure */
/*t_params = rte_zmalloc(NULL, num_lcores * sizeof(struct thread_params),
RTE_CACHE_LINE_SIZE);
TEST_ASSERT_NOT_NULL(t_params, "Failed to alloc %zuB for t_params",
RTE_ALIGN(sizeof(struct thread_params) * num_lcores,
RTE_CACHE_LINE_SIZE));
*/
//total_time = rte_rdtsc_precise() - start_time;
rte_atomic16_set(&op_params->sync, SYNC_WAIT);
/* Master core is set at first entry */
t_params[0].dev_id = ad->dev_id;
t_params[0].lcore_id = rte_lcore_id();
t_params[0].op_params = op_params;
t_params[0].queue_id = ad->queue_ids[used_cores++];
t_params[0].iter_count = 0;
t_params[0].p_out = p_out;
t_params[0].p_offloadParams = p_offloadParams;
t_params[0].r = r;
t_params[0].harq_pid = harq_pid;
t_params[0].ulsch_id = ulsch_id;
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (used_cores >= num_lcores)
break;
t_params[used_cores].dev_id = ad->dev_id;
t_params[used_cores].lcore_id = lcore_id;
t_params[used_cores].op_params = op_params;
t_params[used_cores].queue_id = ad->queue_ids[used_cores];
t_params[used_cores].iter_count = 0;
t_params[used_cores].p_out = p_out;
t_params[used_cores].p_offloadParams = p_offloadParams;
t_params[used_cores].r = r;
t_params[used_cores].harq_pid = harq_pid;
t_params[used_cores].ulsch_id = ulsch_id;
rte_eal_remote_launch(pmd_lcore_ldpc_dec,
&t_params[used_cores++], lcore_id);
}
rte_atomic16_set(&op_params->sync, SYNC_START);
//total_time = rte_rdtsc_precise() - start_time;
//if (total_time > 100*3000)
//LOG_E(PHY," start pmd 1st: %u\n",(uint) (total_time/3000));
ret = pmd_lcore_ldpc_dec(&t_params[0]);
//start_time1 = rte_rdtsc_precise();
/* Master core is always used */
//for (used_cores = 1; used_cores < num_lcores; used_cores++)
// ret |= rte_eal_wait_lcore(t_params[used_cores].lcore_id);
/* Return if test failed */
if (ret) {
rte_free(t_params);
return ret;
}
/* Print throughput if interrupts are disabled and test passed */
if (!intr_enabled) {
///print_dec_throughput(t_params, num_lcores);
//rte_free(t_params);
// total_time1 = rte_rdtsc_precise() - start_time1;
// if (total_time1 > 10*3000)
// LOG_E(PHY," start pmd 2nd: %u\n",(uint) (total_time1/3000));
// rte_free(t_params);
return ret;
}
/* In interrupt TC we need to wait for the interrupt callback to deqeue
* all pending operations. Skip waiting for queues which reported an
* error using processing_status variable.
* Wait for master lcore operations.
*/
tp = &t_params[0];
while ((rte_atomic16_read(&tp->nb_dequeued) <
op_params->num_to_process) &&
(rte_atomic16_read(&tp->processing_status) !=
TEST_FAILED))
rte_pause();
tp->ops_per_sec /= TEST_REPETITIONS;
tp->mbps /= TEST_REPETITIONS;
ret |= (int)rte_atomic16_read(&tp->processing_status);
for (used_cores = 1; used_cores < num_lcores; used_cores++) {
tp = &t_params[used_cores];
while ((rte_atomic16_read(&tp->nb_dequeued) <
op_params->num_to_process) &&
(rte_atomic16_read(&tp->processing_status) !=
TEST_FAILED))
rte_pause();
tp->ops_per_sec /= TEST_REPETITIONS;
tp->mbps /= TEST_REPETITIONS;
ret |= (int)rte_atomic16_read(&tp->processing_status);
}
/* Print throughput if test passed */
if (!ret) {
print_dec_throughput(t_params, num_lcores);
}
rte_free(t_params);
return ret;
}
/* Declare structure for command line test parameters and options */
static struct test_params {
struct test_command *test_to_run[8];
unsigned int num_tests;
unsigned int num_ops;
unsigned int burst_sz;
unsigned int num_lcores;
double snr;
unsigned int iter_max;
char test_vector_filename[PATH_MAX];
bool init_device;
} test_params;
unsigned int
get_num_ops(void)
{
return test_params.num_ops;
}
unsigned int
get_burst_sz(void)
{
return test_params.burst_sz;
}
unsigned int
get_num_lcores(void)
{
return test_params.num_lcores;
}
double
get_snr(void)
{
return test_params.snr;
}
unsigned int
get_iter_max(void)
{
return test_params.iter_max;
}
bool
get_init_device(void)
{
return test_params.init_device;
}
struct test_op_params op_params_e;
struct test_op_params *op_params = &op_params_e;
struct rte_mbuf *m_head[DATA_NUM_TYPES];
struct thread_params *t_params;
int32_t nrLDPC_decod_offload(t_nrLDPC_dec_params* p_decParams, uint8_t harq_pid, uint8_t ulsch_id, uint8_t C, uint8_t rv, uint16_t F,
uint32_t E, uint8_t Qm, int8_t* p_llr, int8_t* p_out, uint8_t mode)
{
t_nrLDPCoffload_params offloadParams;
t_nrLDPCoffload_params* p_offloadParams = &offloadParams;
uint64_t start=rte_rdtsc_precise();
/*uint64_t start_time;//=rte_rdtsc_precise();
uint64_t start_time1; //=rte_rdtsc_precise();
uint64_t total_time=0, total_time1=0;*/
uint32_t numIter = 0;
int ret;
/*uint64_t start_time_init;
uint64_t total_time_init=0;*/
/*
int argc_re=2;
char *argv_re[2];
argv_re[0] = "/home/eurecom/hongzhi/dpdk-20.05orig/build/app/testbbdev";
argv_re[1] = "--";
*/
int argc_re=7;
char *argv_re[7];
argv_re[0] = "/home/eurecom/hongzhi/dpdk-20.05orig/build/app/testbbdev";
argv_re[1] = "-l";
argv_re[2] = "31";
argv_re[3] = "-w";
argv_re[4] = "81:00.0";
argv_re[5] = "--file-prefix=b6";
argv_re[6] = "--";
test_params.num_ops=1;
test_params.burst_sz=1;
test_params.num_lcores=1;
test_params.num_tests = 1;
struct active_device *ad;
ad = &active_devs[0];
int socket_id=0;
int i,f_ret;
struct rte_bbdev_info info;
enum rte_bbdev_op_type op_type = RTE_BBDEV_OP_LDPC_DEC;
switch (mode) {
case 0:
ret = rte_eal_init(argc_re, argv_re);
if (ret<0) {
printf("Could not init EAL, ret %d\n",ret);
return(-1);
}
ret = device_setup();
if (ret != TEST_SUCCESS) {
printf("Couldn't setup device");
return(-1);
}
ret=ut_setup();
if (ret != TEST_SUCCESS) {
printf("Couldn't setup ut");
return(-1);
}
p_offloadParams->E = E;
p_offloadParams->n_cb = (p_decParams->BG==1)?(66*p_decParams->Z):(50*p_decParams->Z);
p_offloadParams->BG = p_decParams->BG;
p_offloadParams->Z = p_decParams->Z;
p_offloadParams->rv = rv;
p_offloadParams->F = F;
p_offloadParams->Qm = Qm;
op_params = rte_zmalloc(NULL,
sizeof(struct test_op_params), RTE_CACHE_LINE_SIZE);
TEST_ASSERT_NOT_NULL(op_params, "Failed to alloc %zuB for op_params",
RTE_ALIGN(sizeof(struct test_op_params),
RTE_CACHE_LINE_SIZE));
rte_bbdev_info_get(ad->dev_id, &info);
socket_id = GET_SOCKET(info.socket_id);
f_ret = create_mempools(ad, socket_id, op_type,
get_num_ops(),p_offloadParams);
if (f_ret != TEST_SUCCESS) {
printf("Couldn't create mempools");
}
f_ret = init_test_op_params(op_params, op_type,
0,
0,
ad->ops_mempool,
1,
get_num_ops(),
get_num_lcores());
if (f_ret != TEST_SUCCESS) {
printf("Couldn't init test op params");
}
//const struct rte_bbdev_op_cap *capabilities = NULL;
rte_bbdev_info_get(ad->dev_id, &info);
socket_id = GET_SOCKET(info.socket_id);
//enum rte_bbdev_op_type op_type = RTE_BBDEV_OP_LDPC_DEC;
/*const struct rte_bbdev_op_cap *cap = info.drv.capabilities;
for (i = 0; i < RTE_BBDEV_OP_TYPE_COUNT; i++) {
if (cap->type == op_type) {
capabilities = cap;
break;
}
cap++;
}*/
ad->nb_queues = 1;
enum op_data_type type;
for (i = 0; i < ad->nb_queues; ++i) {
const uint16_t n = op_params->num_to_process;
struct rte_mempool *in_mp = ad->in_mbuf_pool;
struct rte_mempool *hard_out_mp = ad->hard_out_mbuf_pool;
struct rte_mempool *soft_out_mp = ad->soft_out_mbuf_pool;
struct rte_mempool *harq_in_mp = ad->harq_in_mbuf_pool;
struct rte_mempool *harq_out_mp = ad->harq_out_mbuf_pool;
struct rte_mempool *mbuf_pools[DATA_NUM_TYPES] = {
in_mp,
soft_out_mp,
hard_out_mp,
harq_in_mp,
harq_out_mp,
};
uint8_t queue_id =ad->queue_ids[i];
struct rte_bbdev_op_data **queue_ops[DATA_NUM_TYPES] = {
&op_params->q_bufs[socket_id][queue_id].inputs,
&op_params->q_bufs[socket_id][queue_id].soft_outputs,
&op_params->q_bufs[socket_id][queue_id].hard_outputs,
&op_params->q_bufs[socket_id][queue_id].harq_inputs,
&op_params->q_bufs[socket_id][queue_id].harq_outputs,
};
for (type = DATA_INPUT; type < 3; type+=2) {
ret = allocate_buffers_on_socket(queue_ops[type],
n * sizeof(struct rte_bbdev_op_data),
socket_id);
TEST_ASSERT_SUCCESS(ret,
"Couldn't allocate memory for rte_bbdev_op_data structs");
m_head[type] = rte_pktmbuf_alloc(mbuf_pools[type]);
TEST_ASSERT_NOT_NULL(m_head[type],
"Not enough mbufs in %d data type mbuf pool (needed %u, available %u)",
op_type, 1,
mbuf_pools[type]->size);
}
/* Allocate memory for thread parameters structure */
t_params = rte_zmalloc(NULL, sizeof(struct thread_params),
RTE_CACHE_LINE_SIZE);
TEST_ASSERT_NOT_NULL(t_params, "Failed to alloc %zuB for t_params",
RTE_ALIGN(sizeof(struct thread_params),
RTE_CACHE_LINE_SIZE));
}
break;
case 1:
//printf("offload param E %d BG %d F %d Z %d Qm %d rv %d\n", E,p_decParams->BG, F,p_decParams->Z, Qm,rv);
//uint64_t start_time_init;
//uint64_t total_time_init=0;
//start_time_init = rte_rdtsc_precise();
p_offloadParams->E = E;
p_offloadParams->n_cb = (p_decParams->BG==1)?(66*p_decParams->Z):(50*p_decParams->Z);
p_offloadParams->BG = p_decParams->BG;
p_offloadParams->Z = p_decParams->Z;
p_offloadParams->rv = rv;
p_offloadParams->F = F;
p_offloadParams->Qm = Qm;
rte_bbdev_info_get(ad->dev_id, &info);
socket_id = GET_SOCKET(info.socket_id);
create_reference_ldpc_dec_op(op_params->ref_dec_op, p_offloadParams);
struct rte_mempool *in_mp = ad->in_mbuf_pool;
struct rte_mempool *hard_out_mp = ad->hard_out_mbuf_pool;
struct rte_mempool *soft_out_mp = ad->soft_out_mbuf_pool;
struct rte_mempool *harq_in_mp = ad->harq_in_mbuf_pool;
struct rte_mempool *harq_out_mp = ad->harq_out_mbuf_pool;
struct rte_mempool *mbuf_pools[DATA_NUM_TYPES] = {
in_mp,
soft_out_mp,
hard_out_mp,
harq_in_mp,
harq_out_mp,
};
uint8_t queue_id =ad->queue_ids[0];
struct rte_bbdev_op_data **queue_ops[DATA_NUM_TYPES] = {
&op_params->q_bufs[socket_id][queue_id].inputs,
&op_params->q_bufs[socket_id][queue_id].soft_outputs,
&op_params->q_bufs[socket_id][queue_id].hard_outputs,
&op_params->q_bufs[socket_id][queue_id].harq_inputs,
&op_params->q_bufs[socket_id][queue_id].harq_outputs,
};
//start_time1 = rte_rdtsc_precise();
for (type = DATA_INPUT; type < 3; type+=2) {
ret = init_op_data_objs(*queue_ops[type], p_llr, p_offloadParams->E,
m_head[type], mbuf_pools[type], 1, type, info.drv.min_alignment);
TEST_ASSERT_SUCCESS(ret,
"Couldn't init rte_bbdev_op_data structs");
}
/*total_time_init = rte_rdtsc_precise() - start_time_init;
if (total_time_init > 100*3000)
LOG_E(PHY," ldpc decoder mode 1 first: %u\n",(uint) (total_time_init/3000));
start_time1 = rte_rdtsc_precise();*/
ret = start_pmd_dec(ad, op_params, t_params, p_offloadParams, C, harq_pid, ulsch_id, p_out);
if (ret<0) {
printf("Couldn't start pmd dec");
return(-1);
}
/*total_time1 = rte_rdtsc_precise() - start_time1;
if (total_time1 > 100*3000)
LOG_E(PHY," ldpc decoder mode 1 second: %u\n",(uint) (total_time1/3000));*/
break;
case 2:
free_buffers(ad, op_params);
rte_free(op_params);
rte_free(t_params);
ut_teardown();
testsuite_teardown();
break;
default:
printf("Unknown mode: %d\n", mode);
return(-1);
}
/*uint64_t end=rte_rdtsc_precise();
if (end - start > 200*3000)
LOG_E(PHY," ldpc decode: %u\n",(uint) ((end - start)/3000));
*/
return numIter;
}
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2017 Intel Corporation
*/
#ifndef _MAIN_H_
#define _MAIN_H_
#include <stddef.h>
#include <sys/queue.h>
#include <rte_common.h>
#include <rte_hexdump.h>
#include <rte_log.h>
#define TEST_SUCCESS 0
#define TEST_FAILED -1
#define TEST_SKIPPED 1
#define MAX_BURST 512U
#define DEFAULT_BURST 32U
#define DEFAULT_OPS 64U
#define DEFAULT_ITER 6U
enum op_data_type {
DATA_INPUT = 0,
DATA_SOFT_OUTPUT,
DATA_HARD_OUTPUT,
DATA_HARQ_INPUT,
DATA_HARQ_OUTPUT,
DATA_NUM_TYPES,
};
#define TEST_ASSERT(cond, msg, ...) do { \
if (!(cond)) { \
printf("TestCase %s() line %d failed: " \
msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
return TEST_FAILED; \
} \
} while (0)
/* Compare two buffers (length in bytes) */
#define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len, msg, ...) do { \
if (memcmp((a), (b), len)) { \
printf("TestCase %s() line %d failed: " \
msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
rte_memdump(stdout, "Buffer A", (a), len); \
rte_memdump(stdout, "Buffer B", (b), len); \
return TEST_FAILED; \
} \
} while (0)
#define TEST_ASSERT_SUCCESS(val, msg, ...) do { \
typeof(val) _val = (val); \
if (!(_val == 0)) { \
printf("TestCase %s() line %d failed (err %d): " \
msg "\n", __func__, __LINE__, _val, \
##__VA_ARGS__); \
return TEST_FAILED; \
} \
} while (0)
#define TEST_ASSERT_FAIL(val, msg, ...) \
TEST_ASSERT_SUCCESS(!(val), msg, ##__VA_ARGS__)
#define TEST_ASSERT_NOT_NULL(val, msg, ...) do { \
if ((val) == NULL) { \
printf("TestCase %s() line %d failed (null): " \
msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
return TEST_FAILED; \
} \
} while (0)
struct unit_test_case {
int (*setup)(void);
void (*teardown)(void);
int (*testcase)(void);
const char *name;
};
#define TEST_CASE(testcase) {NULL, NULL, testcase, #testcase}
#define TEST_CASE_ST(setup, teardown, testcase) \
{setup, teardown, testcase, #testcase}
#define TEST_CASES_END() {NULL, NULL, NULL, NULL}
struct unit_test_suite {
const char *suite_name;
int (*setup)(void);
void (*teardown)(void);
struct unit_test_case unit_test_cases[];
};
int unit_test_suite_runner(struct unit_test_suite *suite);
typedef int (test_callback)(void);
TAILQ_HEAD(test_commands_list, test_command);
struct test_command {
TAILQ_ENTRY(test_command) next;
const char *command;
test_callback *callback;
};
void add_test_command(struct test_command *t);
/* Register a test function */
#define REGISTER_TEST_COMMAND(name, testsuite) \
static int test_func_##name(void) \
{ \
return unit_test_suite_runner(&testsuite); \
} \
static struct test_command test_struct_##name = { \
.command = RTE_STR(name), \
.callback = test_func_##name, \
}; \
RTE_INIT(test_register_##name) \
{ \
add_test_command(&test_struct_##name); \
}
const char *get_vector_filename(void);
unsigned int get_num_ops(void);
unsigned int get_burst_sz(void);
unsigned int get_num_lcores(void);
double get_snr(void);
unsigned int get_iter_max(void);
bool get_init_device(void);
#endif
......@@ -75,6 +75,20 @@ typedef struct nrLDPC_dec_params {
e_nrLDPC_outMode outMode; /**< Output format */
} t_nrLDPC_dec_params;
/**
Structure containing LDPC decoder parameters.
*/
typedef struct nrLDPCoffload_params {
uint8_t BG; /**< Base graph */
uint16_t Z;
uint16_t Kr;
uint8_t rv;
uint32_t E;
uint16_t n_cb;
uint16_t F; /**< Filler bits */
uint8_t Qm; /**< Modulation */
} t_nrLDPCoffload_params;
/**
Structure containing LDPC decoder processing time statistics.
*/
......
......@@ -24,6 +24,7 @@
#define __NRLDPC_DEFS__H__
#include <openair1/PHY/defs_nr_common.h>
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
/**
\brief LDPC encoder
\param 1 input
......@@ -71,5 +72,9 @@ typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,sho
\param p_llrOut Output vector
\param p_profiler LDPC profiler statistics
*/
typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_time_stats* );
typedef int32_t(*nrLDPC_decoffloadfunc_t)(t_nrLDPC_dec_params* , uint8_t, uint8_t, uint8_t , uint8_t, uint16_t, uint32_t, uint8_t, int8_t*, int8_t* ,uint8_t);
typedef int32_t(*nrLDPC_dectopfunc_t)(void);
#endif
......@@ -24,14 +24,22 @@
nrLDPC_decoderfunc_t nrLDPC_decoder;
nrLDPC_encoderfunc_t nrLDPC_encoder;
nrLDPC_initcallfunc_t nrLDPC_initcall;
nrLDPC_decoffloadfunc_t nrLDPC_decoder_offload;
nrLDPC_dectopfunc_t top_testsuite;
#else
/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
extern int load_nrLDPClib(char *version) ;
extern int load_nrLDPClib_offload(void) ;
extern int free_nrLDPClib_offload(void) ;
extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr); // for ldpctest
/* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */
extern nrLDPC_initcallfunc_t nrLDPC_initcall;
extern nrLDPC_decoderfunc_t nrLDPC_decoder;
extern nrLDPC_encoderfunc_t nrLDPC_encoder;
extern nrLDPC_decoffloadfunc_t nrLDPC_decoder_offload;
extern nrLDPC_dectopfunc_t top_testsuite;
// inline functions:
#endif
......@@ -71,6 +71,56 @@ int load_nrLDPClib(char *version) {
return 0;
}
int load_nrLDPClib_offload(void) {
loader_shlibfunc_t shlib_decoffload_fdesc;
shlib_decoffload_fdesc.fname = "nrLDPC_decod_offload";
int ret=load_module_shlib("ldpc_offload",&shlib_decoffload_fdesc,1,NULL);
AssertFatal( (ret >= 0),"Error loading ldpc decoder offload");
nrLDPC_decoder_offload = (nrLDPC_decoffloadfunc_t)shlib_decoffload_fdesc.fptr;
t_nrLDPC_dec_params decParams;
t_nrLDPC_dec_params* p_decParams = &decParams;
int8_t l[68*384];
int8_t llrProcBuf[22*384];
p_decParams->Z = 384;
p_decParams->BG = 1;
AssertFatal(nrLDPC_decoder_offload(p_decParams,0, 0,
1,
0,
0,
25344,
8,
l,
llrProcBuf, 0)>=0,
"error loading LDPC decoder offload library\n");
return 0;
}
int free_nrLDPClib_offload(void) {
t_nrLDPC_dec_params decParams;
t_nrLDPC_dec_params* p_decParams = &decParams;
int8_t l[68*384];
int8_t llrProcBuf[22*384];
p_decParams->Z = 384;
p_decParams->BG = 1;
nrLDPC_decoder_offload(p_decParams,0,0,
1,
0,
0,
25344,
8,
l,
llrProcBuf, 2);
return 0;
}
int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr) {
loader_shlibfunc_t shlib_encoder_fdesc;
......
......@@ -508,8 +508,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
crcTableInit();
init_scrambling_luts();
init_pucch2_luts();
load_nrLDPClib(NULL);
if (gNB->ldpc_offload_flag)
load_nrLDPClib_offload();
init_codebook_gNB(gNB);
// PBCH DMRS gold sequences generation
......
......@@ -42,6 +42,7 @@
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "defs.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
......@@ -381,6 +382,23 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint32_t offset;
int kc;
int E;
int8_t llrProcBuf[22*384];
int ret = 0;
int i,j;
int8_t enable_ldpc_offload = phy_vars_gNB->ldpc_offload_flag;
int16_t z_ol [68*384];
int8_t l_ol [68*384];
__m128i *pv_ol128 = (__m128i*)&z_ol;
__m128i *pl_ol128 = (__m128i*)&l_ol;
int no_iteration_ldpc = 2;
int length_dec;
uint8_t crc_type;
int K_bits_F;
int16_t z [68*384 + 16] __attribute__ ((aligned(16)));
int8_t l [68*384 + 16] __attribute__ ((aligned(16)));
__m128i *pv = (__m128i*)&z;
__m128i *pl = (__m128i*)&l;
#ifdef PRINT_CRC_CHECK
prnt_crc_cnt++;
......@@ -395,7 +413,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n");
return 1;
}
uint8_t dtx_det = 0;
t_nrLDPC_dec_params decParams;
t_nrLDPC_dec_params* p_decParams = &decParams;
......@@ -422,6 +440,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
harq_process->round = nr_rv_to_round(pusch_pdu->pusch_data.rv_index);
harq_process->new_rx = false; // flag to indicate if this is a new reception for this harq (initialized to false)
dtx_det = 0;
if (harq_process->round == 0) {
harq_process->new_rx = true;
harq_process->ndi = pusch_pdu->pusch_data.new_data_indicator;
......@@ -431,6 +450,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
if (harq_process->ndi != pusch_pdu->pusch_data.new_data_indicator) {
harq_process->new_rx = true;
harq_process->ndi = pusch_pdu->pusch_data.new_data_indicator;
LOG_D(PHY,"Missed ULSCH detection. NDI toggled but rv %d does not correspond to first reception\n",pusch_pdu->pusch_data.rv_index);
}
......@@ -546,12 +566,179 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
Kr = harq_process->K;
Kr_bytes = Kr>>3;
offset = 0;
//if ((enable_ldpc_offload)&& (dtx_det==0))
if (enable_ldpc_offload){
// if (dtx_det==0) {
if (harq_process->C == 1) {
if (A > 3824)
crc_type = CRC24_A;
else
crc_type = CRC16;
length_dec = harq_process->B;
}
else {
crc_type = CRC24_B;
length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
}
for (r=0; r<harq_process->C; r++) {
E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
memset(harq_process->c[r],0,Kr_bytes);
if ((dtx_det==0)&&(pusch_pdu->pusch_data.rv_index==0)){
//if (dtx_det==0){
if (mcs >9){
memcpy((&z_ol[0]),ulsch_llr+r_offset,E*sizeof(short));
for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++)
{
pl_ol128[j] = _mm_packs_epi16(pv_ol128[i],pv_ol128[i+1]);
}
ret = nrLDPC_decoder_offload(p_decParams, harq_pid,
ULSCH_id,r,
pusch_pdu->pusch_data.rv_index,
harq_process->F,
E,
Qm,
(int8_t*)&pl_ol128[0],
llrProcBuf, 1);
if (ret<0) {
LOG_E(PHY,"ulsch_decoding.c: Problem in LDPC decoder offload\n");
no_iteration_ldpc = ulsch->max_ldpc_iterations + 1;
return 1;
}
}
else{
K_bits_F = Kr-harq_process->F;
t_nrLDPC_time_stats procTime = {0};
t_nrLDPC_time_stats* p_procTime = &procTime ;
/// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
int16_t harq_e[3*8448];
nr_deinterleaving_ldpc(E,
Qm,
harq_e,
ulsch_llr+r_offset);
if (nr_rate_matching_ldpc_rx(pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes,
p_decParams->BG,
p_decParams->Z,
harq_process->d[r],
harq_e,
harq_process->C,
pusch_pdu->pusch_data.rv_index,
harq_process->new_rx,
E,
harq_process->F,
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
no_iteration_ldpc = ulsch->max_ldpc_iterations + 1;
return 1;
}
//set first 2*Z_c bits to zeros
memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
//set Filler bits
memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t));
//Move coded bits before filler bits
memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t));
//skip filler bits
memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t));
//Saturate coded bits before decoding into 8 bits values
for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++)
{
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
}
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
(int8_t*)&pl[0],
llrProcBuf,
p_procTime);
}
for (int m=0; m < Kr>>3; m ++) {
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
}
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
#ifdef PRINT_CRC_CHECK
LOG_I(PHY, "Segment %d CRC OK\n",r);
#endif
no_iteration_ldpc = 2;
} else {
#ifdef PRINT_CRC_CHECK
LOG_I(PHY, "segment %d CRC NOK\n",r);
#endif
no_iteration_ldpc = ulsch->max_ldpc_iterations + 1;
}
//}
r_offset += E;
/*for (int k=0;k<8;k++)
{
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
printf("llrprocbuf [%d] = %x adr %p\n", k, llrProcBuf[k], llrProcBuf+k);
}
*/
}
else{
dtx_det = 0;
no_iteration_ldpc = ulsch->max_ldpc_iterations+1;
}
bool decodeSuccess = (no_iteration_ldpc <= ulsch->max_ldpc_iterations);
if (decodeSuccess) {
memcpy(harq_process->b+offset,
harq_process->c[r],
Kr_bytes - (harq_process->F>>3) -((harq_process->C>1)?3:0));
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
harq_process->processedSegments++;
}
else {
LOG_D(PHY,"uplink segment error %d/%d\n",r,harq_process->C);
LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id);
break; //don't even attempt to decode other segments
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
if ((harq_process->processedSegments==(harq_process->C))) {
LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for slot %d TBS %d\n",
phy_vars_gNB->Mod_id,harq_process->slot,harq_process->TBS);
harq_process->status = SCH_IDLE;
harq_process->round = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
LOG_D(PHY, "ULSCH received ok \n");
nr_fill_indication(phy_vars_gNB,harq_process->frame, harq_process->slot, ULSCH_id, harq_pid, 0,0);
} else {
LOG_D(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) r %d\n",
phy_vars_gNB->Mod_id, harq_process->frame, harq_process->slot,
harq_pid,harq_process->status, harq_process->round,harq_process->TBS,r);
harq_process->handled = 1;
no_iteration_ldpc = ulsch->max_ldpc_iterations + 1;
LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id);
nr_fill_indication(phy_vars_gNB,harq_process->frame, harq_process->slot, ULSCH_id, harq_pid, 1,0);
}
ulsch->last_iteration_cnt = no_iteration_ldpc;
}
else {
dtx_det = 0;
void (*nr_processULSegment_ptr)(void*) = &nr_processULSegment;
for (r=0; r<harq_process->C; r++) {
E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
union ldpcReqUnion id = {.s={ulsch->rnti,frame,nr_tti_rx,0,0}};
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, &phy_vars_gNB->respDecode, nr_processULSegment_ptr);
ldpcDecode_t * rdata=(ldpcDecode_t *) NotifiedFifoData(req);
......@@ -581,5 +768,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
//////////////////////////////////////////////////////////////////////////////////////////
}
}
return 1;
}
......@@ -807,7 +807,7 @@ typedef struct PHY_VARS_gNB_s {
double N0;
unsigned char first_run_I0_measurements;
int ldpc_offload_flag;
unsigned char is_secondary_gNB; // primary by default
unsigned char is_init_sync; /// Flag to tell if initial synchronization is performed. This affects how often the secondary eNB will listen to the PSS from the primary system.
......
......@@ -296,7 +296,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
uint8_t l, number_dmrs_symbols = 0;
uint32_t G;
uint16_t start_symbol, number_symbols, nb_re_dmrs;
uint8_t enable_ldpc_offload = gNB->ldpc_offload_flag;
start_symbol = pusch_pdu->start_symbol_index;
number_symbols = pusch_pdu->nr_of_symbols;
......@@ -361,14 +361,15 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
slot_rx,
harq_pid,
G);
while (gNB->nbDecode > 0) {
notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
if (req == NULL)
break; // Tpool has been stopped
nr_postDecode(gNB, req);
delNotifiedFIFO_elt(req);
}
if (enable_ldpc_offload ==0) {
while (gNB->nbDecode > 0) {
notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
if (req == NULL)
break; // Tpool has been stopped
nr_postDecode(gNB, req);
delNotifiedFIFO_elt(req);
}
}
stop_meas(&gNB->ulsch_decoding_stats);
}
......@@ -493,6 +494,7 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
gNB->UL_INFO.rx_ind.number_of_pdus++;
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
}
// Function to fill UL RB mask to be used for N0 measurements
......@@ -779,8 +781,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot),
dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres);
gNB->pusch_vars[ULSCH_id]->DTX=0;
}
stop_meas(&gNB->rx_pusch_stats);
......
......@@ -65,7 +65,8 @@ double cpuf;
uint16_t NB_UE_INST = 1;
uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1};
const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
// needed for some functions
PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
uint16_t n_rnti = 0x1234;
......
......@@ -60,7 +60,8 @@ double cpuf;
//uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1};
const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
// needed for some functions
PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={{NULL}};
......
......@@ -61,7 +61,8 @@ uint64_t downlink_frequency[MAX_NUM_CCs][4];
void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1};
const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
double cpuf;
//uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
......
......@@ -275,6 +275,7 @@ channel_desc_t *UE2gNB[NUMBER_OF_UE_MAX][NUMBER_OF_gNB_MAX];
int main(int argc, char **argv)
{
char c;
int i;
double SNR, snr0 = -2.0, snr1 = 2.0;
......@@ -323,6 +324,8 @@ int main(int argc, char **argv)
double effTP[100];
float eff_tp_check = 100;
uint8_t snrRun;
int ldpc_offload_flag = 0;
uint8_t max_rounds = 4;
int chest_type[2] = {0};
int enable_ptrs = 0;
......@@ -358,7 +361,7 @@ int main(int argc, char **argv)
/* initialize the sin-cos table */
InitSinLUT();
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:kl:m:n:p:q:r:s:t:u:w:y:z:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:")) != -1) {
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:kl:m:n:op:q:r:s:t:u:v:w:y:z:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:")) != -1) {
printf("handling optarg %c\n",c);
switch (c) {
......@@ -476,6 +479,10 @@ int main(int argc, char **argv)
case 'n':
n_trials = atoi(optarg);
break;
case 'o':
ldpc_offload_flag = 1;
break;
case 'p':
extended_prefix_flag = 1;
......@@ -502,6 +509,10 @@ int main(int argc, char **argv)
mu = atoi(optarg);
break;
case 'v':
max_rounds = atoi(optarg);
break;
case 'w':
start_rb = atoi(optarg);
break;
......@@ -626,6 +637,7 @@ int main(int argc, char **argv)
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("-o ldpc offload flag\n");
printf("-p Use extended prefix mode\n");
printf("-q MCS table\n");
printf("-t Delay spread for multipath channel\n");
......@@ -634,6 +646,7 @@ int main(int argc, char **argv)
//printf("-x Transmission mode (1,2,6 for the moment)\n");
printf("-y Number of TX antennas used at UE\n");
printf("-z Number of RX antennas used at gNB\n");
printf("-v Set the max rounds\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");
......@@ -666,7 +679,6 @@ int main(int argc, char **argv)
get_softmodem_params()->do_ra = 0;
get_softmodem_params()->usim_test = 1;
if (snr1set == 0)
snr1 = snr0 + 10;
......@@ -790,9 +802,12 @@ int main(int argc, char **argv)
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
cfg->carrier_config.num_tx_ant.value = 1;
cfg->carrier_config.num_rx_ant.value = n_rx;
// nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,0,0x01);
gNB->ldpc_offload_flag = ldpc_offload_flag;
gNB->chest_freq = chest_type[0];
gNB->chest_time = chest_type[1];
phy_init_nr_gNB(gNB,0,1);
/* RU handles rxdataF, and gNB just has a pointer. Here, we don't have an RU,
* so we need to allocate that memory as well. */
......@@ -858,6 +873,7 @@ int main(int argc, char **argv)
unsigned char harq_pid = 0;
NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id];
//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 = malloc(sizeof(*UL_tti_req));
NR_Sched_Rsp_t *Sched_INFO = malloc(sizeof(*Sched_INFO));
......@@ -891,7 +907,6 @@ int main(int argc, char **argv)
uint16_t n_rb1 = 75;
uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS;
uint8_t max_rounds = 4;
uint8_t crc_status = 0;
unsigned char mod_order = nr_get_Qm_ul(Imcs, mcs_table);
......@@ -1056,6 +1071,7 @@ int main(int argc, char **argv)
double blerStats[4][100];
double berStats[4][100];
double snrStats[100];
double ldpcDecStats[100] = {0};
memset(errors_scrambling, 0, sizeof(uint32_t)*4*100);
memset(n_errors, 0, sizeof(int)*4*100);
memset(round_trials, 0, sizeof(int)*4*100);
......@@ -1623,6 +1639,8 @@ int main(int argc, char **argv)
printf("\n");
}
ldpcDecStats[snrRun] = gNB->ulsch_decoding_stats.trials?inMicroS(gNB->ulsch_decoding_stats.diff/gNB->ulsch_decoding_stats.trials):0;
if(n_trials==1)
break;
......@@ -1669,8 +1687,11 @@ int main(int argc, char **argv)
LOG_MM(opStatsFile,"BER_round3",berStats[3],snrRun,1,7);
LOG_MM(opStatsFile,"EffRate",effRate,snrRun,1,7);
LOG_MM(opStatsFile,"EffTP",effTP,snrRun,1,7);
free(test_input_bit);
free(estimated_output_bit);
if (gNB->ldpc_offload_flag)
free_nrLDPClib_offload();
if (output_fd)
fclose(output_fd);
......
......@@ -465,7 +465,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
pthread_mutex_unlock(&Sockmutex);
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
return nsamps;
}
......
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_CU_ID = 0xe00;
# cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({
mcc = 208;
mnc = 99;
mnc_length = 2;
snssaiList = (
{
sst = 1;
sd = 0x010203; // 0 false, else true
},
{
sst = 1;
sd = 0x112233; // 0 false, else true
}
);
});
nr_cellid = 12345678L
# tr_s_preference = "local_mac"
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 2;
min_rxtxtime_pdsch = 2;
ul_prbblacklist = "51,52,53,54"
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 11;
searchSpaceZero = 0;
}
);
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3301.68 MHz + 22*12*30e-3 MHz = 3309.6
#absoluteFrequencySSB = 620640;
# this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68
absoluteFrequencySSB = 621312;
# this is 3503.28 MHz + 22*12*30e-3 MHz = 3511.2
#absoluteFrequencySSB = 634080;
# this is 3600.48 MHz
#absoluteFrequencySSB = 640032;
#dl_frequencyBand = 78;
# this is 3301.68 MHz
#dl_absoluteFrequencyPointA = 620112;
# this is 3300.60 MHz
dl_absoluteFrequencyPointA = 620040;
# this is 3502.56 MHz
#dl_absoluteFrequencyPointA = 633552;
# this is 3600.48 MHz
#dl_absoluteFrequencyPointA = 640032;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=0,L=106 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 11;
initialDLBWPsearchSpaceZero = 0;
#pdsch-ConfigCommon
#pdschTimeDomainAllocationList (up to 16 entries)
initialDLBWPk0_0 = 0;
#initialULBWPmappingType
#0=typeA,1=typeB
initialDLBWPmappingType_0 = 0;
#this is SS=1,L=13
initialDLBWPstartSymbolAndLength_0 = 40;
initialDLBWPk0_1 = 0;
initialDLBWPmappingType_1 = 0;
#this is SS=1,L=5
initialDLBWPstartSymbolAndLength_1 = 57;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 12;
preambleReceivedTargetPower = -104;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 6;
initialULBWPmappingType_0 = 1
# this is SS=2 L=13
initialULBWPstartSymbolAndLength_0 = 41;
initialULBWPk2_1 = 6;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=4
initialULBWPstartSymbolAndLength_1 = 52;
initialULBWPk2_2 = 7;
initialULBWPmappingType_2 = 1;
# this is SS=10 L=4
initialULBWPstartSymbolAndLength_2 = 52;
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "192.168.69.131";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "em1";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.18.196/24";
GNB_INTERFACE_NAME_FOR_NGU = "em1";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.18.196/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
ulsch_max_slots_inactivity=10;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 3;
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 50;
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 2
nb_rx = 2
att_tx = 0
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
##beamforming 1x2 matrix: 1 layer x 2 antennas
bf_weights = [0x00007fff, 0x0000];
##beamforming 1x4 matrix: 1 layer x 4 antennas
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
## beamforming 2x2 matrix:
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
## beamforming 4x4 matrix:
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
sdr_addrs = "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=internal,time_source=internal"
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
f1ap_log_level ="debug";
f1ap_log_verbosity ="medium";
};
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_CU_ID = 0xe00;
# cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({
mcc = 208;
mnc = 99;
mnc_length = 2;
snssaiList = (
{
sst = 1;
sd = 0x010203; // 0 false, else true
},
{
sst = 1;
sd = 0x000001; // 0 false, else true
}
);
});
nr_cellid = 12345678L
# tr_s_preference = "local_mac"
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 2;
min_rxtxtime_pdsch = 5;
ul_prbblacklist = "51,52,53,54"
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 11;
searchSpaceZero = 0;
}
);
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3301.68 MHz + 22*12*30e-3 MHz = 3309.6
#absoluteFrequencySSB = 620640;
# this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68
absoluteFrequencySSB = 621312;
# this is 3503.28 MHz + 22*12*30e-3 MHz = 3511.2
#absoluteFrequencySSB = 634080;
# this is 3600.48 MHz
#absoluteFrequencySSB = 640032;
#dl_frequencyBand = 78;
# this is 3301.68 MHz
#dl_absoluteFrequencyPointA = 620112;
# this is 3300.60 MHz
dl_absoluteFrequencyPointA = 620040;
# this is 3502.56 MHz
#dl_absoluteFrequencyPointA = 633552;
# this is 3600.48 MHz
#dl_absoluteFrequencyPointA = 640032;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=0,L=106 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 11;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 12;
preambleReceivedTargetPower = -104;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "192.168.70.132";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24";
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
# pusch_TargetSNRx10 = 200;
# pucch_TargetSNRx10 = 150;
ulsch_max_frame_inactivity = 0;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
thread_pool_size = 4;
# pucch0_dtx_threshold = 150;
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 2
nb_rx = 2
att_tx = 0
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
##beamforming 1x2 matrix: 1 layer x 2 antennas
bf_weights = [0x00007fff, 0x0000];
##beamforming 1x4 matrix: 1 layer x 4 antennas
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
## beamforming 2x2 matrix:
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
## beamforming 4x4 matrix:
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
sf_extension = 0
sdr_addrs = "addr=192.168.82.52,second_addr=192.168.83.52,clock_source=internal,time_source=internal"
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
f1ap_log_level ="debug";
f1ap_log_verbosity ="medium";
};
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_CU_ID = 0xe00;
# cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({
mcc = 208;
mnc = 99;
mnc_length = 2;
snssaiList = (
{
sst = 1;
sd = 0x010203; // 0 false, else true
},
{
sst = 1;
sd = 0x000001; // 0 false, else true
}
);
});
nr_cellid = 12345678L
# tr_s_preference = "local_mac"
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 2;
#pusch_TargetSNRx10 = 200;
#pucch_TargetSNRx10 = 200;
ul_prbblacklist = "79,80,81,82"
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 11;
searchSpaceZero = 0;
}
);
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3301.68 MHz + 22*12*30e-3 MHz = 3309.6
#absoluteFrequencySSB = 620640;
# this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68
absoluteFrequencySSB = 621312;
# this is 3503.28 MHz + 22*12*30e-3 MHz = 3511.2
#absoluteFrequencySSB = 634080;
# this is 3600.48 MHz
#absoluteFrequencySSB = 640032;
#dl_frequencyBand = 78;
# this is 3301.68 MHz
#dl_absoluteFrequencyPointA = 620112;
# this is 3300.60 MHz
dl_absoluteFrequencyPointA = 620040;
# this is 3502.56 MHz
#dl_absoluteFrequencyPointA = 633552;
# this is 3600.48 MHz
#dl_absoluteFrequencyPointA = 640032;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 162;
#initialDownlinkBWP
#genericParameters
# this is RBstart=0,L=106 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 31899;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 11;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 162;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 31899;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 12;
preambleReceivedTargetPower = -104;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "192.168.70.132";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24";
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
#pusch_TargetSNRx10 = 200;
#pucch_TargetSNRx10 = 200;
ulsch_max_frame_inactivity = 1;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
thread_pool_size = 8;
# pucch0_dtx_threshold = 150;
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 2
nb_rx = 2
att_tx = 0
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
##beamforming 1x2 matrix: 1 layer x 2 antennas
bf_weights = [0x00007fff, 0x0000];
##beamforming 1x4 matrix: 1 layer x 4 antennas
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
## beamforming 2x2 matrix:
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
## beamforming 4x4 matrix:
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
sf_extension = 0
sdr_addrs = "addr=192.168.82.52,second_addr=192.168.83.52,clock_source=internal,time_source=internal"
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
f1ap_log_level ="debug";
f1ap_log_verbosity ="medium";
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment