Merge remote-tracking branch 'origin/develop-nr' into shortBlockCoding

Conflicts:
	cmake_targets/CMakeLists.txt
	cmake_targets/autotests/test_case_list.xml
	cmake_targets/build_oai
	openair1/PHY/CODING/TESTBENCH/polartest.c
	openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
	openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
	openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
	openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
	openair1/PHY/CODING/nr_polar_init.c
	openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
	openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
	openair1/SIMULATION/NR_PHY/dlschsim.c
	openair1/SIMULATION/NR_PHY/dlsim.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
This commit is contained in:
Raymond Knopp
2019-04-04 09:14:37 +02:00
167 changed files with 16740 additions and 8622 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
cmake_targets/log/
cmake_targets/ran_build/
cmake_targets/*/build/
targets/bin/
+3 -3
View File
@@ -131,10 +131,10 @@ pipeline {
}
}
stage ("Start VM -- nu-ue-usrp") {
stage ("Start VM -- nr-ue-usrp") {
steps {
timeout (time: 5, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nu-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
}
}
}
@@ -239,7 +239,7 @@ pipeline {
steps {
gitlabCommitStatus(name: "Build nr-UE-usrp") {
timeout (time: 20, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nu-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
}
}
+46 -12
View File
@@ -27,6 +27,8 @@ def pythonExecutor = params.pythonExecutor
// Location of the test XML file to be run
def testXMLFile = params.pythonTestXmlFile
def mainPythonAllXmlFiles = ""
def buildStageStatus = true
// Name of the test stage
def testStageName = params.pipelineTestStageName
@@ -53,6 +55,7 @@ def eNB_Repository
def eNB_Branch
def eNB_CommitID
def eNB_AllowMergeRequestProcess = false
def eNB_TargetBranch
pipeline {
agent {
@@ -107,8 +110,16 @@ pipeline {
if (params.pythonTestXmlFile == null) {
// picking default
testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml'
echo "Test XML file(default): ${testXMLFile}"
mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " "
} else {
echo "Test XML file : ${testXMLFile}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists("ci-scripts/" + xmlFile)) {
mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " "
echo "Test XML file : ${xmlFile}"
}
}
}
// If not present picking a default Stage Name
if (params.pipelineTestStageName == null) {
@@ -150,6 +161,14 @@ pipeline {
echo "eNB_CommitID : ${eNB_CommitID}"
if (params.eNB_mergeRequest != null) {
eNB_AllowMergeRequestProcess = params.eNB_mergeRequest
if (eNB_AllowMergeRequestProcess) {
if (params.eNB_TargetBranch != null) {
eNB_TargetBranch = params.eNB_TargetBranch
} else {
eNB_TargetBranch = 'develop'
}
echo "eNB_TargetBranch : ${eNB_TargetBranch}"
}
}
if (params.EPC_IPAddress == null) {
@@ -174,6 +193,13 @@ pipeline {
if (allParametersPresent) {
echo "All parameters are present"
if (eNB_AllowMergeRequestProcess) {
sh "git fetch"
sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest"
} else {
sh "git fetch"
sh "git checkout -f ${eNB_CommitID}"
}
} else {
echo "Some parameters are missing"
sh "./ci-scripts/fail.sh"
@@ -185,17 +211,25 @@ pipeline {
steps {
script {
dir ('ci-scripts') {
try {
echo "\u2705 \u001B[32m${testStageName}\u001B[0m"
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
]) {
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${testXMLFile}"
echo "\u2705 \u001B[32m${testStageName}\u001B[0m"
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
]) {
sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
try {
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
} catch (Exception e) {
currentBuild.result = 'FAILURE'
buildStageStatus = false
}
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
}
}
}
@@ -327,7 +361,7 @@ pipeline {
}
if(fileExists("ci-scripts/test_results.html")) {
sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html"
sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' test_results-${JOB_NAME}.html"
sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
archiveArtifacts "test_results-${JOB_NAME}.html"
}
}
+21
View File
@@ -0,0 +1,21 @@
#/*
# * 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
# */
/inet.*brd/{print "interfaceToUse="$NF"done"}
+13 -6
View File
@@ -94,15 +94,22 @@ function build_on_vm {
echo "############################################################"
echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
echo "############################################################"
acquire_vm_create_lock
uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml
echo "Waiting for VM to be started"
uvt-kvm wait $VM_NAME --insecure
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
release_vm_create_lock
else
echo "Waiting for VM to be started"
uvt-kvm wait $VM_NAME --insecure
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
fi
echo "Waiting for VM to be started"
uvt-kvm wait $VM_NAME --insecure
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
echo "############################################################"
echo "Copying GIT repo into VM ($VM_NAME)"
echo "############################################################"
+31
View File
@@ -49,6 +49,35 @@ function create_usage {
echo ""
}
function acquire_vm_create_lock {
local FlockFile="/tmp/vmclone.lck"
local unlocked="0"
touch ${FlockFile} 2>/dev/null
if [[ $? -ne 0 ]]
then
echo "Cannot access lock file ${FlockFile}"
exit 2
fi
while [ $unlocked -eq 0 ]
do
exec 5>${FlockFile}
flock -nx 5
if [[ $? -ne 0 ]]
then
echo "Another instance of VM creation is running"
sleep 10
else
unlocked="1"
fi
done
chmod 666 ${FlockFile} 2>/dev/null
}
function release_vm_create_lock {
local FlockFile="/tmp/vmclone.lck"
rm -Rf ${FlockFile}
}
function create_vm {
echo "############################################################"
echo "OAI CI VM script"
@@ -60,10 +89,12 @@ function create_vm {
echo "############################################################"
echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
echo "############################################################"
acquire_vm_create_lock
uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml
echo "Waiting for VM to be started"
uvt-kvm wait $VM_NAME --insecure
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
release_vm_create_lock
}
+26
View File
@@ -1,4 +1,24 @@
#!/bin/bash
#/*
# * 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
# */
function usage {
echo "OAI GitLab merge request applying script"
@@ -83,6 +103,11 @@ esac
done
if [[ $TARGET_COMMIT_ID == "latest" ]]
then
TARGET_COMMIT_ID=`git log -n1 --pretty=format:%H origin/$TARGET_BRANCH`
fi
echo "Source Branch is : $SOURCE_BRANCH"
echo "Source Commit ID is : $SOURCE_COMMIT_ID"
echo "Target Branch is : $TARGET_BRANCH"
@@ -101,6 +126,7 @@ git config user.email "jenkins@openairinterface.org"
git config user.name "OAI Jenkins"
git checkout -f $SOURCE_COMMIT_ID
git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG
git merge --ff $TARGET_COMMIT_ID -m "Temporary merge for CI"
+657 -193
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -39,7 +39,7 @@ function variant_usage {
echo " --variant phy-sim OR -v3"
echo " --variant cppcheck OR -v4"
echo " --variant gnb-usrp OR -v5"
echo " --variant nu-ue-usrp OR -v6"
echo " --variant nr-ue-usrp OR -v6"
echo " --variant enb-ethernet OR -v7"
echo " --variant ue-ethernet OR -v8"
}
@@ -252,9 +252,9 @@ case $key in
VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel15.txt
NB_PATTERN_FILES=8
NB_PATTERN_FILES=9
BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=4096
VM_MEMORY=8192
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
NBARGS=$[$NBARGS+256]
shift
@@ -331,9 +331,9 @@ case $key in
VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel15.txt
NB_PATTERN_FILES=8
NB_PATTERN_FILES=9
BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=4096
VM_MEMORY=8192
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
NBARGS=$[$NBARGS+256]
;;
@@ -354,7 +354,7 @@ case $key in
BUILD_OPTIONS="--gNB -w USRP"
NBARGS=$[$NBARGS+256]
;;
nu-ue-usrp)
nr-ue-usrp)
VM_NAME=ci-ue-nr-usrp
ARCHIVES_LOC=nrue_usrp
LOG_PATTERN=.Rel15.txt
+7 -1
View File
@@ -441,10 +441,16 @@ function run_test_on_vm {
echo "############################################################"
echo "Creating test EPC VM ($EPC_VM_NAME) on Ubuntu Cloud Image base"
echo "############################################################"
acquire_vm_create_lock
uvt-kvm create $EPC_VM_NAME release=xenial --unsafe-caching
echo "Waiting for VM to be started"
uvt-kvm wait $EPC_VM_NAME --insecure
release_vm_create_lock
else
echo "Waiting for VM to be started"
uvt-kvm wait $EPC_VM_NAME --insecure
fi
uvt-kvm wait $EPC_VM_NAME --insecure
EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME`
echo "$EPC_VM_NAME has for IP addr = $EPC_VM_IP_ADDR"
scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu
+20
View File
@@ -1,3 +1,23 @@
#/*
# * 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
# */
BEGIN{max=0;min=10000}
{
if ($0 ~/Mbits/) {
@@ -0,0 +1,54 @@
<!--
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-tab</htmlTabRef>
<htmlTabName>Build</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
010101
050101 060101 070101
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build eNB (USRP)</desc>
<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
</testCase>
<testCase id="050101">
<class>Initialize_HSS</class>
<desc>Initialize HSS</desc>
</testCase>
<testCase id="060101">
<class>Initialize_MME</class>
<desc>Initialize MME</desc>
</testCase>
<testCase id="070101">
<class>Initialize_SPGW</class>
<desc>Initialize SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,47 @@
<!--
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>epc-closure</htmlTabRef>
<htmlTabName>EPC-Closure</htmlTabName>
<htmlTabIcon>log-out</htmlTabIcon>
<TestCaseRequestedList>
050201 060201 070201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="050201">
<class>Terminate_HSS</class>
<desc>Terminate HSS</desc>
</testCase>
<testCase id="060201">
<class>Terminate_MME</class>
<desc>Terminate MME</desc>
</testCase>
<testCase id="070201">
<class>Terminate_SPGW</class>
<desc>Terminate SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,119 @@
<!--
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-05-tm1</htmlTabRef>
<htmlTabName>Test-05MHz-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
040101
030104 040301 040501 040602 040601 040603 040642 040641 040643 040401 040201 030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030104">
<class>Initialize_eNB</class>
<desc>Initialize eNB (TDD/Band40/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf</Initialize_eNB_args>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040501">
<class>Ping</class>
<desc>ping (5MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>25</ping_packetloss_threshold>
</testCase>
<testCase id="040601">
<class>Iperf</class>
<desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040602">
<class>Iperf</class>
<desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040603">
<class>Iperf</class>
<desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(unbalanced)</desc>
<iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040641">
<class>Iperf</class>
<desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040642">
<class>Iperf</class>
<desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040643">
<class>Iperf</class>
<desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
</testCaseList>
@@ -21,43 +21,21 @@
-->
<testCaseList>
<htmlTabRef>test-10-tm1</htmlTabRef>
<htmlTabName>Test-10MHz-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
010101
050101 060101 070101 040101
030104 040301 040501 040602 040601 040603 040642 040641 040643 040401 040201 030201
040101
030114 040301 040511 040612 040611 040613 040652 040651 040653 040401 040201 030201
050201 060201 070201
</TestCaseRequestedList>
<!-- 20MHz is not stable enough to be run -->
<!--
030124 040301 040521 040622 040621 040623 040662 040661 040663 040401 040201 030201
-->
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build eNB (USRP)</desc>
<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
</testCase>
<testCase id="030104">
<class>Initialize_eNB</class>
<desc>Initialize eNB (TDD/Band40/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
</testCase>
<testCase id="030114">
<class>Initialize_eNB</class>
<desc>Initialize eNB (TDD/Band40/10MHz/info)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf</Initialize_eNB_args>
</testCase>
<testCase id="030106">
<class>Initialize_eNB</class>
<desc>Initialize eNB (TDD/Band40/20MHz/info)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
@@ -83,13 +61,6 @@
<desc>Detach UE</desc>
</testCase>
<testCase id="040501">
<class>Ping</class>
<desc>ping (5MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>25</ping_packetloss_threshold>
</testCase>
<testCase id="040511">
<class>Ping</class>
<desc>ping (10MHz - 20 sec)</desc>
@@ -97,30 +68,6 @@
<ping_packetloss_threshold>25</ping_packetloss_threshold>
</testCase>
<testCase id="040601">
<class>Iperf</class>
<desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040602">
<class>Iperf</class>
<desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040603">
<class>Iperf</class>
<desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(unbalanced)</desc>
<iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040611">
<class>Iperf</class>
<desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced)</desc>
@@ -145,30 +92,6 @@
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040641">
<class>Iperf</class>
<desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040642">
<class>Iperf</class>
<desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040643">
<class>Iperf</class>
<desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040651">
<class>Iperf</class>
<desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc>
@@ -193,34 +116,4 @@
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="050101">
<class>Initialize_HSS</class>
<desc>Initialize HSS</desc>
</testCase>
<testCase id="060101">
<class>Initialize_MME</class>
<desc>Initialize MME</desc>
</testCase>
<testCase id="070101">
<class>Initialize_SPGW</class>
<desc>Initialize SPGW</desc>
</testCase>
<testCase id="050201">
<class>Terminate_HSS</class>
<desc>Terminate HSS</desc>
</testCase>
<testCase id="060201">
<class>Terminate_MME</class>
<desc>Terminate MME</desc>
</testCase>
<testCase id="070201">
<class>Terminate_SPGW</class>
<desc>Terminate SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,119 @@
<!--
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-20-tm1</htmlTabRef>
<htmlTabName>Test-20MHz-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
040101
030124 040301 040521 040622 040621 040623 040662 040661 040663 040401 040201 030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030124">
<class>Initialize_eNB</class>
<desc>Initialize eNB (TDD/Band40/20MHz/info)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf</Initialize_eNB_args>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040521">
<class>Ping</class>
<desc>ping (20MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>25</ping_packetloss_threshold>
</testCase>
<testCase id="040621">
<class>Iperf</class>
<desc>iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040622">
<class>Iperf</class>
<desc>iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040623">
<class>Iperf</class>
<desc>iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced)</desc>
<iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040661">
<class>Iperf</class>
<desc>iperf (20MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040662">
<class>Iperf</class>
<desc>iperf (20MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040663">
<class>Iperf</class>
<desc>iperf (20MHz - UL/2Mbps/UDP)(30 sec)(unbalanced)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
</testCaseList>
@@ -0,0 +1,65 @@
<!--
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>tracer-test</htmlTabRef>
<htmlTabName>T-Tracer</htmlTabName>
<htmlTabIcon>duplicate</htmlTabIcon>
<TestCaseRequestedList>
040101
030100 040300 040401 040201 030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030100">
<class>Initialize_eNB</class>
<desc>Initialize eNB (TDD/Band40/5MHz) with T Tracer on</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf --T_stdout 0</Initialize_eNB_args>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040300">
<class>Attach_UE</class>
<desc>Attach single UE</desc>
<nbMaxUEtoAttach>1</nbMaxUEtoAttach>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
</testCaseList>
-350
View File
@@ -1,350 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<TestCaseRequestedList>
010101
050101 060101 070101 040101
030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201
030111 040301 040511 040613 040614 040615 040616 040617 040651 040652 040653 040654 040401 040201 030201
030121 040301 040521 040623 040624 040625 040626 040627 040662 040661 040663 040664 040401 040201 030201
050201 060201 070201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build eNB (USRP)</desc>
<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
</testCase>
<testCase id="030101">
<class>Initialize_eNB</class>
<desc>Initialize eNB (FDD/Band7/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
</testCase>
<testCase id="030111">
<class>Initialize_eNB</class>
<desc>Initialize eNB (FDD/Band7/10MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
</testCase>
<testCase id="030121">
<class>Initialize_eNB</class>
<desc>Initialize eNB (FDD/Band7/20MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040501">
<class>Ping</class>
<desc>ping (5MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040511">
<class>Ping</class>
<desc>ping (10MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040521">
<class>Ping</class>
<desc>ping (20MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040603">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040604">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040605">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040606">
<class>Iperf</class>
<desc>iperf (5MHz - DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040607">
<class>Iperf</class>
<desc>iperf (5MHz - DL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040641">
<class>Iperf</class>
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040642">
<class>Iperf</class>
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040643">
<class>Iperf</class>
<desc>iperf (5MHz - UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040644">
<class>Iperf</class>
<desc>iperf (5MHz - UL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040613">
<class>Iperf</class>
<desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 30M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040614">
<class>Iperf</class>
<desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 30M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040615">
<class>Iperf</class>
<desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(unbalanced profile)</desc>
<iperf_args>-u -b 30M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040616">
<class>Iperf</class>
<desc>iperf (10MHz - DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040617">
<class>Iperf</class>
<desc>iperf (10MHz - DL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040651">
<class>Iperf</class>
<desc>iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040652">
<class>Iperf</class>
<desc>iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040653">
<class>Iperf</class>
<desc>iperf (10MHz - UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040654">
<class>Iperf</class>
<desc>iperf (10MHz - UL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040623">
<class>Iperf</class>
<desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 70M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040624">
<class>Iperf</class>
<desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 70M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040625">
<class>Iperf</class>
<desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(unbalanced profile)</desc>
<iperf_args>-u -b 70M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040626">
<class>Iperf</class>
<desc>iperf (20MHz - DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040627">
<class>Iperf</class>
<desc>iperf (20MHz - DL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040661">
<class>Iperf</class>
<desc>iperf (20MHz - UL/20Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040662">
<class>Iperf</class>
<desc>iperf (20MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040663">
<class>Iperf</class>
<desc>iperf (20MHz - UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040664">
<class>Iperf</class>
<desc>iperf (20MHz - UL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="050101">
<class>Initialize_HSS</class>
<desc>Initialize HSS</desc>
</testCase>
<testCase id="060101">
<class>Initialize_MME</class>
<desc>Initialize MME</desc>
</testCase>
<testCase id="070101">
<class>Initialize_SPGW</class>
<desc>Initialize SPGW</desc>
</testCase>
<testCase id="050201">
<class>Terminate_HSS</class>
<desc>Terminate HSS</desc>
</testCase>
<testCase id="060201">
<class>Terminate_MME</class>
<desc>Terminate MME</desc>
</testCase>
<testCase id="070201">
<class>Terminate_SPGW</class>
<desc>Terminate SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,54 @@
<!--
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-tab</htmlTabRef>
<htmlTabName>Build</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
010101
050101 060101 070101
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build eNB (USRP)</desc>
<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
</testCase>
<testCase id="050101">
<class>Initialize_HSS</class>
<desc>Initialize HSS</desc>
</testCase>
<testCase id="060101">
<class>Initialize_MME</class>
<desc>Initialize MME</desc>
</testCase>
<testCase id="070101">
<class>Initialize_SPGW</class>
<desc>Initialize SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,47 @@
<!--
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>epc-closure</htmlTabRef>
<htmlTabName>EPC-Closure</htmlTabName>
<htmlTabIcon>log-out</htmlTabIcon>
<TestCaseRequestedList>
050201 060201 070201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="050201">
<class>Terminate_HSS</class>
<desc>Terminate HSS</desc>
</testCase>
<testCase id="060201">
<class>Terminate_MME</class>
<desc>Terminate MME</desc>
</testCase>
<testCase id="070201">
<class>Terminate_SPGW</class>
<desc>Terminate SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,143 @@
<!--
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-05-tm1</htmlTabRef>
<htmlTabName>Test-05MHz-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
040101
030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030101">
<class>Initialize_eNB</class>
<desc>Initialize eNB (FDD/Band7/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf</Initialize_eNB_args>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040501">
<class>Ping</class>
<desc>ping (5MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040603">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040604">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040605">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040606">
<class>Iperf</class>
<desc>iperf (5MHz - DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040607">
<class>Iperf</class>
<desc>iperf (5MHz - DL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040641">
<class>Iperf</class>
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040642">
<class>Iperf</class>
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040643">
<class>Iperf</class>
<desc>iperf (5MHz - UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040644">
<class>Iperf</class>
<desc>iperf (5MHz - UL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
</testCaseList>
@@ -0,0 +1,143 @@
<!--
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-10-tm1</htmlTabRef>
<htmlTabName>Test-10MHz-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
040101
030111 040301 040511 040613 040614 040615 040616 040617 040651 040652 040653 040654 040401 040201 030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030111">
<class>Initialize_eNB</class>
<desc>Initialize eNB (FDD/Band7/10MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf</Initialize_eNB_args>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040511">
<class>Ping</class>
<desc>ping (10MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040613">
<class>Iperf</class>
<desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 30M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040614">
<class>Iperf</class>
<desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 30M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040615">
<class>Iperf</class>
<desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(unbalanced profile)</desc>
<iperf_args>-u -b 30M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040616">
<class>Iperf</class>
<desc>iperf (10MHz - DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040617">
<class>Iperf</class>
<desc>iperf (10MHz - DL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040651">
<class>Iperf</class>
<desc>iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040652">
<class>Iperf</class>
<desc>iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040653">
<class>Iperf</class>
<desc>iperf (10MHz - UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040654">
<class>Iperf</class>
<desc>iperf (10MHz - UL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
</testCaseList>
@@ -0,0 +1,143 @@
<!--
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-20-tm1</htmlTabRef>
<htmlTabName>Test-20MHz-TM1</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
040101
030121 040301 040521 040623 040624 040625 040662 040401 040201 030201
</TestCaseRequestedList>
<TestCaseExclusionList>040626 040627 040661 040663 040664</TestCaseExclusionList>
<testCase id="030121">
<class>Initialize_eNB</class>
<desc>Initialize eNB (FDD/Band7/20MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf</Initialize_eNB_args>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040521">
<class>Ping</class>
<desc>ping (20MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040623">
<class>Iperf</class>
<desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 70M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040624">
<class>Iperf</class>
<desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 70M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040625">
<class>Iperf</class>
<desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(unbalanced profile)</desc>
<iperf_args>-u -b 70M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile>
</testCase>
<testCase id="040626">
<class>Iperf</class>
<desc>iperf (20MHz - DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040627">
<class>Iperf</class>
<desc>iperf (20MHz - DL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040661">
<class>Iperf</class>
<desc>iperf (20MHz - UL/12Mbps/UDP)(30 sec)(balanced profile)</desc>
<iperf_args>-u -b 12M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
<testCase id="040662">
<class>Iperf</class>
<desc>iperf (20MHz - UL/17Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 17M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040663">
<class>Iperf</class>
<desc>iperf (20MHz - UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040664">
<class>Iperf</class>
<desc>iperf (20MHz - UL/TCP)(30 sec)(balanced profile)</desc>
<iperf_args>-t 30 -i 1 -fm -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile>
</testCase>
</testCaseList>
@@ -0,0 +1,65 @@
<!--
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>tracer-test</htmlTabRef>
<htmlTabName>T-Tracer</htmlTabName>
<htmlTabIcon>duplicate</htmlTabIcon>
<TestCaseRequestedList>
040101
030100 040300 040401 040201 030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030100">
<class>Initialize_eNB</class>
<desc>Initialize eNB (FDD/Band7/5MHz) with T Tracer on</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --T_stdout 0</Initialize_eNB_args>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040300">
<class>Attach_UE</class>
<desc>Attach single UE</desc>
<nbMaxUEtoAttach>1</nbMaxUEtoAttach>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
</testCaseList>
@@ -1,219 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<!-- Only 5MHz is tested since neither 10MHz nor 20MHz work in this configuration -->
<!-- Also no UL iperf in 5MHz (040642) -->
<TestCaseRequestedList>
010101
050101 060101 070101 040101
030104 030105 040301 040501 040602 040401 040201 030201 030202
050201 060201 070201
</TestCaseRequestedList>
<!--
030104 030105 040301 040501 040602 040642 040401 040201 030201 030202
030114 030115 040301 040511 040612 040652 040401 040201 030201 030202
030124 030125 040301 040521 040622 040662 040401 040201 030201 030202
-->
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build eNB (USRP -- Ethernet Fronthaul)</desc>
<Build_eNB_args>-t ETHERNET -w USRP -c --eNB</Build_eNB_args>
</testCase>
<testCase id="030104">
<class>Initialize_eNB</class>
<desc>Initialize RRU (TDD/Band40)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030105">
<class>Initialize_eNB</class>
<desc>Initialize RCC (TDD/Band40/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030114">
<class>Initialize_eNB</class>
<desc>Initialize RRU (TDD/Band40)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030115">
<class>Initialize_eNB</class>
<desc>Initialize RCC (TDD/Band40/10MHz/info)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030124">
<class>Initialize_eNB</class>
<desc>Initialize RRU (TDD/Band40)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030125">
<class>Initialize_eNB</class>
<desc>Initialize RCC (TDD/Band40/20MHz/info)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate RCC</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate RRU</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040501">
<class>Ping</class>
<desc>ping (5MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>25</ping_packetloss_threshold>
</testCase>
<testCase id="040511">
<class>Ping</class>
<desc>ping (10MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>25</ping_packetloss_threshold>
</testCase>
<testCase id="040521">
<class>Ping</class>
<desc>ping (20MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>25</ping_packetloss_threshold>
</testCase>
<testCase id="040602">
<class>Iperf</class>
<desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040612">
<class>Iperf</class>
<desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040622">
<class>Iperf</class>
<desc>iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040642">
<class>Iperf</class>
<desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040652">
<class>Iperf</class>
<desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040662">
<class>Iperf</class>
<desc>iperf (20MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="050101">
<class>Initialize_HSS</class>
<desc>Initialize HSS</desc>
</testCase>
<testCase id="060101">
<class>Initialize_MME</class>
<desc>Initialize MME</desc>
</testCase>
<testCase id="070101">
<class>Initialize_SPGW</class>
<desc>Initialize SPGW</desc>
</testCase>
<testCase id="050201">
<class>Terminate_HSS</class>
<desc>Terminate HSS</desc>
</testCase>
<testCase id="060201">
<class>Terminate_MME</class>
<desc>Terminate MME</desc>
</testCase>
<testCase id="070201">
<class>Terminate_SPGW</class>
<desc>Terminate SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,55 @@
<!--
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-tab</htmlTabRef>
<htmlTabName>Build</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
010101
050101 060101 070101
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build eNB (USRP -- Ethernet Fronthaul)</desc>
<Build_eNB_args>-t ETHERNET -w USRP -c --eNB</Build_eNB_args>
</testCase>
<testCase id="050101">
<class>Initialize_HSS</class>
<desc>Initialize HSS</desc>
</testCase>
<testCase id="060101">
<class>Initialize_MME</class>
<desc>Initialize MME</desc>
</testCase>
<testCase id="070101">
<class>Initialize_SPGW</class>
<desc>Initialize SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,48 @@
<!--
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>epc-closure</htmlTabRef>
<htmlTabName>EPC-Closure</htmlTabName>
<htmlTabIcon>log-out</htmlTabIcon>
<TestCaseRequestedList>
050201 060201 070201
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="050201">
<class>Terminate_HSS</class>
<desc>Terminate HSS</desc>
</testCase>
<testCase id="060201">
<class>Terminate_MME</class>
<desc>Terminate MME</desc>
</testCase>
<testCase id="070201">
<class>Terminate_SPGW</class>
<desc>Terminate SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,103 @@
<!--
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-05</htmlTabRef>
<htmlTabName>Test-05MHz</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
040101
030104 030105 040301 040501 040602 040642 040401 040201 030201 030202
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="030104">
<class>Initialize_eNB</class>
<desc>Initialize RRU (TDD/Band40)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030105">
<class>Initialize_eNB</class>
<desc>Initialize RCC (TDD/Band40/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate RCC</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate RRU</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040501">
<class>Ping</class>
<desc>ping (5MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>25</ping_packetloss_threshold>
</testCase>
<testCase id="040602">
<class>Iperf</class>
<desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040642">
<class>Iperf</class>
<desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
</testCaseList>
@@ -0,0 +1,110 @@
<!--
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-10</htmlTabRef>
<htmlTabName>Test-10MHz</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
000001
</TestCaseRequestedList>
<TestCaseExclusionList>
040101
030114 030115 040301 040511 040612 040652 040401 040201 030201 030202
</TestCaseExclusionList>
<testCase id="000001">
<class>IdleSleep</class>
<desc>No Test in IF4.5 for FDD-10MHz</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="030114">
<class>Initialize_eNB</class>
<desc>Initialize RRU (TDD/Band40)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030115">
<class>Initialize_eNB</class>
<desc>Initialize RCC (TDD/Band40/10MHz/info)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate RCC</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate RRU</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040511">
<class>Ping</class>
<desc>ping (10MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>25</ping_packetloss_threshold>
</testCase>
<testCase id="040612">
<class>Iperf</class>
<desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040652">
<class>Iperf</class>
<desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
</testCaseList>
@@ -0,0 +1,110 @@
<!--
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-20</htmlTabRef>
<htmlTabName>Test-20MHz</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
000001
</TestCaseRequestedList>
<TestCaseExclusionList>
040101
030124 030125 040301 040521 040622 040662 040401 040201 030201 030202
</TestCaseExclusionList>
<testCase id="000001">
<class>IdleSleep</class>
<desc>No Test in IF4.5 for FDD-20MHz</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="030124">
<class>Initialize_eNB</class>
<desc>Initialize RRU (TDD/Band40)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030125">
<class>Initialize_eNB</class>
<desc>Initialize RCC (TDD/Band40/20MHz/info)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate RCC</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate RRU</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040521">
<class>Ping</class>
<desc>ping (20MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>25</ping_packetloss_threshold>
</testCase>
<testCase id="040622">
<class>Iperf</class>
<desc>iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040662">
<class>Iperf</class>
<desc>iperf (20MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
</testCaseList>
@@ -1,217 +0,0 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<!-- Only 5MHz is tested since neither 10MHz nor 20MHz work in this configuration -->
<TestCaseRequestedList>
010101
050101 060101 070101 040101
030101 030102 040301 040501 040604 040642 040401 040201 030201 030202
050201 060201 070201
</TestCaseRequestedList>
<!--
030111 030112 040301 040511 040614 040652 040401 040201 030201 030202
030121 030122 040301 040521 040624 040662 040401 040201 030201 030202
-->
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build eNB (USRP -- Ethernet Fronthaul)</desc>
<Build_eNB_args>-t ETHERNET -w USRP -c --eNB</Build_eNB_args>
</testCase>
<testCase id="030101">
<class>Initialize_eNB</class>
<desc>Initialize RRU (FDD/Band7)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030102">
<class>Initialize_eNB</class>
<desc>Initialize RCC (FDD/Band7/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030111">
<class>Initialize_eNB</class>
<desc>Initialize RRU (FDD/Band7)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030112">
<class>Initialize_eNB</class>
<desc>Initialize RCC (FDD/Band7/10MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030121">
<class>Initialize_eNB</class>
<desc>Initialize RRU (FDD/Band7)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030122">
<class>Initialize_eNB</class>
<desc>Initialize RCC (FDD/Band7/20MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate RCC</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate RRU</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040501">
<class>Ping</class>
<desc>ping (5MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040604">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040642">
<class>Iperf</class>
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040511">
<class>Ping</class>
<desc>ping (10MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040614">
<class>Iperf</class>
<desc>iperf (10MHz - DL/32Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 32M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040652">
<class>Iperf</class>
<desc>iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040521">
<class>Ping</class>
<desc>ping (20MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040624">
<class>Iperf</class>
<desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 70M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040662">
<class>Iperf</class>
<desc>iperf (20MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="050101">
<class>Initialize_HSS</class>
<desc>Initialize HSS</desc>
</testCase>
<testCase id="060101">
<class>Initialize_MME</class>
<desc>Initialize MME</desc>
</testCase>
<testCase id="070101">
<class>Initialize_SPGW</class>
<desc>Initialize SPGW</desc>
</testCase>
<testCase id="050201">
<class>Terminate_HSS</class>
<desc>Terminate HSS</desc>
</testCase>
<testCase id="060201">
<class>Terminate_MME</class>
<desc>Terminate MME</desc>
</testCase>
<testCase id="070201">
<class>Terminate_SPGW</class>
<desc>Terminate SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,55 @@
<!--
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-tab</htmlTabRef>
<htmlTabName>Build</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
010101
050101 060101 070101 040101
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build eNB (USRP -- Ethernet Fronthaul)</desc>
<Build_eNB_args>-t ETHERNET -w USRP -c --eNB</Build_eNB_args>
</testCase>
<testCase id="050101">
<class>Initialize_HSS</class>
<desc>Initialize HSS</desc>
</testCase>
<testCase id="060101">
<class>Initialize_MME</class>
<desc>Initialize MME</desc>
</testCase>
<testCase id="070101">
<class>Initialize_SPGW</class>
<desc>Initialize SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,48 @@
<!--
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>epc-closure</htmlTabRef>
<htmlTabName>EPC-Closure</htmlTabName>
<htmlTabIcon>log-out</htmlTabIcon>
<TestCaseRequestedList>
050201 060201 070201
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="050201">
<class>Terminate_HSS</class>
<desc>Terminate HSS</desc>
</testCase>
<testCase id="060201">
<class>Terminate_MME</class>
<desc>Terminate MME</desc>
</testCase>
<testCase id="070201">
<class>Terminate_SPGW</class>
<desc>Terminate SPGW</desc>
</testCase>
</testCaseList>
@@ -0,0 +1,103 @@
<!--
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-05</htmlTabRef>
<htmlTabName>Test-05MHz</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
040101
030101 030102 040301 040501 040604 040642 040401 040201 030201 030202
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="030101">
<class>Initialize_eNB</class>
<desc>Initialize RRU (FDD/Band7)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030102">
<class>Initialize_eNB</class>
<desc>Initialize RCC (FDD/Band7/5MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate RCC</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate RRU</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040501">
<class>Ping</class>
<desc>ping (5MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040604">
<class>Iperf</class>
<desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 15M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040642">
<class>Iperf</class>
<desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
</testCaseList>
@@ -0,0 +1,110 @@
<!--
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-10</htmlTabRef>
<htmlTabName>Test-10MHz</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
000001
</TestCaseRequestedList>
<TestCaseExclusionList>
040101
030111 030112 040301 040511 040614 040652 040401 040201 030201 030202
</TestCaseExclusionList>
<testCase id="000001">
<class>IdleSleep</class>
<desc>No Test in IF4.5 for FDD-10MHz</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="030111">
<class>Initialize_eNB</class>
<desc>Initialize RRU (FDD/Band7)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030112">
<class>Initialize_eNB</class>
<desc>Initialize RCC (FDD/Band7/10MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate RCC</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate RRU</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040511">
<class>Ping</class>
<desc>ping (10MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040614">
<class>Iperf</class>
<desc>iperf (10MHz - DL/32Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 32M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040652">
<class>Iperf</class>
<desc>iperf (10MHz - UL/5Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 5M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>60</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
</testCaseList>
@@ -0,0 +1,110 @@
<!--
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-20</htmlTabRef>
<htmlTabName>Test-20MHz</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
000001
</TestCaseRequestedList>
<TestCaseExclusionList>
040101
030121 030122 040301 040521 040624 040662 040401 040201 030201 030202
</TestCaseExclusionList>
<testCase id="000001">
<class>IdleSleep</class>
<desc>No Test in IF4.5 for FDD-20MHz</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="030121">
<class>Initialize_eNB</class>
<desc>Initialize RRU (FDD/Band7)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="030122">
<class>Initialize_eNB</class>
<desc>Initialize RCC (FDD/Band7/20MHz)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate RCC</desc>
<eNB_instance>0</eNB_instance>
</testCase>
<testCase id="030202">
<class>Terminate_eNB</class>
<desc>Terminate RRU</desc>
<eNB_instance>1</eNB_instance>
</testCase>
<testCase id="040101">
<class>Initialize_UE</class>
<desc>Initialize UE</desc>
</testCase>
<testCase id="040201">
<class>Terminate_UE</class>
<desc>Terminate UE</desc>
</testCase>
<testCase id="040301">
<class>Attach_UE</class>
<desc>Attach UE</desc>
</testCase>
<testCase id="040401">
<class>Detach_UE</class>
<desc>Detach UE</desc>
</testCase>
<testCase id="040521">
<class>Ping</class>
<desc>ping (20MHz - 20 sec)</desc>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="040624">
<class>Iperf</class>
<desc>iperf (20MHz - DL/50Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 50M -t 30 -i 1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="040662">
<class>Iperf</class>
<desc>iperf (20MHz - UL/10Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 10M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
</testCaseList>
+146 -180
View File
@@ -21,7 +21,7 @@
# Author: laurent THOMAS, Lionel GAUTHIER
cmake_minimum_required (VERSION 2.8)
cmake_minimum_required (VERSION 3.0)
#############################################
# Base directories, compatible with legacy OAI building
@@ -167,13 +167,14 @@ endif()
#
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC ")
"${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC")
# add autotools definitions that were maybe used!
set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'"
"${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER}"
)
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'"
"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D${MKVER}"
)
add_definitions("-DASN_DISABLE_OER_SUPPORT")
@@ -252,6 +253,7 @@ add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace")
add_boolean_option(DISABLE_LOG_X False "Deactivate all LOG_* macros")
add_boolean_option(USRP_REC_PLAY False "Enable USRP record playback mode")
add_boolean_option(UE_NAS_USE_TUN False "Enable UE NAS TUN device instead of ue_ip.ko")
add_boolean_option(NOS1 False "Allows to run without a EPC")
add_boolean_option(BASIC_SIMULATOR False "Has to be True when building the basic simulator, False otherwise")
add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering")
@@ -260,17 +262,17 @@ add_boolean_option(ENABLE_ITTI True "ITTI is internal messaging, should remain e
set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti)
if (${ENABLE_ITTI})
add_library(ITTI
# add .h files if depend on (this one is generated)
${OCP_ITTI}/intertask_interface.cpp
${OPENAIR_DIR}/common/utils/backtrace.c
${OPENAIR_DIR}/common/utils/memory_pools.c
)
add_dependencies(ITTI rrc_flag)
set(ITTI_LIB ITTI)
set(GTPU_need_ITTI ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_eNB.c)
endif (${ENABLE_ITTI})
#############################
# ASN.1 grammar C code generation & dependancies
# ASN.1 grammar C code generation & dependencies
################################
# A difficulty: asn1c generates C code of a un-predictable list of files
# so, generate the c from asn1c once at cmake run time
@@ -278,8 +280,6 @@ endif (${ENABLE_ITTI})
# (so creating new asn.1 objects instead of modifying the object attributes)
# New C code source file, cmake must be re-run (instead of re-running make only)
#############
# set(asn1c_call "${OPENAIR_CMAKE}/tools/generate_asn1")
# set(fix_asn1c_call "${OPENAIR_CMAKE}/tools/fix_asn1")
set(asn1_generated_dir ${OPENAIR_BIN_DIR})
set(protoc_call "${OPENAIR_CMAKE}/tools/generate_protobuf")
@@ -290,7 +290,6 @@ set(protobuf_generated_dir ${OPENAIR_BIN_DIR})
add_list2_option(RRC_ASN1_VERSION "Rel15" "ASN.1 version of RRC interface" "Rel8" "Rel10" "Rel14" "CBA")
Message("RRC_ASN1_VERSION is ${RRC_ASN1_VERSION}")
if (${RRC_ASN1_VERSION} STREQUAL "Rel8")
make_version(RRC_VERSION 8 6 0)
@@ -320,34 +319,25 @@ elseif (${RRC_ASN1_VERSION} STREQUAL "Rel15")
endif (${RRC_ASN1_VERSION} STREQUAL "Rel8")
add_definitions(-DRRC_VERSION=${RRC_VERSION})
set (RRC_FULL_DIR ${asn1_generated_dir}/RRC_${RRC_ASN1_VERSION})
message("calling asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR}")
execute_process(COMMAND mkdir -p ${RRC_FULL_DIR}
COMMAND env asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR}
RESULT_VARIABLE ret
OUTPUT_QUIET
ERROR_QUIET)
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${RRC_FULL_DIR}" "${RRC_GRAMMAR}"
RESULT_VARIABLE ret)
if (NOT ${ret} STREQUAL 0)
message(FATAL_ERROR "${ret}: error")
endif (NOT ${ret} STREQUAL 0)
file(GLOB rrc_source ${RRC_FULL_DIR}/*.c)
file(GLOB rrc_h ${RRC_FULL_DIR}/*.h)
set(rrc_h ${rrc_h} ${RRC_FULL_DIR}/asn_constant.h)
set_source_files_properties(${rrc_source} PROPERTIES COMPILE_FLAGS -w) # suppress warnings from generated code
add_library(RRC_LIB ${rrc_h} ${rrc_source}
${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg.c
${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c)
include_directories ("${RRC_FULL_DIR}")
# add the command to generate the source code
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
add_custom_command (
OUTPUT ${RRC_FULL_DIR}/asn_constant.h
COMMAND mkdir -p ${RRC_FULL_DIR}
COMMAND env asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR}
add_custom_target (
rrc_flag ALL
${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${RRC_FULL_DIR}" "${RRC_GRAMMAR}"
DEPENDS ${RRC_GRAMMAR}
)
add_library(RRC_LIB ${rrc_source}
${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg.c
${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c)
add_dependencies(RRC_LIB rrc_flag)
include_directories ("${RRC_FULL_DIR}")
#NR RRC
######
@@ -361,34 +351,26 @@ endif (${NR_RRC_ASN1_VERSION} STREQUAL "NR_Rel15")
add_definitions(-DNR_RRC_VERSION=${NR_RRC_VERSION})
set (NR_RRC_FULL_DIR ${asn1_generated_dir}/${NR_RRC_ASN1_VERSION})
message("calling ASN1C_PREFIX=NR_ asn1c -pdu=all -fcompound-names -findirect-choice -gen-PER -no-gen-OER -no-gen-example -D ${NR_RRC_FULL_DIR} ${NR_RRC_GRAMMAR}")
execute_process(COMMAND mkdir -p ${NR_RRC_FULL_DIR}
COMMAND env "ASN1C_PREFIX=NR_" asn1c -fcompound-names -findirect-choice -gen-PER -no-gen-OER -no-gen-example -D ${NR_RRC_FULL_DIR} ${NR_RRC_GRAMMAR}
RESULT_VARIABLE ret
OUTPUT_QUIET
ERROR_QUIET)
#if (NOT ${ret} STREQUAL 0)
# message(FATAL_ERROR "${ret}: error")
#endif (NOT ${ret} STREQUAL 0)
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${NR_RRC_FULL_DIR}" "${NR_RRC_GRAMMAR}" "NR_" "-findirect-choice"
RESULT_VARIABLE ret)
if (NOT ${ret} STREQUAL 0)
message(FATAL_ERROR "${ret}: error")
endif ()
file(GLOB nr_rrc_source ${NR_RRC_FULL_DIR}/*.c)
file(GLOB nr_rrc_h ${NR_RRC_FULL_DIR}/*.h)
set(nr_rrc_h ${nr_rrc_h} ${NR_RRC_FULL_DIR}/NR_asn_constant.h)
#set_source_files_properties(${nr_rrc_source} PROPERTIES COMPILE_FLAGS -w) # suppress warnings from generated code
add_library(NR_RRC_LIB
${nr_rrc_h}
${nr_rrc_source}
${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1_msg.c)
add_custom_target (
nr_rrc_flag ALL
${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${NR_RRC_FULL_DIR}" "${NR_RRC_GRAMMAR}" "NR_" "-findirect-choice"
DEPENDS ${NR_RRC_GRAMMAR}
)
add_library(NR_RRC_LIB ${nr_rrc_h} ${nr_rrc_source}
${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1_msg.c
)
add_dependencies(NR_RRC_LIB nr_rrc_flag)
include_directories ("${NR_RRC_FULL_DIR}")
# add the command to generate the source code
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
add_custom_command (OUTPUT ${NR_RRC_FULL_DIR}/NR_asn_constant.h
COMMAND mkdir -p ${NR_RRC_FULL_DIR}
DEPENDS ${NR_RRC_GRAMMAR}
)
# S1AP
# Same limitation as described in RRC: unknown generated file list
@@ -425,30 +407,26 @@ endif(${S1AP_RELEASE} STREQUAL "R8")
add_definitions(-DS1AP_VERSION=${S1AP_VERSION})
set(S1AP_ASN_DIR ${S1AP_DIR}/MESSAGES/ASN1/${S1AP_RELEASE})
set(S1AP_C_DIR ${asn1_generated_dir}/S1AP_${S1AP_RELEASE})
message("calling ASN1C_PREFIX=S1AP_ asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${S1AP_C_DIR} ${S1AP_ASN_DIR}/${S1AP_ASN_FILES}")
execute_process(COMMAND mkdir -p ${S1AP_C_DIR}
COMMAND env "ASN1C_PREFIX=S1AP_" asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${S1AP_C_DIR} ${S1AP_ASN_DIR}/${S1AP_ASN_FILES}
RESULT_VARIABLE ret
OUTPUT_QUIET
ERROR_QUIET)
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" "S1AP_" -fno-include-deps
RESULT_VARIABLE ret)
if (NOT ${ret} STREQUAL 0)
message(FATAL_ERROR "${ret}: error")
endif (NOT ${ret} STREQUAL 0)
file(GLOB S1AP_source ${S1AP_C_DIR}/*.c)
file(GLOB s1ap_h ${S1AP_C_DIR}/*.h)
set(s1ap_h ${s1ap_h})
add_custom_command (
OUTPUT ${S1AP_C_DIR}/S1AP_asn_constant.h
COMMAND mkdir -p ${S1AP_C_DIR}
COMMAND env "ASN1C_PREFIX=S1AP_" asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${S1AP_C_DIR} ${S1AP_ASN_DIR}/${S1AP_ASN_FILES}
DEPENDS ${S1AP_ASN_DIR}/${S1AP_ASN_FILES}
add_custom_target (
s1ap_flag ALL
${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" "S1AP_" -fno-include-deps
DEPENDS "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}"
)
add_library(S1AP_LIB
${S1AP_source}
${S1AP_DIR}/s1ap_common.c
)
add_dependencies(S1AP_LIB rrc_flag s1ap_flag)
include_directories ("${S1AP_C_DIR}")
include_directories ("${S1AP_DIR}")
@@ -467,6 +445,7 @@ add_library(S1AP_ENB
${S1AP_DIR}/s1ap_eNB_trace.c
${S1AP_DIR}/s1ap_eNB_ue_context.c
)
add_dependencies(S1AP_ENB rrc_flag s1ap_flag)
#X2AP
# Same limitation as described in RRC/S1AP: unknown generated file list
@@ -494,24 +473,19 @@ endif(${X2AP_RELEASE} STREQUAL "R8")
add_definitions(-DX2AP_VERSION=${X2AP_VERSION})
set(X2AP_ASN_DIR ${X2AP_DIR}/MESSAGES/ASN1/${X2AP_RELEASE})
set(X2AP_C_DIR ${asn1_generated_dir}/X2AP_${X2AP_RELEASE})
message("calling ASN1C_PREFIX=X2AP_ asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${X2AP_C_DIR} ${X2AP_ASN_DIR}/${X2AP_ASN_FILES}")
execute_process(COMMAND mkdir -p ${X2AP_C_DIR}
COMMAND env "ASN1C_PREFIX=X2AP_" asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${X2AP_C_DIR} ${X2AP_ASN_DIR}/${X2AP_ASN_FILES}
RESULT_VARIABLE ret
OUTPUT_QUIET
ERROR_QUIET)
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${X2AP_C_DIR}" "${X2AP_ASN_DIR}/${X2AP_ASN_FILES}" "X2AP_" -fno-include-deps
RESULT_VARIABLE ret)
if (NOT ${ret} STREQUAL 0)
message(FATAL_ERROR "${ret}: error")
endif (NOT ${ret} STREQUAL 0)
file(GLOB X2AP_source ${X2AP_C_DIR}/*.c)
file(GLOB x2ap_h ${X2AP_C_DIR}/*.h)
set(x2ap_h ${x2ap_h})
add_custom_command (
OUTPUT ${X2AP_C_DIR}/X2AP_asn_constant.h
COMMAND mkdir -p ${X2AP_C_DIR}
COMMAND env "ASN1C_PREFIX=X2AP_" asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${X2AP_C_DIR} ${X2AP_ASN_DIR}/${X2AP_ASN_FILES}
add_custom_target (
x2_flag ALL
COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${X2AP_C_DIR}" "${X2AP_ASN_DIR}/${X2AP_ASN_FILES}" "X2AP_" -fno-include-deps
DEPENDS ${X2AP_ASN_DIR}/${X2AP_ASN_FILES}
)
@@ -519,6 +493,7 @@ add_library(X2AP_LIB
${X2AP_source}
${X2AP_DIR}/x2ap_common.c
)
add_dependencies(X2AP_LIB rrc_flag x2_flag)
include_directories ("${X2AP_C_DIR}")
include_directories ("${X2AP_DIR}")
@@ -532,6 +507,7 @@ add_library(X2AP_ENB
${X2AP_DIR}/x2ap_eNB_management_procedures.c
${X2AP_DIR}/x2ap_eNB_generate_messages.c
)
add_dependencies(X2AP_ENB rrc_flag x2_flag)
# Hardware dependant options
###################################
@@ -539,6 +515,10 @@ add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4
add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4")
add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR")
if (NOT ${RF_BOARD} STREQUAL "None")
add_definitions(-DMANAGED_RF=1)
endif()
add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET")
#NOKIA config enhancement
@@ -639,6 +619,8 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE
add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} )
set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c)
##########################################################
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
@@ -661,7 +643,6 @@ add_boolean_option(NAS_NETLINK False "useless ??? Must be True to compile nasmes
add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????")
add_boolean_option(USE_MME False "this flag is used only one time in lte-softmodem.c")
add_list_string_option(PACKAGE_NAME "NotDefined" "As per attribute name")
add_boolean_option(MESSAGE_CHART_GENERATOR False "For generating sequence diagrams")
add_boolean_option(MESSAGE_CHART_GENERATOR_RLC_MAC False "trace RLC-MAC exchanges in sequence diagrams")
add_boolean_option(MESSAGE_CHART_GENERATOR_PHY False "trace some PHY exchanges in sequence diagrams")
@@ -669,11 +650,7 @@ add_boolean_option(MESSAGE_CHART_GENERATOR_PHY False "trace some PHY exchang
add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION with max 256 UE")
add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE")
add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE")
########################
# Include order
##########################
add_boolean_option(ENB_MODE True "Swap the include directories between openair2 and openair3" )
add_boolean_option(UESIM_EXPANSION False "enable UESIM_EXPANSION with max 256 UE")
##########################
# SCHEDULING/REAL-TIME/PERF options
@@ -694,7 +671,7 @@ add_boolean_option(EXMIMO_IOT True "????")
add_boolean_option(LOCALIZATION False "???")
add_integer_option(MAX_NUM_CCs 1 "????")
add_boolean_option(MU_RECEIVER False "????")
add_boolean_option(PHYSIM True "for L1 simulators (dlsim, ulsim, ...)")
add_boolean_option(PHYSIM False "for L1 simulators (dlsim, ulsim, ...)")
add_boolean_option(PHY_CONTEXT True "not clear: must remain False for dlsim")
add_boolean_option(PHY_EMUL False "not clear: must remain False for dlsim")
add_boolean_option(SMBV False "Rohde&Schwarz SMBV100A vector signal generator")
@@ -776,19 +753,13 @@ include_directories("${OPENAIR_BIN_DIR}")
#include_directories("${include_dirs_all}")
# Legacy exact order
if(ENB_MODE)
include_directories("${OPENAIR2_DIR}/COMMON")
include_directories("${OPENAIR2_DIR}/UTIL")
include_directories("${OPENAIR2_DIR}/UTIL/LOG")
include_directories("${OPENAIR3_DIR}/COMMON")
include_directories("${OPENAIR3_DIR}/UTILS")
else()
include_directories("${OPENAIR3_DIR}/COMMON")
include_directories("${OPENAIR3_DIR}/UTILS")
include_directories("${OPENAIR2_DIR}/COMMON")
include_directories("${OPENAIR2_DIR}/UTIL")
include_directories("${OPENAIR2_DIR}/UTIL/LOG")
endif()
include_directories("${OPENAIR2_DIR}/COMMON")
include_directories("${OPENAIR2_DIR}/UTIL")
include_directories("${OPENAIR2_DIR}/UTIL/LOG")
include_directories("${OPENAIR3_DIR}/COMMON")
include_directories("${OPENAIR3_DIR}/UTILS")
include_directories("${NFAPI_DIR}/nfapi/public_inc")
include_directories("${NFAPI_DIR}/common/public_inc")
include_directories("${NFAPI_DIR}/pnf/public_inc")
@@ -927,6 +898,7 @@ add_library(FLEXRAN_AGENT
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c
)
add_dependencies(FLEXRAN_AGENT rrc_flag)
set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT)
#include_directories(${OPENAIR2_DIR}/ENB_APP)
@@ -992,6 +964,7 @@ set(UTIL_SRC
# ${OPENAIR2_DIR}/UTIL/OTG/otg_rx.c
)
add_library(UTIL ${UTIL_SRC})
add_dependencies(UTIL rrc_flag)
#set(OMG_SUMO_SRC
# ${OPENAIR2_DIR}/UTIL/OMG/client_traci_OMG.c
@@ -1031,7 +1004,7 @@ set(SCHED_SRC
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c
)
add_library(SCHED_LIB ${SCHED_SRC})
add_dependencies(SCHED_LIB rrc_flag)
set(SCHED_NR_SRC
${OPENAIR1_DIR}/SCHED_NR/fapi_nr_l1.c
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
@@ -1045,6 +1018,7 @@ set(SCHED_SRC_RU
${OPENAIR1_DIR}/SCHED/prach_procedures.c
)
add_library(SCHED_RU_LIB ${SCHED_SRC_RU})
add_dependencies(SCHED_RU_LIB rrc_flag)
set(SCHED_SRC_UE
${OPENAIR1_DIR}/SCHED_UE/phy_procedures_lte_ue.c
@@ -1054,7 +1028,7 @@ set(SCHED_SRC_UE
${OPENAIR1_DIR}/SCHED_UE/srs_pc.c
)
add_library(SCHED_UE_LIB ${SCHED_SRC_UE})
add_dependencies(SCHED_UE_LIB rrc_flag)
set(SCHED_SRC_NR_UE
${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
@@ -1116,6 +1090,7 @@ set(NFAPI_USER_SRC
${NFAPI_USER_DIR}/nfapi_vnf.c
)
add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC})
add_dependencies(NFAPI_USER_LIB rrc_flag)
include_directories(${NFAPI_USER_DIR})
# Layer 1
@@ -1158,11 +1133,7 @@ set(PHY_LDPCSRC
)
add_library(coding MODULE ${PHY_TURBOSRC} )
set(PHY_SRC_COMMON
# depend on code generation from asn1c
${RRC_FULL_DIR}/asn_constant.h
# actual source
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slss.c
@@ -1216,7 +1187,6 @@ set(PHY_SRC_COMMON
)
set(PHY_SRC
# actual source
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pss.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss_gen.c
@@ -1244,7 +1214,6 @@ set(PHY_SRC
)
set(PHY_SRC_RU
# actual source
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c
@@ -1259,7 +1228,6 @@ set(PHY_SRC_RU
)
set(PHY_SRC_UE
# actual source
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/sss_ue.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss_gen.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
@@ -1301,9 +1269,6 @@ set(PHY_SRC_UE
)
set(PHY_NR_SRC
# depend on code generation from asn1c
${RRC_FULL_DIR}/asn_constant.h
# actual source
${OPENAIR1_DIR}/PHY/INIT/nr_init.c
${OPENAIR1_DIR}/PHY/INIT/nr_parms.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_pss.c
@@ -1314,6 +1279,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_coding.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
@@ -1335,9 +1301,6 @@ set(PHY_SRC_UE
)
set(PHY_NR_UE_SRC
# depend on code generation from asn1c
${RRC_FULL_DIR}/asn_constant.h
# actual source
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_nr.c
${OPENAIR1_DIR}/PHY/INIT/nr_parms.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -1347,6 +1310,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
@@ -1396,11 +1360,15 @@ if (${COMPILATION_AVX2} STREQUAL "True")
endif ()
add_library(PHY_COMMON ${PHY_SRC_COMMON})
add_dependencies(PHY_COMMON rrc_flag)
add_library(PHY ${PHY_SRC})
add_dependencies(PHY rrc_flag)
add_library(PHY_UE ${PHY_SRC_UE})
add_dependencies(PHY_UE rrc_flag)
add_library(PHY_NR ${PHY_NR_SRC})
add_library(PHY_NR_UE ${PHY_NR_UE_SRC})
add_library(PHY_RU ${PHY_SRC_RU})
add_dependencies(PHY_RU rrc_flag)
#Library for mex functions
#########################3
@@ -1614,6 +1582,7 @@ add_library(L2
${MAC_SRC}
${ENB_APP_SRC}
)
add_dependencies(L2 rrc_flag s1ap_flag x2_flag)
add_library(MAC_NR
${MAC_NR_SRC}
@@ -1628,52 +1597,26 @@ add_library(L2_NR
${MAC_NR_SRC}
${GNB_APP_SRC}
)
add_dependencies(S1AP_LIB nr_rrc_flag s1ap_flag)
add_library(L2_UE
${L2_SRC_UE}
${MAC_SRC_UE}
#${MAC_NR_SRC_UE}
)
if (NOT ${NOS1})
target_compile_definitions(L2_UE PUBLIC -DPDCP_USE_NETLINK)
endif()
add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag)
add_library( NR_L2_UE
#${L2_SRC_UE}
${NR_L2_SRC_UE}
${MAC_NR_SRC_UE}
#${MAC_SRC_UE}
)
set ( NR_LTE_UE_REUSE_SRC
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_timefreq.c
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c
#${OPENAIR1_DIR}/SCHED_UE/phy_procedures_lte_ue.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c
#${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pmch_common.c
#${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_cell_spec.c
#${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c
#${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/prach_common.c
# ${OPENAIR1_DIR}/PHY/INIT/lte_init_ue.c
${OPENAIR1_DIR}/PHY/CODING/crc_byte.c
${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c
${OPENAIR1_DIR}/PHY/CODING/viterbi.c
#${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/phich_common.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c
# ${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_est_freq_offset.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c
#${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
#${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c
)
add_library( NR_LTE_UE_REUSE_LIB
${NR_LTE_UE_REUSE_SRC}
)
)
add_library( MAC_NR_COMMON
${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.c
)
include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE")
include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE")
@@ -1702,6 +1645,7 @@ set (GTPV1U_SRC
${GTPV1U_DIR}/gtpv1u_teid_pool.c
)
add_library(GTPV1U ${GTPV1U_SRC})
add_dependencies(GTPV1U rrc_flag)
set(SCTP_SRC
${OPENAIR3_DIR}/SCTP/sctp_common.c
@@ -1709,8 +1653,10 @@ set(SCTP_SRC
${OPENAIR3_DIR}/SCTP/sctp_eNB_itti_messaging.c
)
add_library(SCTP_CLIENT ${SCTP_SRC})
add_dependencies(SCTP_CLIENT rrc_flag)
add_library(UDP ${OPENAIR3_DIR}/UDP/udp_eNB_task.c)
add_dependencies(UDP rrc_flag)
set(NAS_SRC ${OPENAIR3_DIR}/NAS/)
@@ -1959,6 +1905,7 @@ if(NAS_UE)
${libnas_ue_esm_OBJS}
${libnas_ue_esm_sap_OBJS}
)
add_dependencies(LIB_NAS_UE rrc_flag)
set(NAS_UE_LIB LIB_NAS_UE)
include_directories(${NAS_SRC}UE)
@@ -2219,8 +2166,6 @@ add_definitions(-DASN1_MINIMUM_VERSION=924)
###################################################
add_executable(lte-softmodem
${rrc_h}
${s1ap_h}
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/RT/USER/lte-enb.c
${OPENAIR_TARGETS}/RT/USER/lte-ru.c
@@ -2242,6 +2187,7 @@ add_executable(lte-softmodem
${CONFIG_SOURCES}
${SHLIB_LOADER_SOURCES}
)
add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag)
target_link_libraries (lte-softmodem
-Wl,--start-group
@@ -2258,8 +2204,6 @@ target_link_libraries (lte-softmodem ${T_LIB})
# lte-softmodem-nos1 is both eNB and UE implementation
###################################################
add_executable(lte-softmodem-nos1
${rrc_h}
${s1ap_h}
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/RT/USER/lte-enb.c
${OPENAIR_TARGETS}/RT/USER/lte-ru.c
@@ -2296,8 +2240,6 @@ target_link_libraries (lte-softmodem-nos1 ${T_LIB})
#######################################
add_executable(lte-uesoftmodem
${rrc_h}
${s1ap_h}
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/RT/USER/lte-ue.c
${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c
@@ -2319,6 +2261,10 @@ add_executable(lte-uesoftmodem
${SHLIB_LOADER_SOURCES}
)
add_dependencies(lte-uesoftmodem rrc_flag s1ap_flag x2_flag)
if (NOT ${NOS1})
target_compile_definitions(lte-uesoftmodem PRIVATE -DPDCP_USE_NETLINK)
endif()
target_link_libraries (lte-uesoftmodem
-Wl,--start-group
RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU
@@ -2334,8 +2280,6 @@ target_link_libraries (lte-uesoftmodem ${T_LIB})
# lte-uesoftmodem-nos1 is UE implementation
###################################################
add_executable(lte-uesoftmodem-nos1
${rrc_h}
${s1ap_h}
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/RT/USER/lte-ue.c
${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c
@@ -2358,6 +2302,7 @@ add_executable(lte-uesoftmodem-nos1
${SHLIB_LOADER_SOURCES}
)
add_dependencies(lte-uesoftmodem-nos1 rrc_flag s1ap_flag x2_flag)
target_link_libraries (lte-uesoftmodem-nos1
-Wl,--start-group
RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU ${RAL_LIB} ${ITTI_LIB}
@@ -2400,7 +2345,7 @@ target_link_libraries (nr-softmodem
-Wl,--start-group
UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB}
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)
@@ -2441,7 +2386,7 @@ target_link_libraries (nr-softmodem-nos1
-Wl,--start-group
UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${MIH_LIB}
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)
@@ -2457,11 +2402,10 @@ add_executable(nr-uesoftmodem
${rrc_h}
${s1ap_h}
# ${OPENAIR_BIN_DIR}/messages_xml.h
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/RT/USER/nr-ue.c
${OPENAIR_TARGETS}/RT/USER/nr-uesoftmodem.c
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
${OPENAIR_DIR}/executables//nr-uesoftmodem.c
${OPENAIR_DIR}/executables/nr-ue.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
# ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
@@ -2476,7 +2420,7 @@ add_executable(nr-uesoftmodem
target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_UE PHY_RU LFDS NR_L2_UE #NR_LTE_UE_REUSE_LIB
RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_UE PHY_RU LFDS NR_L2_UE MAC_NR_COMMON
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
@@ -2510,7 +2454,7 @@ add_executable(nr-uesoftmodem-nos1
target_link_libraries (nr-uesoftmodem-nos1
-Wl,--start-group
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_UE PHY_UE PHY_RU LFDS NR_L2_UE
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_UE PHY_UE PHY_RU LFDS NR_L2_UE MAC_NR_COMMON
${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
@@ -2561,36 +2505,56 @@ target_link_libraries (dlsim_tm4
pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB}
)
add_executable(polartest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c)
add_executable(polartest
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c
${OPENAIR_DIR}/common/utils/backtrace.c)
target_link_libraries(polartest SIMU PHY PHY_NR PHY_COMMON m ${ATLAS_LIBRARIES})
add_executable(smallblocktest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c)
target_link_libraries(smallblocktest SIMU PHY PHY_NR PHY_COMMON m ${ATLAS_LIBRARIES})
add_executable(ldpctest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c)
add_executable(ldpctest
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
${OPENAIR_DIR}/common/utils/backtrace.c)
target_link_libraries(ldpctest SIMU PHY PHY_NR m ${ATLAS_LIBRARIES})
add_executable(nr_dlschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c ${T_SOURCE})
add_executable(nr_dlschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c
${OPENAIR_DIR}/common/utils/backtrace.c
${T_SOURCE})
target_link_libraries(nr_dlschsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
add_executable(nr_pbchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c ${T_SOURCE})
add_executable(nr_pbchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c
${OPENAIR_DIR}/common/utils/backtrace.c
${T_SOURCE})
target_link_libraries(nr_pbchsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
add_executable(nr_dlsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c ${T_SOURCE})
target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
add_executable(nr_dlsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c
${OPENAIR_DIR}/common/utils/backtrace.c
${T_SOURCE})
target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
add_executable(nr_ulschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
${OPENAIR_DIR}/common/utils/backtrace.c
${T_SOURCE})
target_link_libraries(nr_ulschsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
add_executable(${myExe}
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
${OPENAIR_DIR}/common/utils/backtrace.c
${XFORMS_SOURCE}
${T_SOURCE}
${CONFIG_SOURCES}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries (${myExe}
-Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group
pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl
)
@@ -2660,7 +2624,7 @@ if (${T_TRACER})
#all "add_executable" definitions (except tests, rb_tool, updatefw)
lte-softmodem lte-softmodem-nos1 lte-uesoftmodem lte-uesoftmodem-nos1
nr-softmodem nr-softmodem-nos1 nr-uesoftmodem nr-uesoftmodem-nos1
dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim
dlsim_tm4 nr_dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim
pdcchsim pucchsim prachsim syncsim ulsim
ldpctest polartest
#all "add_library" definitions
@@ -2710,7 +2674,9 @@ L2
L2_NR
L2_UE
NR_L2_UE
NR_LTE_UE_REUSE_LIB
MAC_NR_COMMON
MAC_NR
MAC_UE_NR
CN_UTILS
GTPV1U
SCTP_CLIENT
@@ -2776,7 +2742,7 @@ endfunction(make_driver name dir src)
# nashmesh module
################
list(APPEND nasmesh_src device.c common.c ioctl.c classifier.c tool.c mesh.c)
set(module_cc_opt "${module_cc_opt} -DNAS_NETLINK -DPDCP_USE_NETLINK")
set(module_cc_opt "${module_cc_opt} -DNAS_NETLINK -DPDCP_USE_NETLINK -D${MKVER}")
# legacy Makefile was using NAS_NETLINK flag, but other drivers the hereafter flag
# so, this cmake use OAI_NW_DRIVER_USE_NETLINK everywhere
if (OAI_NW_DRIVER_USE_NETLINK)
+44 -9
View File
@@ -1057,8 +1057,8 @@
(Test2: PBCH and synchronization, 106PBR),
(Test3: PBCH-only, 217 PRB),
(Test4: PBCH and synchronization, 217 RPB),
(Test5: PBCH-only, 217 PRB),
(Test6: PBCH and synchronization, 217 PRB)</desc>
(Test5: PBCH-only, 273 PRB),
(Test6: PBCH and synchronization, 273 PRB)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
@@ -1071,24 +1071,59 @@
-s0 -S1 -n10 -I -R217
-s0 -S1 -n1000 -R273
-s0 -S1 -n10 -I -R273</main_exec_args>
<tags>nr_pbchsim.test1 nr_pbchsim.test2</tags>
<tags>nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6</tags>
<search_expr_true>PBCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
<testCase id="015105">
<testCase id="015105">
<class>execution</class>
<desc>nr_dlsim Test cases. (Test1: 106 PRB),
(Test2: 217 PRB),
(Test3: 273 PRB)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/nr_dlsim.Rel15</main_exec>
<main_exec_args>-n100 -R106
-n100 -R217
-n100 -R273</main_exec_args>
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3</tags>
<search_expr_true>PDCCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
<testCase id="015106">
<class>execution</class>
<desc>nr_dlschsim Test cases. (Test1: 106 PRB),
(Test2: 217 PRB),
(Test3: 273 PRB)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/nr_dlschsim.Rel15</main_exec>
<main_exec_args>-R 106 -m9 -s13 -n100
-R 217 -m15 -s15 -n100
-R 273 -m19 -s20 -n100</main_exec_args>
<tags>nr_dlschsim.test1 nr_dlschsim.test2 nr_dlschsim.test3</tags>
<search_expr_true>PDSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
<testCase id="015107">
<class>execution</class>
<desc>shortblocktest Test cases. (Test1: 3 bits),
(Test2: 6 bits)
(Test3: 7 bits)
(Test4: 11 bits)
</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/smallblocktest.Rel15</main_exec>
<main_exec_args>-l 3
-l 6
+36 -41
View File
@@ -43,10 +43,10 @@ conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
MSC_GEN=0
XFORMS="True"
UE_EXPANSION="False"
UESIM_EXPANSION="False"
PRINT_STATS="False"
VCD_TIMING="False"
DEADLINE_SCHEDULER_FLAG_USER="False"
FORCE_DEADLINE_SCHEDULER_FLAG_USER=""
DEADLINE_SCHEDULER_FLAG_USER=""
CPU_AFFINITY_FLAG_USER="False" #Only valid when lowlatecy flag is set to False
REL="Rel15"
NR_REL="NR_Rel15"
@@ -78,7 +78,7 @@ trap handle_ctrl_c INT
function print_help() {
echo_info "
This program installs OpenAirInterface Software
You should have ubuntu 14.xx, updated, and the Linux kernel >= 3.14
You should have ubuntu 16.xx or 18.04 updated
Options
-h
This help
@@ -116,7 +116,7 @@ Options
Rel8 limits the implementation to 3GPP Release 8 version
Rel10 limits the implementation to 3GPP Release 10 version
-w | --hardware
EXMIMO, USRP, BLADERF, ETHERNET, LMSSDR, ADRV9371_ZC706, None (Default)
EXMIMO, USRP, BLADERF, ETHERNET, LMSSDR, ADRV9371_ZC706, SIMU, None (Default)
Adds this RF board support (in external packages installation and in compilation)
-t | --transport protocol
ETHERNET , None
@@ -175,6 +175,9 @@ Options
--basic-simulator
Generates a basic [1 UE + 1 eNB + no channel] simulator.
See targets/ARCH/tcp_bridge/README.tcp_bridge_oai for documentation.
--rfsimulator
Generate virtual RF driver
to use it, set the environement variable RFSIMULATOR to \"enb\" in the eNB and to the eNB IP address in the UEs
Usage (first build):
NI/ETTUS B201 + COTS UE : ./build_oai -I --eNB -x --install-system-files -w USRP
Usage (Regular):
@@ -250,7 +253,7 @@ function main() {
-w | --hardware)
HW="$2" #"${i#*=}"
# Use OAI_USRP as the key word USRP is used inside UHD driver
if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" -a "$HW" != "ADRV9371_ZC706" ] ; then
if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" -a "$HW" != "ADRV9371_ZC706" -a "$HW" != "SIMU" ] ; then
echo_fatal "Unknown HW type $HW will exit..."
else
if [ "$HW" == "USRP" ] ; then
@@ -265,6 +268,9 @@ function main() {
if [ "$HW" == "LMSSDR" ] ; then
HW="OAI_LMSSDR"
fi
if [ "$HW" == "SIMU" ] ; then
HW="OAI_SIMU"
fi
echo_info "Setting hardware to: $HW"
fi
shift 2;;
@@ -331,13 +337,13 @@ function main() {
BUILD_DOXYGEN=1
echo_info "Will build doxygen support"
shift;;
--disable-deadline)
FORCE_DEADLINE_SCHEDULER_FLAG_USER="False"
echo_info "Disabling the usage of deadline scheduler"
shift 1;;
--enable-deadline)
FORCE_DEADLINE_SCHEDULER_FLAG_USER="True"
echo_info "Enabling the usage of deadline scheduler"
--disable-deadline)
DEADLINE_SCHEDULER_FLAG_USER="False"
echo_info "Disabling the usage of deadline scheduler"
shift 1;;
--enable-deadline)
DEADLINE_SCHEDULER_FLAG_USER="True"
echo_info "Enabling the usage of deadline scheduler"
shift 1;;
--enable-cpu-affinity)
CPU_AFFINITY_FLAG_USER="True"
@@ -400,7 +406,11 @@ function main() {
BASIC_SIMULATOR=1
echo_info "Compiling the basic simulator"
shift 1;;
-h | --help)
--rfsimulator)
RFSIMULATOR=true
echo_info "Compiling the RF simulator"
shift 1;;
-h | --help)
print_help
exit 1;;
*)
@@ -441,33 +451,18 @@ function main() {
fi
fi
echo_info "RF HW set to $HW"
#Now we set flags to enable deadline scheduler settings
#By default: USRP: disable,
#By default: BLADERF: enable,
#By default: EXMIMO: enable
if [ "$FORCE_DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then
if [ "$HW" = "EXMIMO" ] ; then
DEADLINE_SCHEDULER_FLAG_USER="True"
elif [ "$HW" = "ETHERNET" ] ; then
DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "OAI_USRP" ] ; then
DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "OAI_ADRV9371_ZC706" ] ; then
DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "OAI_BLADERF" ] ; then
DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "OAI_LMSSDR" ] ; then
DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "None" ] ; then
DEADLINE_SCHEDULER_FLAG_USER="False"
else
echo_error "Unknown HW type $HW. Exiting now..."
exit
fi
else
DEADLINE_SCHEDULER_FLAG_USER=$FORCE_DEADLINE_SCHEDULER_FLAG_USER
fi
echo_info "RF HW set to $HW"
# If the user doesn't specify the Linux scheduler to use, we set a value
if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then
case "$HW" in
"EXMIMO")
DEADLINE_SCHEDULER_FLAG_USER="True"
;;
*)
DEADLINE_SCHEDULER_FLAG_USER="False"
;;
esac
fi
#Disable CPU Affinity for deadline scheduler
if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "True" ] ; then
@@ -696,7 +691,7 @@ function main() {
echo_info "Compiling unitary tests simulators"
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
simlist="dlsim ulsim polartest ldpctest smallblocktest nr_pbchsim nr_dlschsim nr_dlsim"
simlist="dlsim ulsim polartest ldpctest smallblocktest nr_pbchsim nr_dlschsim nr_dlsim nr_ulschsim"
for f in $simlist ; do
compilations \
phy_simulators $f \
+15
View File
@@ -0,0 +1,15 @@
#!/bin/bash
GENERATED_FULL_DIR=$1
shift
ASN1_SOURCE_DIR=$1
shift
export ASN1C_PREFIX=$1
shift
options=$*
done_flag="$GENERATED_FULL_DIR"/done
if [ "$done_flag" -ot $ASN1_SOURCE_DIR ] ; then
rm -f "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}*.c "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}*.h
mkdir -p "$GENERATED_FULL_DIR"
asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example $options -D $GENERATED_FULL_DIR $ASN1_SOURCE_DIR |& egrep -v "^Copied|^Compiled" | sort -u
fi
touch $done_flag
+7
View File
@@ -23,9 +23,16 @@
#ifndef BACKTRACE_H_
#define BACKTRACE_H_
#ifdef __cplusplus
extern "C" {
#endif
void display_backtrace(void);
void backtrace_handle_signal(siginfo_t *info);
#ifdef __cplusplus
}
#endif
#endif /* BACKTRACE_H_ */
+8
View File
@@ -0,0 +1,8 @@
all: measurement_display thread-pool-test
measurement_display: measurement_display.c thread-pool.h
gcc measurement_display.c -I /data/openairinterface5g.nr/common/utils/ -I. /data/openairinterface5g.nr/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o measurement_display
thread-pool-test: thread-pool.c thread-pool.h
gcc -g thread-pool.c -I /data/openairinterface5g.nr/common/utils/ -I. /data/openairinterface5g.nr/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test
@@ -0,0 +1,61 @@
/*
Author: Laurent THOMAS, Open Cells
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#define __USE_GNU
#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <stdint.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "thread-pool.h"
#define SEP "\t"
uint64_t cpuCyclesMicroSec;
int main(int argc, char *argv[]) {
if(argc != 2) {
printf("Need one paramter: the trace Linux pipe (fifo)");
exit(1);
}
mkfifo(argv[1],0666);
int fd=open(argv[1], O_RDONLY);
if ( fd == -1 ) {
perror("open read mode trace file:");
exit(1);
}
uint64_t deb=rdtsc();
usleep(100000);
cpuCyclesMicroSec=(rdtsc()-deb)/100000;
printf("Cycles per µs: %lu\n",cpuCyclesMicroSec);
printf("Key" SEP "delay to process" SEP "processing time" SEP "delay to be read answer\n");
notifiedFIFO_elt_t doneRequest;
while ( 1 ) {
if ( read(fd,&doneRequest, sizeof(doneRequest)) == sizeof(doneRequest)) {
printf("%lu" SEP "%lu" SEP "%lu" SEP "%lu" "\n",
doneRequest.key,
(doneRequest.startProcessingTime-doneRequest.creationTime)/cpuCyclesMicroSec,
(doneRequest.endProcessingTime-doneRequest.startProcessingTime)/cpuCyclesMicroSec,
(doneRequest.returnTime-doneRequest.endProcessingTime)/cpuCyclesMicroSec
);
} else {
printf("no measurements\n");
sleep(1);
}
}
}
+230
View File
@@ -0,0 +1,230 @@
/*
Author: Laurent THOMAS, Open Cells
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#define _GNU_SOURCE
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/sysinfo.h>
#include <threadPool/thread-pool.h>
void displayList(notifiedFIFO_t *nf) {
int n=0;
notifiedFIFO_elt_t *ptr=nf->outF;
while(ptr) {
printf("element: %d, key: %lu\n",++n,ptr->key);
ptr=ptr->next;
}
printf("End of list: %d elements\n",n);
}
static inline notifiedFIFO_elt_t *pullNotifiedFifoRemember( notifiedFIFO_t *nf, struct one_thread *thr) {
mutexlock(nf->lockF);
while(!nf->outF)
condwait(nf->notifF, nf->lockF);
notifiedFIFO_elt_t *ret=nf->outF;
nf->outF=nf->outF->next;
if (nf->outF==NULL)
nf->inF=NULL;
// For abort feature
thr->runningOnKey=ret->key;
thr->abortFlag=false;
mutexunlock(nf->lockF);
return ret;
}
void *one_thread(void *arg) {
struct one_thread *myThread=(struct one_thread *) arg;
struct thread_pool *tp=myThread->pool;
// configure the thread core assignment
// TBD: reserve the core for us exclusively
if ( myThread->coreID >= 0 && myThread->coreID < get_nprocs_conf()) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(myThread->coreID, &cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
}
//Configure the thread scheduler policy for Linux
struct sched_param sparam= {0};
sparam.sched_priority = sched_get_priority_max(SCHED_RR);
pthread_setschedparam(pthread_self(), SCHED_RR, &sparam);
// set the thread name for debugging
sprintf(myThread->name,"Tpool_%d",myThread->coreID);
pthread_setname_np(pthread_self(), myThread->name );
// Infinite loop to process requests
do {
notifiedFIFO_elt_t *elt=pullNotifiedFifoRemember(&tp->incomingFifo, myThread);
if (tp->measurePerf) elt->startProcessingTime=rdtsc();
elt->processingFunc(NotifiedFifoData(elt));
if (tp->measurePerf) elt->endProcessingTime=rdtsc();
if (elt->reponseFifo) {
// Check if the job is still alive, else it has been aborted
mutexlock(tp->incomingFifo.lockF);
if (myThread->abortFlag)
delNotifiedFIFO_elt(elt);
else
pushNotifiedFIFO(elt->reponseFifo, elt);
mutexunlock(tp->incomingFifo.lockF);
}
} while (true);
}
void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
memset(pool,0,sizeof(*pool));
char *measr=getenv("threadPoolMeasurements");
pool->measurePerf=performanceMeas;
// force measurement if the output is defined
pool->measurePerf=measr!=NULL;
if (measr) {
mkfifo(measr,0666);
AssertFatal(-1 != (pool->dummyTraceFd=
open(measr, O_RDONLY| O_NONBLOCK)),"");
AssertFatal(-1 != (pool->traceFd=
open(measr, O_WRONLY|O_APPEND|O_NOATIME|O_NONBLOCK)),"");
} else
pool->traceFd=-1;
//Configure the thread scheduler policy for Linux
struct sched_param sparam= {0};
sparam.sched_priority = sched_get_priority_max(SCHED_RR)-1;
pthread_setschedparam(pthread_self(), SCHED_RR, &sparam);
pool->activated=true;
initNotifiedFIFO(&pool->incomingFifo);
char *saveptr, * curptr;
pool->nbThreads=0;
pool->restrictRNTI=false;
curptr=strtok_r(params,",",&saveptr);
while ( curptr!=NULL ) {
int c=toupper(curptr[0]);
switch (c) {
case 'U':
pool->restrictRNTI=true;
break;
case 'N':
pool->activated=false;
break;
default:
pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread));
pool->allthreads->next=pool->allthreads;
printf("create a thread for core %d\n", atoi(curptr));
pool->allthreads->coreID=atoi(curptr);
pool->allthreads->id=pool->nbThreads;
pool->allthreads->pool=pool;
pthread_create(&pool->allthreads->threadID, NULL, one_thread, (void *)pool->allthreads);
pool->nbThreads++;
}
curptr=strtok_r(NULL,",",&saveptr);
}
if (pool->activated && pool->nbThreads==0) {
printf("No servers created in the thread pool, exit\n");
exit(1);
}
}
#ifdef TEST_THREAD_POOL
struct testData {
int id;
char txt[30];
};
void processing(void *arg) {
struct testData *in=(struct testData *)arg;
printf("doing: %d, %s, in thr %ld\n",in->id, in->txt,pthread_self() );
sprintf(in->txt,"Done by %ld, job %d", pthread_self(), in->id);
usleep(rand()%100);
printf("done: %d, %s, in thr %ld\n",in->id, in->txt,pthread_self() );
}
int main() {
notifiedFIFO_t myFifo;
initNotifiedFIFO(&myFifo);
pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 1234,NULL,NULL));
for(int i=10; i>1; i--) {
pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 1000+i,NULL,NULL));
}
displayList(&myFifo);
notifiedFIFO_elt_t *tmp=pullNotifiedFIFO(&myFifo);
printf("pulled: %lu\n", tmp->key);
displayList(&myFifo);
tmp=pullNotifiedFIFO(&myFifo);
printf("pulled: %lu\n", tmp->key);
displayList(&myFifo);
abortNotifiedFIFO(&myFifo,1005);
printf("aborted 1005\n");
displayList(&myFifo);
pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 12345678, NULL, NULL));
displayList(&myFifo);
abortNotifiedFIFO(&myFifo,12345678);
printf("aborted 12345678\n");
displayList(&myFifo);
do {
tmp=pollNotifiedFIFO(&myFifo);
if (tmp) {
printf("pulled: %lu\n", tmp->key);
displayList(&myFifo);
} else
printf("Empty list \n");
} while(tmp);
tpool_t pool;
char params[]="1,2,3,u";
initTpool(params,&pool, true);
notifiedFIFO_t worker_back;
initNotifiedFIFO(&worker_back);
for (int i=0; i <1000 ; i++) {
notifiedFIFO_elt_t *work=newNotifiedFIFO_elt(sizeof(struct testData), i, &worker_back, processing);
struct testData *x=(struct testData *)NotifiedFifoData(work);
x->id=i;
pushTpool(&pool, work);
}
do {
tmp=pullTpool(&worker_back,&pool);
if (tmp) {
struct testData *dd=NotifiedFifoData(tmp);
printf("Result: %s\n",dd->txt);
delNotifiedFIFO_elt(tmp);
} else
printf("Empty list \n");
abortTpool(&pool,510);
} while(tmp);
return 0;
}
#endif
+244
View File
@@ -0,0 +1,244 @@
/*
Author: Laurent THOMAS, Open Cells
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#include <stdbool.h>
#include <stdint.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <assertions.h>
#include <LOG/log.h>
#ifdef DEBUG
#define THREADINIT PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
#else
#define THREADINIT PTHREAD_MUTEX_INITIALIZER
#endif
#define mutexinit(mutex) AssertFatal(pthread_mutex_init(&mutex,NULL)==0,"");
#define condinit(signal) AssertFatal(pthread_cond_init(&signal,NULL)==0,"");
#define mutexlock(mutex) AssertFatal(pthread_mutex_lock(&mutex)==0,"");
#define mutextrylock(mutex) pthread_mutex_trylock(&mutex)
#define mutexunlock(mutex) AssertFatal(pthread_mutex_unlock(&mutex)==0,"");
#define condwait(condition, mutex) AssertFatal(pthread_cond_wait(&condition, &mutex)==0,"");
#define condbroadcast(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,"");
#define condsignal(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,"");
typedef struct notifiedFIFO_elt_s {
struct notifiedFIFO_elt_s *next;
uint64_t key; //To filter out elements
struct notifiedFIFO_s *reponseFifo;
void (*processingFunc)(void *);
bool malloced;
uint64_t creationTime;
uint64_t startProcessingTime;
uint64_t endProcessingTime;
uint64_t returnTime;
void *msgData;
} notifiedFIFO_elt_t;
typedef struct notifiedFIFO_s {
notifiedFIFO_elt_t *outF;
notifiedFIFO_elt_t *inF;
pthread_mutex_t lockF;
pthread_cond_t notifF;
} notifiedFIFO_t;
// You can use this allocator or use any piece of memory
static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size,
uint64_t key,
notifiedFIFO_t *reponseFifo,
void (*processingFunc)(void *)) {
notifiedFIFO_elt_t *ret;
AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) malloc(sizeof(notifiedFIFO_elt_t)+size+32)), "");
ret->next=NULL;
ret->key=key;
ret->reponseFifo=reponseFifo;
ret->processingFunc=processingFunc;
// We set user data piece aligend 32 bytes to be able to process it with SIMD
ret->msgData=(void *)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32;
ret->malloced=true;
return ret;
}
static inline void *NotifiedFifoData(notifiedFIFO_elt_t *elt) {
return elt->msgData;
}
static inline void delNotifiedFIFO_elt(notifiedFIFO_elt_t *elt) {
if (elt->malloced) {
elt->malloced=false;
free(elt);
} else
printf("delNotifiedFIFO on something not allocated by newNotifiedFIFO\n");
//LOG_W(UTIL,"delNotifiedFIFO on something not allocated by newNotifiedFIFO\n");
}
static inline void initNotifiedFIFO(notifiedFIFO_t *nf) {
mutexinit(nf->lockF);
condinit (nf->notifF);
nf->inF=NULL;
nf->outF=NULL;
// No delete function: the creator has only to free the memory
}
static inline void pushNotifiedFIFO(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg) {
mutexlock(nf->lockF);
msg->next=NULL;
if (nf->outF == NULL)
nf->outF = msg;
if (nf->inF)
nf->inF->next = msg;
nf->inF = msg;
condbroadcast(nf->notifF);
mutexunlock(nf->lockF);
}
static inline notifiedFIFO_elt_t *pullNotifiedFIFO(notifiedFIFO_t *nf) {
mutexlock(nf->lockF);
while(!nf->outF)
condwait(nf->notifF, nf->lockF);
notifiedFIFO_elt_t *ret=nf->outF;
nf->outF=nf->outF->next;
if (nf->outF==NULL)
nf->inF=NULL;
mutexunlock(nf->lockF);
return ret;
}
static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) {
int tmp=mutextrylock(nf->lockF);
if (tmp != 0 )
return NULL;
notifiedFIFO_elt_t *ret=nf->outF;
if (ret!=NULL)
nf->outF=nf->outF->next;
if (nf->outF==NULL)
nf->inF=NULL;
mutexunlock(nf->lockF);
return ret;
}
// This function aborts all messages matching the key
// If the queue is used in thread pools, it doesn't cancels already running processing
// because the message has already been picked
static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) {
mutexlock(nf->lockF);
notifiedFIFO_elt_t **start=&nf->outF;
while(*start!=NULL) {
if ( (*start)->key == key ) {
notifiedFIFO_elt_t *request=*start;
*start=(*start)->next;
delNotifiedFIFO_elt(request);
}
if (*start != NULL)
start=&(*start)->next;
}
mutexunlock(nf->lockF);
}
struct one_thread {
pthread_t threadID;
int id;
int coreID;
char name[256];
uint64_t runningOnKey;
bool abortFlag;
struct thread_pool *pool;
struct one_thread *next;
};
typedef struct thread_pool {
int activated;
bool measurePerf;
int traceFd;
int dummyTraceFd;
uint64_t cpuCyclesMicroSec;
uint64_t startProcessingUE;
int nbThreads;
bool restrictRNTI;
notifiedFIFO_t incomingFifo;
struct one_thread *allthreads;
} tpool_t;
static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) {
if (t->measurePerf) msg->creationTime=rdtsc();
pushNotifiedFIFO(&t->incomingFifo, msg);
}
static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
notifiedFIFO_elt_t *msg= pullNotifiedFIFO(responseFifo);
if (t->measurePerf)
msg->returnTime=rdtsc();
if (t->traceFd)
if(write(t->traceFd, msg, sizeof(*msg)));
return msg;
}
static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
notifiedFIFO_elt_t *msg= pollNotifiedFIFO(responseFifo);
if (msg == NULL)
return NULL;
if (t->measurePerf)
msg->returnTime=rdtsc();
if (t->traceFd)
if(write(t->traceFd, msg, sizeof(*msg)));
return msg;
}
static inline void abortTpool(tpool_t *t, uint64_t key) {
notifiedFIFO_t *nf=&t->incomingFifo;
mutexlock(nf->lockF);
notifiedFIFO_elt_t **start=&nf->outF;
while(*start!=NULL) {
if ( (*start)->key == key ) {
notifiedFIFO_elt_t *request=*start;
*start=(*start)->next;
delNotifiedFIFO_elt(request);
}
if (*start != NULL)
start=&(*start)->next;
}
struct one_thread *ptr=t->allthreads;
while(ptr!=NULL) {
if (ptr->runningOnKey==key)
ptr->abortFlag=true;
ptr=ptr->next;
}
mutexunlock(nf->lockF);
}
void initTpool(char *params,tpool_t *pool, bool performanceMeas);
#endif
+71
View File
@@ -0,0 +1,71 @@
# Thread pool
The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores.
Each worker loop on pick from the same input queue jobs to do.
When a job is done, the worker sends a return if a return is defined.
A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless).
All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter.
## license
Author: Laurent Thomas, Open cells project
The owner share this piece code to Openairsoftware alliance as per OSA license terms
# jobs
A job is a message (notifiedFIFO_elt_t):
next: internal FIFO chain, do not set it
key: a long int that the client can use to identify a message or a group of messages
responseFifo: if the client defines a response FIFO, the message will be posted back after processing
processingFunc: any funtion (type void processingFunc(void *)) that the worker will launch
msgData: the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing
malloced: a boolean that enable internal free in these cases: no return Fifo or Abort feature
The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client.
# Queues of jobs
Queues are type of: notifiedFIFO_t that must be initialized by init_notifiedFIFO()
No delete function is required, the creator has only to free the data of type notifiedFIFO_t
push_notifiedFIFO() add a job in the queue
pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking
abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition)
# Thread pools
## initialization
The clients can create one or more thread pools with init_tpool()
the params string structure: describes a list of cores, separated by "," that run a worker thread
If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core).
The threads are all Linux real time scheduler, their name is set automatically is "Tpool_<core id>"
## adding jobs
The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO())
If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job.
## abort
A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues.
Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue.
## Performance measurements
A performance measurement is integrated: the pool will automacillay fill timestamps:
* creationTime: time the request is push to the pool;
* startProcessingTime: time a worker start to run on the job
* endProcessingTime: time the worker finished the job
* returnTime: time the client reads the result
if you set the environement variable: thread-pool-measurements to a valid file name
These measurements will be wrote to this Linux pipe.
A tool to read the linux fifo and display it in ascii is provided: see the local directory Makefile for this tool and to compile the thread pool unitary tests.
+732
View File
@@ -0,0 +1,732 @@
/*
* 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.0 (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
*/
#include "executables/nr-uesoftmodem.h"
#include "LAYER2/NR_MAC_UE/mac.h"
//#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface_extern.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
#include "fapi_nr_ue_l1.h"
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "RRC/NR_UE/rrc_proto.h"
//#ifndef NO_RAT_NR
#include "SCHED_NR/phy_frame_config_nr.h"
//#endif
#include "SCHED_NR_UE/defs.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "T.h"
#ifdef XFORMS
#include "PHY/TOOLS/nr_phy_scope.h"
extern char do_forms;
#endif
extern double cpuf;
//static nfapi_nr_config_request_t config_t;
//static nfapi_nr_config_request_t* config =&config_t;
/*
* NR SLOT PROCESSING SEQUENCE
*
* Processing occurs with following steps for connected mode:
*
* - Rx samples for a slot are received,
* - PDCCH processing (including DCI extraction for downlink and uplink),
* - PDSCH processing (including transport blocks decoding),
* - PUCCH/PUSCH (transmission of acknowledgements, CSI, ... or data).
*
* Time between reception of the slot and related transmission depends on UE processing performance.
* It is defined by the value NR_UE_CAPABILITY_SLOT_RX_TO_TX.
*
* In NR, network gives the duration between Rx slot and Tx slot in the DCI:
* - for reception of a PDSCH and its associated acknowledgment slot (with a PUCCH or a PUSCH),
* - for reception of an uplink grant and its associated PUSCH slot.
*
* So duration between reception and it associated transmission depends on its transmission slot given in the DCI.
* NR_UE_CAPABILITY_SLOT_RX_TO_TX means the minimum duration but higher duration can be given by the network because UE can support it.
*
* Slot k
* -------+------------+--------
* Frame | Tx samples |
* Subframe | buffer |
* Slot n -------+------------+--------
* ------ +------------+-------- |
* | Rx samples | |
* | buffer | |
* -------+------------+-------- |
* | |
* V |
* +------------+ |
* | PDCCH | |
* | processing | |
* +------------+ |
* | | |
* | v |
* | +------------+ |
* | | PDSCH | |
* | | processing | decoding result |
* | +------------+ -> ACK/NACK of PDSCH |
* | | |
* | v |
* | +-------------+------------+ |
* | | PUCCH/PUSCH | Tx samples | |
* | | processing | transfer | |
* | +-------------+------------+ |
* | |
* |/___________________________________________________________\|
* \ duration between reception and associated transmission /
*
* Remark: processing is done slot by slot, it can be distribute on different threads which are executed in parallel.
* This is an architecture optimization in order to cope with real time constraints.
* By example, for LTE, subframe processing is spread over 4 different threads.
*
*/
#ifndef NO_RAT_NR
#define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */
#else
#define DURATION_RX_TO_TX (4) /* For LTE, this duration is fixed to 4 and it is linked to LTE standard for both modes FDD/TDD */
#endif
#define FRAME_PERIOD 100000000ULL
#define DAQ_PERIOD 66667ULL
#define FIFO_PRIORITY 40
typedef enum {
pss=0,
pbch=1,
si=2
} sync_mode_t;
PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id,
uint8_t abstraction_flag)
{
PHY_VARS_NR_UE *ue;
if (frame_parms!=(NR_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in
ue = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
memset(ue,0,sizeof(PHY_VARS_NR_UE));
memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS));
} else ue = PHY_vars_UE_g[UE_id][0];
ue->Mod_id = UE_id;
ue->mac_enabled = 1;
// initialize all signal buffers
init_nr_ue_signal(ue,1,abstraction_flag);
// intialize transport
init_nr_ue_transport(ue,abstraction_flag);
return(ue);
}
/*!
* It performs band scanning and synchonization.
* \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
*/
typedef struct syncData_s {
PHY_VARS_NR_UE *UE;
} syncData_t;
static void UE_synch(void *arg) {
syncData_t *syncD=(syncData_t *) arg;
int i, hw_slot_offset;
PHY_VARS_NR_UE *UE = syncD->UE;
int current_band = 0;
int current_offset = 0;
sync_mode_t sync_mode = pbch;
int CC_id = UE->CC_id;
int freq_offset=0;
UE->is_synchronized = 0;
if (UE->UE_scan == 0) {
int ind;
get_band(downlink_frequency[CC_id][0], &UE->frame_parms.eutra_band, &uplink_frequency_offset[CC_id][0], &UE->frame_parms.frame_type);
LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n",
downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],
oai_exit, openair0_cfg[0].rx_num_channels);
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
if (uplink_frequency_offset[CC_id][i] != 0) //
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD;
else //FDD
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD;
}
sync_mode = pbch;
} else {
current_band=0;
LOG_E(PHY,"Fixme!\n");
/*
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] =
bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
}
*/
}
LOG_W(PHY, "Starting sync detection\n");
switch (sync_mode) {
/*
case pss:
LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
//lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
current_offset += 20000000; // increase by 20 MHz
if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
current_band++;
current_offset=0;
}
if (current_band==bands_to_scan.nbands) {
current_band=0;
oai_exit=1;
}
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
if (UE->UE_scan_carrier) {
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
}
break;
*/
case pbch:
LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
if (nr_initial_sync( UE, UE->mode ) == 0) {
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot;
LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
hw_slot_offset,
freq_offset,
UE->rx_total_gain_dB,
downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
UE->UE_scan_carrier );
// rerun with new cell parameters and frequency-offset
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
if (freq_offset >= 0)
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(freq_offset);
else
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(freq_offset);
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
}
// reconfigure for potentially different bandwidth
switch(UE->frame_parms.N_RB_DL) {
case 6:
openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
openair0_cfg[UE->rf_map.card].rx_bw =.96e6;
openair0_cfg[UE->rf_map.card].tx_bw =.96e6;
// openair0_cfg[0].rx_gain[0] -= 12;
break;
case 25:
openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
openair0_cfg[UE->rf_map.card].rx_bw =2.5e6;
openair0_cfg[UE->rf_map.card].tx_bw =2.5e6;
// openair0_cfg[0].rx_gain[0] -= 6;
break;
case 50:
openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
openair0_cfg[UE->rf_map.card].rx_bw =5.0e6;
openair0_cfg[UE->rf_map.card].tx_bw =5.0e6;
// openair0_cfg[0].rx_gain[0] -= 3;
break;
case 100:
openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
// openair0_cfg[0].rx_gain[0] -= 0;
break;
}
if (UE->mode != loop_through_memory) {
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
//UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
//UE->rfdevice.trx_stop_func(&UE->rfdevice);
// sleep(1);
//nr_init_frame_parms_ue(&UE->frame_parms);
/*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
LOG_E(HW,"Could not start the device\n");
oai_exit=1;
}*/
}
if (UE->UE_scan_carrier == 1) {
UE->UE_scan_carrier = 0;
} else {
UE->is_synchronized = 1;
}
} else {
// initial sync failed
// calculate new offset and try again
if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
freq_offset += 100;
freq_offset *= -1;
LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
freq_offset,
UE->rx_total_gain_dB,
downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
if (UE->UE_scan_carrier==1)
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
if (UE->mode != loop_through_memory)
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
}// initial_sync=0
break;
case si:
default:
break;
}
}
}
void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
// Process Rx data for one sub-frame
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) {
//clean previous FAPI MESSAGE
UE->rx_ind.number_pdus = 0;
UE->dci_ind.number_of_dcis = 0;
//clean previous FAPI MESSAGE
// call L2 for DL_CONFIG (DCI)
UE->dcireq.module_id = UE->Mod_id;
UE->dcireq.gNB_index = 0;
UE->dcireq.cc_id = 0;
UE->dcireq.frame = proc->frame_rx;
UE->dcireq.slot = proc->nr_tti_rx;
nr_ue_dcireq(&UE->dcireq); //to be replaced with function pointer later
NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0);
UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req;
UE_mac->scheduled_response.slot = proc->nr_tti_rx;
nr_ue_scheduled_response(&UE_mac->scheduled_response);
//write_output("uerxdata_frame.m", "uerxdata_frame", UE->common_vars.rxdata[0], UE->frame_parms.samples_per_frame, 1, 1);
printf("Processing slot %d\n",proc->nr_tti_rx);
#ifdef UE_SLOT_PARALLELISATION
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode);
// printf(">>> nr_ue_pdcch_procedures ended\n");
#endif
}
if (UE->mac_enabled==1) {
// trigger L2 to run ue_scheduler thru IF module
// [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
UE->ul_indication.module_id = 0;
UE->ul_indication.gNB_index = 0;
UE->ul_indication.cc_id = 0;
UE->ul_indication.frame = proc->frame_rx;
UE->ul_indication.slot = proc->nr_tti_rx;
UE->if_inst->ul_indication(&UE->ul_indication);
}
}
}
/*!
* \brief This is the UE thread for RX subframe n and TX subframe n+4.
* This thread performs the phy_procedures_UE_RX() on every received slot.
* then, if TX is enabled it performs TX for n+4.
* \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
typedef struct processingData_s {
UE_nr_rxtx_proc_t proc;
PHY_VARS_NR_UE *UE;
} processingData_t;
void UE_processing(void *arg) {
processingData_t *rxtxD=(processingData_t *) arg;
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
processSubframeRX(UE, proc);
//printf(">>> mac ended\n");
// Prepare the future Tx data
#if 0
#ifndef NO_RAT_NR
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT)
#else
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
(UE->frame_parms.frame_type == FDD) )
#endif
if (UE->mode != loop_through_memory)
phy_procedures_nrUE_TX(UE,proc,0,0,UE->mode,no_relay);
//phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay);
#endif
#if 0
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
(UE->frame_parms.frame_type == TDD))
if (UE->mode != loop_through_memory)
//phy_procedures_UE_S_TX(UE,0,0,no_relay);
updateTimes(current, &t3, 10000, timing_proc_name);
#endif
}
void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
void *rxp[NB_ANTENNAS_RX];
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
for(int x=0; x<10; x++) {
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + 4*x*UE->frame_parms.samples_per_subframe;
AssertFatal( UE->frame_parms.samples_per_subframe ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
rxp,
UE->frame_parms.samples_per_subframe,
UE->frame_parms.nb_antennas_rx), "");
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
}
void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
void *dummy_rx[UE->frame_parms.nb_antennas_rx];
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
dummy_rx[i]=malloc16(UE->frame_parms.samples_per_subframe*4);
for (int sf=0; sf<NR_NUMBER_OF_SUBFRAMES_PER_FRAME; sf++) {
// printf("Reading dummy sf %d\n",sf);
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
dummy_rx,
UE->frame_parms.samples_per_subframe,
UE->frame_parms.nb_antennas_rx);
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
free(dummy_rx[i]);
}
void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
if (UE->no_timing_correction==0) {
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
AssertFatal(unitTransfer ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),"");
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
}
}
int computeSamplesShift(PHY_VARS_NR_UE *UE) {
if ( getenv("RFSIMULATOR") != 0) {
LOG_E(PHY,"SET rx_offset %d \n",UE->rx_offset);
//UE->rx_offset_diff=0;
return 0;
}
// compute TO compensation that should be applied for this frame
if ( UE->rx_offset < 5*UE->frame_parms.samples_per_slot &&
UE->rx_offset > 0 )
return -1 ;
if ( UE->rx_offset > 5*UE->frame_parms.samples_per_slot &&
UE->rx_offset < 10*UE->frame_parms.samples_per_slot )
return 1;
return 0;
}
void *UE_thread(void *arg) {
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
// int tx_enabled = 0;
openair0_timestamp timestamp;
void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
int start_rx_stream = 0;
const uint16_t table_sf_slot[20] = {0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9};
AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
UE->rfdevice.host_type = RAU_HOST;
AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
notifiedFIFO_t nf;
initNotifiedFIFO(&nf);
bool syncRunning=false;
notifiedFIFO_elt_t *syncMsg=newNotifiedFIFO_elt(sizeof(syncData_t),0,&nf,UE_synch);
syncData_t *syncD=(syncData_t *)NotifiedFifoData(syncMsg);
syncD->UE=UE;
int nbSlotProcessing=0;
int thread_idx=0;
notifiedFIFO_elt_t *processingMsg[RX_NB_TH];
for (int i=0; i<RX_NB_TH; i++) {
processingMsg[i]= newNotifiedFIFO_elt(sizeof(processingData_t), 0,&nf,UE_processing);
processingData_t *tmp=(processingData_t *)NotifiedFifoData(processingMsg[i]);
tmp->UE=UE;
}
const int nb_slot_frame = 10*UE->frame_parms.slots_per_subframe;
int absolute_slot=-1;
while (!oai_exit) {
if (!syncD->UE->is_synchronized) {
if (syncRunning) {
notifiedFIFO_elt_t *res=tryPullTpool(&nf, Tpool);
if (res) {
syncRunning=false;
} else
trashFrame(UE, &timestamp);
} else {
readFrame(UE, &timestamp);
pushTpool(Tpool, syncMsg);
syncRunning=true;
}
continue;
}
if (start_rx_stream==0) {
start_rx_stream=1;
syncInFrame(UE, &timestamp);
UE->rx_offset=0;
UE->time_sync_cell=0;
//printf("first stream frame rx %d\n",UE->proc.proc_rxtx[0].frame_rx);
// read in first symbol
AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void **)UE->common_vars.rxdata,
UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
UE->frame_parms.nb_antennas_rx),"");
continue;
}
absolute_slot++;
thread_idx = absolute_slot % RX_NB_TH;
int slot_nr=absolute_slot % nb_slot_frame;
UE_nr_rxtx_proc_t *proc=&(((processingData_t *)NotifiedFifoData(processingMsg[thread_idx]))->proc);
// update thread index for received subframe
proc->nr_tti_rx= slot_nr;
UE->current_thread_id[slot_nr] = thread_idx;
proc->subframe_rx=table_sf_slot[slot_nr];
proc->nr_tti_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
proc->subframe_tx=proc->nr_tti_rx;
proc->frame_rx = ( absolute_slot/nb_slot_frame ) % MAX_FRAME_NUMBER;
proc->frame_tx = ( (absolute_slot + DURATION_RX_TO_TX) /nb_slot_frame ) % MAX_FRAME_NUMBER;
LOG_D(PHY,"Process slot %d thread Idx %d \n", slot_nr, thread_idx);
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+
UE->frame_parms.nb_prefix_samples0+
slot_nr*UE->frame_parms.samples_per_slot];
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
txp[i] = (void *)&UE->common_vars.txdata[i][proc->nr_tti_tx*UE->frame_parms.samples_per_slot];
int readBlockSize, writeBlockSize;
if (slot_nr<(nb_slot_frame - 1)) {
readBlockSize=UE->frame_parms.samples_per_slot;
writeBlockSize=UE->frame_parms.samples_per_slot;
} else {
UE->rx_offset_diff = computeSamplesShift(UE);
readBlockSize=UE->frame_parms.samples_per_slot -
UE->frame_parms.ofdm_symbol_size -
UE->frame_parms.nb_prefix_samples0 -
UE->rx_offset_diff;
writeBlockSize=UE->frame_parms.samples_per_slot -
UE->rx_offset_diff;
}
AssertFatal(readBlockSize ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp,
readBlockSize,
UE->frame_parms.nb_antennas_rx),"");
AssertFatal( writeBlockSize ==
UE->rfdevice.trx_write_func(&UE->rfdevice,
timestamp+
(2*UE->frame_parms.samples_per_slot) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
1),"");
if( slot_nr==(nb_slot_frame-1)) {
// read in first symbol of next frame and adjust for timing drift
int first_symbols=writeBlockSize-readBlockSize;
if ( first_symbols > 0 )
AssertFatal(first_symbols ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void **)UE->common_vars.rxdata,
first_symbols,
UE->frame_parms.nb_antennas_rx),"");
else
LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
}
proc->timestamp_tx = timestamp+
(DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot)-
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
if (getenv("RFSIMULATOR")) {
// FixMe: Wait previous thread is done, because race conditions seems too bad
// in case of actual RF board, the overlap between threads mitigate the issue
while (!tryPullTpool(&nf, Tpool)) {
nbSlotProcessing--;
usleep(200);
}
}
while (nbSlotProcessing >= RX_NB_TH && !tryPullTpool(&nf, Tpool)) {
nbSlotProcessing--;
usleep(200);
}
pushTpool(Tpool, processingMsg[thread_idx]);
} // while !oai_exit
return NULL;
}
void init_UE(int nb_inst) {
int inst;
NR_UE_MAC_INST_t *mac_inst;
pthread_t threads[nb_inst];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&attr, SCHED_RR);
struct sched_param sched;
sched.sched_priority = sched_get_priority_max(SCHED_RR)-1;
pthread_attr_setschedparam(&attr, &sched);
for (inst=0; inst < nb_inst; inst++) {
// UE->rfdevice.type = NONE_DEV;
//PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];
LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]);
PHY_vars_UE_g[inst][0] = init_nr_ue_vars(NULL,inst,0);
PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];
AssertFatal((UE->if_inst = nr_ue_if_module_init(inst)) != NULL, "can not initial IF module\n");
nr_l3_init_ue();
nr_l2_init_ue();
mac_inst = get_mac_inst(0);
mac_inst->if_module = UE->if_inst;
UE->if_inst->scheduled_response = nr_ue_scheduled_response;
UE->if_inst->phy_config_request = nr_ue_phy_config_request;
LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
//init_UE_threads(inst);
//UE = PHY_vars_UE_g[inst][0];
AssertFatal(0 == pthread_create(&threads[inst],
&attr,
UE_thread,
(void *)UE), "");
}
printf("UE threads created by %ld\n", gettid());
}
+831
View File
@@ -0,0 +1,831 @@
/*
* 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
*/
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sched.h>
#include "T.h"
#include "assertions.h"
#include "PHY/types.h"
#include "PHY/defs_nr_UE.h"
#include "common/ran_context.h"
#include "common/config/config_userapi.h"
#include "common/utils/load_module_shlib.h"
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
#include "../../ARCH/COMMON/common_lib.h"
#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
#include "PHY/phy_vars_nr_ue.h"
#include "PHY/LTE_TRANSPORT/transport_vars.h"
#include "SCHED/sched_common_vars.h"
#include "PHY/MODULATION/modulation_vars.h"
//#include "../../SIMU/USER/init_lte.h"
#include "LAYER2/MAC/mac_vars.h"
#include "LAYER2/MAC/mac_proto.h"
#include "RRC/LTE/rrc_vars.h"
#include "PHY_INTERFACE/phy_interface_vars.h"
#ifdef SMBV
#include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "enb_config.h"
//#include "PHY/TOOLS/time_meas.h"
#ifndef OPENAIR2
#include "UTIL/OTG/otg_vars.h"
#endif
#include "intertask_interface.h"
#include "create_tasks.h"
#include "PHY/INIT/phy_init.h"
#include "system.h"
#include <openair2/RRC/NR_UE/rrc_proto.h>
#include <openair2/LAYER2/NR_MAC_UE/mac_defs.h>
#include <openair2/LAYER2/NR_MAC_UE/mac_proto.h>
#include <openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h>
#include <openair1/SCHED_NR_UE/fapi_nr_ue_l1.h>
#ifdef XFORMS
#include <forms.h>
/* Callbacks, globals and object handlers */
extern void reset_stats( FL_OBJECT *, long );
/* Forms and Objects */
typedef struct {
FL_FORM *stats_form;
void *vdata;
char *cdata;
long ldata;
FL_OBJECT *stats_text;
FL_OBJECT *stats_button;
} FD_stats_form;
extern FD_stats_form *create_form_stats_form( void );
#include "PHY/TOOLS/nr_phy_scope.h"
//#include "stats.h"
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
// at eNB 0, an UL scope for every UE
FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX];
//FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
char title[255];
//unsigned char scope_enb_num_ue = 2;
static pthread_t forms_thread; //xforms
#endif //XFORMS
#include <executables/nr-uesoftmodem.h>
RAN_CONTEXT_t RC;
volatile int start_eNB = 0;
volatile int start_UE = 0;
volatile int oai_exit = 0;
static clock_source_t clock_source = internal;
int single_thread_flag=1;
int threequarter_fs=0;
uint32_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern int16_t nr_dlsch_demod_shift;
int UE_scan = 0;
int UE_scan_carrier = 0;
int UE_fo_compensation = 0;
runmode_t mode = normal_txrx;
openair0_config_t openair0_cfg[MAX_CARDS];
#if MAX_NUM_CCs == 1
rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}};
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
#else
rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}};
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}};
#endif
double rx_gain_off = 0.0;
double sample_rate=30.72e6;
double bw = 10.0e6;
static int tx_max_power[MAX_NUM_CCs] = {0};
char rf_config_file[1024];
int chain_offset=0;
int phy_test = 0;
uint8_t usim_test = 0;
uint8_t dci_Format = 0;
uint8_t agregation_Level =0xFF;
uint8_t nb_antenna_tx = 1;
uint8_t nb_antenna_rx = 1;
char ref[128] = "internal";
char channels[128] = "0";
char *parallel_config = NULL;
char *worker_config = NULL;
static THREAD_STRUCT thread_struct;
void set_parallel_conf(char *parallel_conf) {
if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD;
else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT;
else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT;
printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf);
}
void set_worker_conf(char *worker_conf) {
if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE;
else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE;
printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf);
}
PARALLEL_CONF_t get_thread_parallel_conf(void) {
return thread_struct.parallel_conf;
}
WORKER_CONF_t get_thread_worker_conf(void) {
return thread_struct.worker_conf;
}
int rx_input_level_dBm;
//static int online_log_messages=0;
#ifdef XFORMS
extern int otg_enabled;
int do_forms=0;
#else
int otg_enabled;
#endif
//int number_of_cards = 1;
static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
static nfapi_nr_config_request_t *config[MAX_NUM_CCs];
int16_t node_synch_ref[MAX_NUM_CCs];
uint32_t target_dl_mcs = 28; //maximum allowed mcs
uint32_t target_ul_mcs = 20;
uint32_t timing_advance = 0;
uint8_t exit_missed_slots=1;
uint64_t num_missed_slots=0; // counter for the number of missed slots
int transmission_mode=1;
int numerology = 0;
/* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */
//uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD;
/* struct for ethernet specific parameters given in eNB conf file */
//eth_params_t *eth_params;
double cpuf;
char uecap_xer[1024],uecap_xer_in=0;
int oaisim_flag=0;
int emulate_rf = 0;
tpool_t *Tpool;
char *usrp_args=NULL;
char *usrp_clksrc=NULL;
/* forward declarations */
void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
* this is very hackish - find a proper solution
*/
uint8_t abstraction_flag=0;
/*---------------------BMC: timespec helpers -----------------------------*/
struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
struct timespec clock_difftime(struct timespec start, struct timespec end) {
struct timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
void print_difftimes(void) {
LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
}
void exit_function(const char *file, const char *function, const int line, const char *s) {
int CC_id;
if (s != NULL) {
printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s);
}
oai_exit = 1;
if (PHY_vars_UE_g && PHY_vars_UE_g[0]) {
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (PHY_vars_UE_g[0][CC_id] && PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func)
PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice);
}
}
sleep(1); //allow lte-softmodem threads to exit first
itti_terminate_tasks (TASK_UNKNOWN);
}
#ifdef XFORMS
void reset_stats(FL_OBJECT *button, long arg) {
//int i,j,k;
/*PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
for (k=0; k<8; k++) { //harq_processes
for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) {
phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0;
phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0;
phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0;
}
phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0;
phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0;
phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0;
for (j=0; j<phy_vars_eNB->ulsch[i]->Mlimit; j++) {
phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0;
phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0;
phy_vars_eNB->UE_stats[i].ulsch_round_errors[k][j]=0;
phy_vars_eNB->UE_stats[i].ulsch_round_fer[k][j]=0;
}
}
phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0;
phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0;
phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0;
}*/
}
static void *scope_thread(void *arg) {
struct sched_param sched_param;
sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
sched_setscheduler(0, SCHED_FIFO,&sched_param);
printf("Scope thread has priority %d\n",sched_param.sched_priority);
//wait the modem is runnign
sleep(5);
while (!oai_exit) {
phy_scope_UE(form_ue[0],
PHY_vars_UE_g[0][0],
0,0,1);
usleep(100*1000);
}
pthread_exit((void *)arg);
}
#endif
void init_scope(void) {
#ifdef XFORMS
int ret;
int fl_argc=1;
if (do_forms==1) {
char *name="5G-UE-scope";
fl_initialize (&fl_argc, &name, NULL, 0, 0);
int UE_id = 0;
form_ue[UE_id] = create_lte_phy_scope_ue();
sprintf (title, "NR DL SCOPE UE");
fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
fl_set_button(form_ue[UE_id]->button_0,0);
fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
if (ret == 0)
pthread_setname_np( forms_thread, "xforms" );
printf("Scope thread created, ret=%d\n",ret);
}
#endif
}
#if defined(ENABLE_ITTI)
void *l2l1_task(void *arg) {
MessageDef *message_p = NULL;
int result;
itti_set_task_real_time(TASK_L2L1);
itti_mark_task_ready(TASK_L2L1);
do {
// Wait for a message
itti_receive_msg (TASK_L2L1, &message_p);
switch (ITTI_MSG_ID(message_p)) {
case TERMINATE_MESSAGE:
oai_exit=1;
itti_exit_task ();
break;
case ACTIVATE_MESSAGE:
start_UE = 1;
break;
case DEACTIVATE_MESSAGE:
start_UE = 0;
break;
case MESSAGE_TEST:
LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
break;
default:
LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
} while(!oai_exit);
return NULL;
}
#endif
int16_t dlsch_demod_shift;
static void get_options(void) {
int CC_id;
int tddflag=0, nonbiotflag;
char *loopfile=NULL;
int dumpframe=0;
uint32_t online_log_messages;
uint32_t glog_level, glog_verbosity;
uint32_t start_telnetsrv=0;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
if (strlen(in_path) > 0) {
opt_type = OPT_PCAP;
opt_enabled=1;
printf("Enabling OPT for PCAP with the following file %s \n",in_path);
}
if (strlen(in_ip) > 0) {
opt_enabled=1;
opt_type = OPT_WIRESHARK;
printf("Enabling OPT for wireshark for local interface");
}
config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL);
if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) {
set_glog_onlinelog(online_log_messages);
}
if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) {
set_glog(glog_level);
}
if (start_telnetsrv) {
load_module_shlib("telnetsrv",NULL,0,NULL);
}
paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC;
paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC;
config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL);
config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med;
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp;
if (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr)
if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach;
if (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr)
if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect;
if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr)
if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx;
if (dumpframe > 0) mode = rx_dump_frame;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0];
}
UE_scan=0;
if (tddflag > 0) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
frame_parms[CC_id]->frame_type = TDD;
}
/*if (frame_parms[0]->N_RB_DL !=0) {
if ( frame_parms[0]->N_RB_DL < 6 ) {
frame_parms[0]->N_RB_DL = 6;
printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL);
}
if ( frame_parms[0]->N_RB_DL > 100 ) {
frame_parms[0]->N_RB_DL = 100;
printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL);
}
if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) {
frame_parms[0]->N_RB_DL = 50;
printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL);
}
if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) {
frame_parms[0]->N_RB_DL = 25;
printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL);
}
UE_scan = 0;
frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL;
for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
frame_parms[CC_id]->N_RB_DL=frame_parms[0]->N_RB_DL;
frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL;
}
}*/
for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
tx_max_power[CC_id]=tx_max_power[0];
rx_gain[0][CC_id] = rx_gain[0][0];
tx_gain[0][CC_id] = tx_gain[0][0];
}
#if T_TRACER
paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ;
config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL);
#endif
if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) {
// Here the configuration file is the XER encoded UE capabilities
// Read it in and store in asn1c data structures
sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME"));
printf("%s\n",uecap_xer);
uecap_xer_in=1;
} /* UE with config file */
}
#if T_TRACER
int T_nowait = 0; /* by default we wait for the tracer */
int T_port = 2021; /* default port to listen to to wait for the tracer */
int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */
#endif
void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
int CC_id;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
/* Set some default values that may be overwritten while reading options */
frame_parms[CC_id] = (NR_DL_FRAME_PARMS *) calloc(sizeof(NR_DL_FRAME_PARMS),1);
config[CC_id] = (nfapi_nr_config_request_t *) calloc(sizeof(nfapi_nr_config_request_t),1);
config[CC_id]->subframe_config.numerology_index_mu.value =1;
config[CC_id]->subframe_config.duplex_mode.value = 1; //FDD
config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL
config[CC_id]->rf_config.dl_carrier_bandwidth.value = 106;
config[CC_id]->rf_config.ul_carrier_bandwidth.value = 106;
config[CC_id]->sch_config.physical_cell_id.value = 0;
frame_parms[CC_id]->eutra_band = 78;
frame_parms[CC_id]->frame_type = FDD;
frame_parms[CC_id]->tdd_config = 3;
//frame_parms[CC_id]->tdd_config_S = 0;
frame_parms[CC_id]->N_RB_DL = 106;
frame_parms[CC_id]->N_RB_UL = 106;
frame_parms[CC_id]->Ncp = NORMAL;
//frame_parms[CC_id]->Ncp_UL = NORMAL;
frame_parms[CC_id]->Nid_cell = 0;
//frame_parms[CC_id]->num_MBSFN_config = 0;
frame_parms[CC_id]->nb_antenna_ports_eNB = 1;
frame_parms[CC_id]->nb_antennas_tx = 1;
frame_parms[CC_id]->nb_antennas_rx = 1;
//frame_parms[CC_id]->nushift = 0;
///frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
//frame_parms[CC_id]->phich_config_common.phich_duration = normal;
// UL RS Config
/*frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 1;//n_DMRS1 set to 0
frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
frame_parms[CC_id]->pusch_config_common.n_SB = 1;
frame_parms[CC_id]->pusch_config_common.hoppingMode = 0;
frame_parms[CC_id]->pusch_config_common.pusch_HoppingOffset = 0;
frame_parms[CC_id]->pusch_config_common.enable64QAM = 0;
frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;*/
// NR: Init to legacy LTE 20Mhz params
frame_parms[CC_id]->numerology_index = 0;
frame_parms[CC_id]->ttis_per_subframe = 1;
frame_parms[CC_id]->slots_per_tti = 2;
}
}
void init_openair0(void) {
int card;
int i;
for (card=0; card<MAX_CARDS; card++) {
openair0_cfg[card].configFilename = NULL;
if(frame_parms[0]->N_RB_DL == 106) {
if (numerology==0) {
if (frame_parms[0]->threequarter_fs) {
openair0_cfg[card].sample_rate=23.04e6;
openair0_cfg[card].samples_per_frame = 230400;
openair0_cfg[card].tx_bw = 10e6;
openair0_cfg[card].rx_bw = 10e6;
} else {
openair0_cfg[card].sample_rate=30.72e6;
openair0_cfg[card].samples_per_frame = 307200;
openair0_cfg[card].tx_bw = 10e6;
openair0_cfg[card].rx_bw = 10e6;
}
} else if (numerology==1) {
openair0_cfg[card].sample_rate=61.44e6;
openair0_cfg[card].samples_per_frame = 307200;
openair0_cfg[card].tx_bw = 20e6;
openair0_cfg[card].rx_bw = 20e6;
} else if (numerology==2) {
openair0_cfg[card].sample_rate=122.88e6;
openair0_cfg[card].samples_per_frame = 307200;
openair0_cfg[card].tx_bw = 40e6;
openair0_cfg[card].rx_bw = 40e6;
} else {
LOG_E(PHY,"Unsupported numerology!\n");
exit(-1);
}
} else if(frame_parms[0]->N_RB_DL == 50) {
openair0_cfg[card].sample_rate=15.36e6;
openair0_cfg[card].samples_per_frame = 153600;
openair0_cfg[card].tx_bw = 5e6;
openair0_cfg[card].rx_bw = 5e6;
} else if (frame_parms[0]->N_RB_DL == 25) {
openair0_cfg[card].sample_rate=7.68e6;
openair0_cfg[card].samples_per_frame = 76800;
openair0_cfg[card].tx_bw = 2.5e6;
openair0_cfg[card].rx_bw = 2.5e6;
} else if (frame_parms[0]->N_RB_DL == 6) {
openair0_cfg[card].sample_rate=1.92e6;
openair0_cfg[card].samples_per_frame = 19200;
openair0_cfg[card].tx_bw = 1.5e6;
openair0_cfg[card].rx_bw = 1.5e6;
}
if (frame_parms[0]->frame_type==TDD)
openair0_cfg[card].duplex_mode = duplex_mode_TDD;
else //FDD
openair0_cfg[card].duplex_mode = duplex_mode_FDD;
printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx,
PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx);
openair0_cfg[card].Mod_id = 0;
openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
openair0_cfg[card].clock_source = clock_source;
openair0_cfg[card].tx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx);
openair0_cfg[card].rx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx);
for (i=0; i<4; i++) {
if (i<openair0_cfg[card].tx_num_channels)
openair0_cfg[card].tx_freq[i] = downlink_frequency[0][i]+uplink_frequency_offset[0][i];
else
openair0_cfg[card].tx_freq[i]=0.0;
if (i<openair0_cfg[card].rx_num_channels)
openair0_cfg[card].rx_freq[i] = downlink_frequency[0][i];
else
openair0_cfg[card].rx_freq[i]=0.0;
openair0_cfg[card].autocal[i] = 1;
openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off;
openair0_cfg[card].configFilename = rf_config_file;
printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
card,i, openair0_cfg[card].tx_gain[i],
openair0_cfg[card].rx_gain[i],
openair0_cfg[card].tx_freq[i],
openair0_cfg[card].rx_freq[i]);
}
if (usrp_args) openair0_cfg[card].sdr_addrs = usrp_args;
if (usrp_clksrc) {
if (strcmp(usrp_clksrc, "internal") == 0) {
openair0_cfg[card].clock_source = internal;
LOG_D(PHY, "USRP clock source set as internal\n");
} else if (strcmp(usrp_clksrc, "external") == 0) {
openair0_cfg[card].clock_source = external;
LOG_D(PHY, "USRP clock source set as external\n");
} else if (strcmp(usrp_clksrc, "gpsdo") == 0) {
openair0_cfg[card].clock_source = gpsdo;
LOG_D(PHY, "USRP clock source set as gpsdo\n");
} else {
openair0_cfg[card].clock_source = internal;
LOG_I(PHY, "USRP clock source unknown ('%s'). defaulting to internal\n", usrp_clksrc);
}
} else {
openair0_cfg[card].clock_source = internal;
LOG_I(PHY, "USRP clock source not specified. defaulting to internal\n");
}
}
}
int main( int argc, char **argv ) {
//uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
PHY_VARS_NR_UE *UE[MAX_NUM_CCs];
start_background_system();
if ( load_configmodule(argc,argv) == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
set_default_frame_parms(frame_parms);
mode = normal_txrx;
memset(openair0_cfg,0,sizeof(openair0_config_t)*MAX_CARDS);
memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
// initialize logging
logInit();
// get options and fill parameters from configuration file
get_options (); //Command-line options, enb_properties
#if T_TRACER
T_Config_Init();
#endif
//randominit (0);
set_taus_seed (0);
tpool_t pool;
Tpool = &pool;
char params[]="-1,-1,-1,-1";
initTpool(params, Tpool, false);
cpuf=get_cpu_freq_GHz();
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
if (opt_type != OPT_NONE) {
if (init_opt(in_path, in_ip) == -1)
LOG_E(OPT,"failed to run OPT \n");
}
#ifdef PDCP_USE_NETLINK
netlink_init();
#if defined(PDCP_USE_NETLINK_QUEUES)
pdcp_netlink_init();
#endif
#endif
#ifndef PACKAGE_VERSION
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
// init the parameters
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx;
frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx;
frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later
LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx);
get_band(downlink_frequency[CC_id][0], &frame_parms[CC_id]->eutra_band, &uplink_frequency_offset[CC_id][0], &frame_parms[CC_id]->frame_type);
}
NB_UE_INST=1;
NB_INST=1;
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE **));
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs);
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
printf("frame_parms %d\n",frame_parms[CC_id]->ofdm_symbol_size);
nr_init_frame_parms_ue(frame_parms[CC_id],numerology,NORMAL,frame_parms[CC_id]->N_RB_DL,(frame_parms[CC_id]->N_RB_DL-20)>>1,0);
PHY_vars_UE_g[0][CC_id] = init_nr_ue_vars(frame_parms[CC_id], 0,abstraction_flag);
UE[CC_id] = PHY_vars_UE_g[0][CC_id];
if (phy_test==1)
UE[CC_id]->mac_enabled = 0;
else
UE[CC_id]->mac_enabled = 1;
if (UE[CC_id]->mac_enabled == 0) { //set default UL parameters for testing mode
for (int i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
//UE[CC_id]->pusch_config_dedicated[i] = malloc(sizeof(PUSCH_CONFIG_DEDICATED));
//UE[CC_id]->scheduling_request_config[i] = malloc(sizeof(SCHEDULING_REQUEST_CONFIG));
/*UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI;
UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0;
UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3);
UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4;*/
}
}
UE[CC_id]->UE_scan = UE_scan;
UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
UE[CC_id]->UE_fo_compensation = UE_fo_compensation;
UE[CC_id]->mode = mode;
printf("UE[%d]->mode = %d\n",CC_id,mode);
for (uint8_t i=0; i<RX_NB_TH_MAX; i++) {
if (UE[CC_id]->mac_enabled == 1)
UE[CC_id]->pdcch_vars[i][0]->crnti = 0x1234;
else
UE[CC_id]->pdcch_vars[i][0]->crnti = 0x1235;
}
UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off;
UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
if (frame_parms[CC_id]->frame_type==FDD) {
UE[CC_id]->N_TA_offset = 0;
} else {
if (frame_parms[CC_id]->N_RB_DL == 100)
UE[CC_id]->N_TA_offset = 624;
else if (frame_parms[CC_id]->N_RB_DL == 50)
UE[CC_id]->N_TA_offset = 624/2;
else if (frame_parms[CC_id]->N_RB_DL == 25)
UE[CC_id]->N_TA_offset = 624/4;
}
}
// printf("tx_max_power = %d -> amp %d\n",tx_max_power[0],get_tx_amp(tx_max_poHwer,tx_max_power));
init_openair0();
// init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
mlockall(MCL_CURRENT | MCL_FUTURE);
init_scope();
number_of_cards = 1;
for(int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
PHY_vars_UE_g[0][CC_id]->rf_map.card=0;
PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
#if defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706)
PHY_vars_UE_g[0][CC_id]->hw_timing_advance = timing_advance;
#else
PHY_vars_UE_g[0][CC_id]->hw_timing_advance = 160;
#endif
}
// wait for end of program
printf("TYPE <CTRL-C> TO TERMINATE\n");
init_UE(1);
while(true)
sleep(3600);
return 0;
}
+246
View File
@@ -0,0 +1,246 @@
#ifndef NR_UESOFTMODEM_H
#define NR_UESOFTMODEM_H
#define _GNU_SOURCE
#include <execinfo.h>
#include <fcntl.h>
#include <getopt.h>
#include <linux/sched.h>
#include <sched.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syscall.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysinfo.h>
#include "../../ARCH/COMMON/common_lib.h"
#undef MALLOC
#include "assertions.h"
#include "PHY/types.h"
#include "PHY/defs_nr_UE.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#include <threadPool/thread-pool.h>
#if defined(ENABLE_ITTI)
#if defined(ENABLE_USE_MME)
#include "s1ap_eNB.h"
#ifdef PDCP_USE_NETLINK
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#endif
#endif
#endif
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n"
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
#define CONFIG_HLP_CALUERM ""
#define CONFIG_HLP_CALUERB ""
#define CONFIG_HLP_DBGUEPR "UE run normal prach power ramping, but don't continue random-access\n"
#define CONFIG_HLP_CALPRACH "UE run normal prach with maximum power, but don't continue random-access\n"
#define CONFIG_HLP_NOL2CN "bypass L2 and upper layers\n"
#define CONFIG_HLP_UERXG "set UE RX gain\n"
#define CONFIG_HLP_UERXGOFF "external UE amplifier offset\n"
#define CONFIG_HLP_UETXG "set UE TX gain\n"
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
#define CONFIG_HLP_UEFO "set UE to enable estimation and compensation of frequency offset\n"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n"
#define CONFIG_HLP_EXCCLK "tells hardware to use an external clock reference\n"
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
#define CONFIG_HLP_TADV "Set timing_advance\n"
#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n"
#define CONFIG_HLP_CHOFF "Channel id offset\n"
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n"
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n"
#define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n"
#define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n"
#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"
#define CONFIG_HLP_TPORT "tracer port\n"
#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n"
#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n"
#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n"
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n"
#define CONFIG_HLP_USRP_CLK_SRC "USRP clock source: 'internal' or 'external'\n"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
/*------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters defining UE running mode */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_UEMODEPARAMS_DESC { \
{"calib-ue-rx", CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{"calib-ue-rx-med", CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{"calib-ue-rx-byp", CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
{"debug-ue-prach", CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"no-L2-connect", CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"calib-prach-tx", CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
{"loop-memory", CONFIG_HLP_UELOOP, 0, strptr:&loopfile, defstrval:"iqs.in", TYPE_STRING,0}, \
{"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
}
#define CMDLINE_CALIBUERX_IDX 0
#define CMDLINE_CALIBUERXMED_IDX 1
#define CMDLINE_CALIBUERXBYP_IDX 2
#define CMDLINE_DEBUGUEPRACH_IDX 3
#define CMDLINE_NOL2CONNECT_IDX 4
#define CMDLINE_CALIBPRACHTX_IDX 5
#define CMDLINE_MEMLOOP_IDX 6
#define CMDLINE_DUMPMEMORY_IDX 7
/*------------------------------------------------------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters specific to UE */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_UEPARAMS_DESC { \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \
{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \
{"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&UE_fo_compensation, defintval:0, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \
{"r" , CONFIG_HLP_PRB, 0, iptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT, 0}, \
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0} \
}
#define DEFAULT_DLF 2680000000
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters common to eNodeB and UE */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_PARAMS_DESC { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \
{"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \
{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, iptr:&do_forms, defintval:0, TYPE_INT, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \
{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
{"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \
{"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
}
#define CONFIG_HLP_FLOG "Enable online log \n"
#define CONFIG_HLP_LOGL "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n"
#define CONFIG_HLP_LOGV "Set the global log verbosity \n"
#define CONFIG_HLP_TELN "Start embedded telnet server \n"
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for LOG utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_LOGPARAMS_DESC { \
{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
{"G" , CONFIG_HLP_LOGV, 0, uptr:&glog_verbosity, defintval:0, TYPE_UINT16, 0}, \
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
}
#define CMDLINE_ONLINELOG_IDX 0
#define CMDLINE_GLOGLEVEL_IDX 1
#define CMDLINE_GLOGVERBO_IDX 2
#define CMDLINE_STARTTELN_IDX 3
extern int T_port;
extern int T_nowait;
extern int T_dont_fork;
/***************************************************************************************************************************************/
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern int rx_input_level_dBm;
extern uint8_t exit_missed_slots;
extern uint64_t num_missed_slots; // counter for the number of missed slots
extern int oaisim_flag;
extern volatile int oai_exit;
extern openair0_config_t openair0_cfg[MAX_CARDS];
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;
extern int transmission_mode;
extern double cpuf;
#if defined(ENABLE_ITTI)
extern volatile int start_eNB;
extern volatile int start_UE;
#endif
// In nr-ue.c
extern int setup_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
extern void fill_ue_band_info(void);
extern void init_UE(int);
extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char *name);
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
void *UE_thread(void *arg);
PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id,
uint8_t abstraction_flag);
extern tpool_t *Tpool;
#endif
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/sh
echo "building ctags for openair1 and openair2 ..."
ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair2/RRC/CELLULAR/ --exclude=openair2/NAS/DRIVER/CELLULAR/ --exclude=openair2/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi
ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi
@@ -13,6 +13,9 @@
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
#define NFAPI_NR_MAX_NB_CORESETS 12
#define NFAPI_NR_MAX_NB_SEARCH_SPACES 40
// Extension to the generic structures for single tlv values
typedef struct {
@@ -28,12 +31,12 @@ typedef struct {
/*typedef struct {
nfapi_tl_t tl;
int64_t value;
} nfapi_int64_tlv_t;
} nfapi_int64_tlv_t;*/
typedef struct {
nfapi_tl_t tl;
uint64_t value;
} nfapi_uint64_tlv_t;*/
} nfapi_uint64_tlv_t;
// nFAPI enums
typedef enum {
@@ -175,8 +178,8 @@ typedef struct {
nfapi_uint16_tlv_t physical_cell_id;
nfapi_uint16_tlv_t half_frame_index;
nfapi_uint16_tlv_t ssb_subcarrier_offset;
nfapi_uint16_tlv_t ssb_sib1_position_in_burst;
nfapi_uint16_tlv_t ssb_scg_position_in_burst;
nfapi_uint16_tlv_t ssb_sib1_position_in_burst; // in sib1
nfapi_uint64_tlv_t ssb_scg_position_in_burst; // in servingcellconfigcommon
nfapi_uint16_tlv_t ssb_periodicity;
nfapi_uint16_tlv_t ss_pbch_block_power;
nfapi_uint16_tlv_t n_ssb_crb;
@@ -356,7 +359,8 @@ typedef enum {
typedef enum {
NFAPI_NR_CSET_CONFIG_MIB_SIB1=0,
NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG
NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG, // implicit assumption of coreset Id other than 0
NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG_CSET_0
} nfapi_nr_coreset_config_type_e;
typedef enum {
@@ -364,6 +368,31 @@ typedef enum {
NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS
} nfapi_nr_coreset_precoder_granularity_type_e;
typedef enum {
NFAPI_NR_QCL_TYPE_A=0,
NFAPI_NR_QCL_TYPE_B,
NFAPI_NR_QCL_TYPE_C,
NFAPI_NR_QCL_TYPE_D
} nfapi_nr_qcl_type_e;
typedef enum {
NFAPI_NR_SS_PERIODICITY_SL1=1,
NFAPI_NR_SS_PERIODICITY_SL2=2,
NFAPI_NR_SS_PERIODICITY_SL4=4,
NFAPI_NR_SS_PERIODICITY_SL5=5,
NFAPI_NR_SS_PERIODICITY_SL8=8,
NFAPI_NR_SS_PERIODICITY_SL10=10,
NFAPI_NR_SS_PERIODICITY_SL16=16,
NFAPI_NR_SS_PERIODICITY_SL20=20,
NFAPI_NR_SS_PERIODICITY_SL40=40,
NFAPI_NR_SS_PERIODICITY_SL80=80,
NFAPI_NR_SS_PERIODICITY_SL160=160,
NFAPI_NR_SS_PERIODICITY_SL320=320,
NFAPI_NR_SS_PERIODICITY_SL640=640,
NFAPI_NR_SS_PERIODICITY_SL1280=1280,
NFAPI_NR_SS_PERIODICITY_SL2560=2560
} nfapi_nr_search_space_monitoring_periodicity_e;
typedef enum {
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A=0,
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_B,
@@ -496,9 +525,9 @@ typedef struct{
uint8_t css_format_2_2;
uint8_t css_format_2_3;
uint8_t uss_dci_formats;
uint8_t srs_monitoring_periodicity;
uint8_t slot_monitoring_periodicity;
uint8_t slot_monitoring_offset;
uint16_t srs_monitoring_periodicity;
uint16_t slot_monitoring_periodicity;
uint16_t slot_monitoring_offset;
uint16_t monitoring_symbols_in_slot;
uint16_t number_of_candidates[NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS];
} nfapi_nr_search_space_t;
@@ -516,7 +545,7 @@ typedef struct {
uint8_t aggregation_level;
uint8_t n_rb;
uint8_t n_symb;
uint8_t rb_offset;
int8_t rb_offset;
uint8_t cr_mapping_type;
uint8_t reg_bundle_size;
uint8_t interleaver_size;
@@ -644,4 +673,45 @@ typedef struct {
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_dl_config_request_t;
typedef enum {nr_pusch_freq_hopping_disabled = 0 ,
nr_pusch_freq_hopping_enabled = 1
} nr_pusch_freq_hopping_t;
typedef struct{
uint8_t aperiodicSRS_ResourceTrigger;
} nfapi_nr_ul_srs_config_t;
typedef struct {
uint8_t bandwidth_part_ind;
uint16_t number_rbs;
uint16_t start_rb;
uint8_t frame_offset;
uint16_t number_symbols;
uint16_t start_symbol;
nr_pusch_freq_hopping_t pusch_freq_hopping;
uint8_t mcs;
uint8_t Qm;
uint8_t ndi;
uint8_t rv;
uint8_t harq_process_nbr;
int8_t accumulated_delta_PUSCH;
int8_t absolute_delta_PUSCH;
uint8_t n_layers;
uint8_t tpmi;
uint8_t n_dmrs_cdm_groups;
uint8_t dmrs_ports[4];
uint8_t n_front_load_symb;
nfapi_nr_ul_srs_config_t srs_config;
uint8_t csi_reportTriggerSize;
uint8_t maxCodeBlockGroupsPerTransportBlock;
uint8_t ptrs_dmrs_association_port;
uint8_t beta_offset_ind;
} nfapi_nr_ul_config_ulsch_pdu_rel15_t;
typedef struct {
uint16_t rnti;
nfapi_nr_ul_config_ulsch_pdu_rel15_t ulsch_pdu_rel15;
} nfapi_nr_ul_config_ulsch_pdu;
#endif
+385 -434
View File
@@ -20,7 +20,7 @@
//#define DEBUG_POLARTEST
uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31};
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31};
void nr_init_pbch_interleaver(uint8_t *interleaver) {
uint8_t j_sfn=0, j_hrf=10, j_ssb=11, j_other=14;
@@ -28,7 +28,7 @@ void nr_init_pbch_interleaver(uint8_t *interleaver) {
for (uint8_t i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
if (!i) // choice bit:1
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
else if (i<7) //Sfn bits:6
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++);
else if (i<24) // other:17
@@ -43,495 +43,446 @@ void nr_init_pbch_interleaver(uint8_t *interleaver) {
}
int main(int argc, char *argv[]) {
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
time_stats_t timeEncoder,timeDecoder;
opp_enabled=1;
int decoder_int16=0;
cpu_freq_GHz = get_cpu_freq_GHz();
reset_meas(&timeEncoder);
reset_meas(&timeDecoder);
randominit(0);
crcTableInit();
//Default simulation values (Aim for iterations = 1000000.)
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
double SNR, SNR_lin;
int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks).
uint32_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error.
uint16_t testLength = NR_POLAR_PBCH_PAYLOAD_BITS, coderLength = NR_POLAR_PBCH_E, blockErrorCumulative=0, bitErrorCumulative=0;
double timeEncoderCumulative = 0, timeDecoderCumulative = 0;
uint8_t aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL, decoderListSize = 8, pathMetricAppr = 0;
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
time_stats_t timeEncoder,timeDecoder;
opp_enabled=1;
int decoder_int16=0;
cpu_freq_GHz = get_cpu_freq_GHz();
reset_meas(&timeEncoder);
reset_meas(&timeDecoder);
randominit(0);
crcTableInit();
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:hqgL:K:")) != -1)
switch (arguments) {
case 's':
SNRstart = atof(optarg);
break;
//Default simulation values (Aim for iterations = 1000000.)
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
case 'd':
SNRinc = atof(optarg);
break;
double SNR, SNR_lin;
int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks).
uint32_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error.
uint16_t testLength = 0, coderLength = 0, blockErrorCumulative=0, bitErrorCumulative=0;
uint8_t aggregation_level = 8, decoderListSize = 8, pathMetricAppr = 0, matlabDebug = 0;
case 'f':
SNRstop = atof(optarg);
break;
while ((arguments = getopt (argc, argv, "s:d:f:c:i:l:a:hqgm")) != -1)
switch (arguments)
{
case 's':
SNRstart = atof(optarg);
break;
case 'm':
polarMessageType = atoi(optarg);
if (polarMessageType!=0 && polarMessageType!=1 && polarMessageType!=2) {
printf("Illegal polar message type %d (should be 0,1 or 2)\n",
polarMessageType);
}
break;
case 'd':
SNRinc = atof(optarg);
break;
case 'i':
iterations = atoi(optarg);
break;
case 'f':
SNRstop = atof(optarg);
break;
case 'l':
decoderListSize = (uint8_t) atoi(optarg);
break;
case 'c':
polarMessageType = atoi(optarg);
break;
case 'a':
pathMetricAppr = (uint8_t) atoi(optarg);
break;
case 'i':
iterations = atoi(optarg);
break;
case 'q':
decoder_int16 = 1;
break;
case 'l':
decoderListSize = (uint8_t) atoi(optarg);
break;
case 'g':
iterations = 1;
SNRstart = -6.0;
SNRstop = -6.0;
decoder_int16 = 1;
break;
case 'a':
pathMetricAppr = (uint8_t) atoi(optarg);
break;
case 'L':
aggregation_level=atoi(optarg);
if (aggregation_level != 1 &&
aggregation_level != 2 &&
aggregation_level != 4 &&
aggregation_level != 8 &&
aggregation_level != 16) {
printf("Illegal aggregation level %d \n",aggregation_level);
exit(-1);
}
case 'q':
decoder_int16 = 1;
break;
break;
case 'm':
matlabDebug = 1;
//#define DEBUG_POLAR_MATLAB
break;
case 'g':
iterations = 1;
SNRstart = -6.0;
SNRstop = -6.0;
decoder_int16 = 1;
break;
case 'h':
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -c [0=PBCH|1=DCI|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr -m Matlab Debug\n");
exit(-1);
default:
perror("[polartest.c] Problem at argument parsing with getopt");
exit(-1);
}
if (polarMessageType == 0) { //PBCH
testLength = NR_POLAR_PBCH_PAYLOAD_BITS;
coderLength = NR_POLAR_PBCH_E;
aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
} else if (polarMessageType == 1) { //DCI
//testLength = nr_get_dci_size(params_rel15->dci_format, params_rel15->rnti_type, &fp->initial_bwp_dl, cfg);
testLength = 41; //20;
coderLength = 108*8; //to be changed by aggregate level function.
} else if (polarMessageType == -1) { //UCI
//testLength = ;
//coderLength = ;
}
case 'K':
testLength=atoi(optarg);
if (testLength <12 || testLength > 60) {
printf("Illegal packet bitlength\n",testLength);
exit(-1);
}
break;
//Logging
time_t currentTime;
time (&currentTime);
char fileName[512], currentTimeInfo[25];
char folderName[] = ".";
case 'h':
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=PBCH|1=DCI|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr -L aggregation level (for DCI) -K packet_length (bits) for DCI/UCI\n");
exit(-1);
break;
/*
folderName=getenv("HOME");
strcat(folderName,"/Desktop/polartestResults");
*/
#ifdef DEBUG_POLAR_TIMING
sprintf(fileName,"%s/TIMING_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
#else
sprintf(fileName,"%s/_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
#endif
strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(&currentTime));
strcat(fileName,currentTimeInfo);
default:
perror("[polartest.c] Problem at argument parsing with getopt");
exit(-1);
break;
}
//Create "~/Desktop/polartestResults" folder if it doesn't already exist.
/*
struct stat folder = {0};
if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);
*/
FILE* logFile;
logFile = fopen(fileName, "w");
if (logFile==NULL) {
fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName);
exit(-1);
}
if (polarMessageType == 0) { //PBCH
} else if (polarMessageType == 1) { //DCI
coderLength = 108*aggregation_level;
} else if (polarMessageType == -1) { //UCI
printf("UCI testing not supported yet\n");
exit(-1);
}
//Logging
time_t currentTime;
time (&currentTime);
char fileName[512], currentTimeInfo[25];
char folderName[] = ".";
/*
folderName=getenv("HOME");
strcat(folderName,"/Desktop/polartestResults");
*/
#ifdef DEBUG_POLAR_TIMING
fprintf(logFile,",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n");
sprintf(fileName,"%s/TIMING_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
#else
fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
sprintf(fileName,"%s/_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
#endif
strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(&currentTime));
strcat(fileName,currentTimeInfo);
//Create "~/Desktop/polartestResults" folder if it doesn't already exist.
/*
struct stat folder = {0};
if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);
*/
FILE *logFile;
logFile = fopen(fileName, "w");
uint8_t testArrayLength = ceil(testLength / 32.0);
uint8_t coderArrayLength = ceil(coderLength / 32.0);
uint32_t testInput[testArrayLength]; //generate randomly
uint32_t encoderOutput[coderArrayLength];
uint32_t estimatedOutput[testArrayLength]; //decoder output
memset(testInput,0,sizeof(uint32_t) * testArrayLength);
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength);
uint8_t encoderOutputByte[coderLength];
double modulatedInput[coderLength]; //channel input
double channelOutput[coderLength]; //add noise
int16_t channelOutput_int16[coderLength];
t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL;
nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level);
currentPtr = nr_polar_params(nrPolar_params, polarMessageType, testLength, aggregation_level);
#ifdef DEBUG_DCI_POLAR_PARAMS
uint32_t dci_pdu[4];
memset(dci_pdu,0,sizeof(uint32_t)*4);
dci_pdu[0]=0x01189400;
printf("dci_pdu: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]);
uint32_t encoder_output[54];
memset(encoder_output,0,sizeof(uint32_t)*54);
uint16_t size=41;
uint16_t rnti=3;
aggregation_level=8;
nr_polar_init(&nrPolar_params, 1, size, aggregation_level);
t_nrPolar_paramsPtr currentPtrDCI=nr_polar_params(nrPolar_params, 1, size, aggregation_level);
polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti);
for (int i=0;i<54;i++)
printf("encoder_output: [%2d]->0x%08x \n",i, encoder_output[i]);
uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength);
double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength);
uint32_t dci_estimation[4];
memset(dci_estimation,0,sizeof(uint32_t)*4);
printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]);
nr_bit2byte_uint32_8(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte);
printf("[polartest] encoder_outputByte: ");
for (int i = 0; i < currentPtrDCI->encoderLength; i++) printf("%d-", encoder_outputByte[i]);
printf("\n");
for(int i=0; i<currentPtrDCI->encoderLength; i++) {
if (encoder_outputByte[i] == 0) {
channel_output[i]=1/sqrt(2);
}
else {
channel_output[i]=(-1)/sqrt(2);
}
}
decoderState = polar_decoder_dci(channel_output,
dci_estimation,
currentPtrDCI,
NR_POLAR_DECODER_LISTSIZE,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
rnti);
printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]);
free(encoder_outputByte);
free(channel_output);
return 0;
#endif
#ifdef DEBUG_CRC
uint32_t crc;
unsigned int poly24c = 0xb2b11700;
uint32_t testInputCRC[4];
testInputCRC[0]=0x00291880;
//testInputCRC[0]=0x01189400;
testInputCRC[1]=0x00000000;
testInputCRC[2]=0x00000000;
testInputCRC[3]=0x00000000;
uint32_t testInputcrc=0x01189400;
uint32_t testInputcrc2=0x00291880;
uint8_t testInputCRC2[8];
nr_crc_bit2bit_uint32_8(testInputCRC, 32, testInputCRC2);
printf("testInputCRC2: [0]->%x \t [1]->%x \t [2]->%x \t [3]->%x\n"
" [4]->%x \t [5]->%x \t [6]->%x \t [7]->%x\n",
testInputCRC2[0], testInputCRC2[1], testInputCRC2[2], testInputCRC2[3],
testInputCRC2[4], testInputCRC2[5], testInputCRC2[6], testInputCRC2[7]);
unsigned int crc41 = crc24c(testInputCRC, 32);
unsigned int crc65 = crc24c(testInputCRC, 56);
printf("crc41: [0]->0x%08x\tcrc65: [0]->0x%08x\n",crc41, crc65);
for (int i=0;i<32;i++) printf("crc41[%d]=%d\tcrc65[%d]=%d\n",i,(crc41>>i)&1,i,(crc65>>i)&1);
crc = crc24c(testInputCRC, testLength)>>8;
for (int i=0;i<24;i++) printf("[i]=%d\n",(crc>>i)&1);
printf("crc: [0]->0x%08x\n",crc);
//crcbit(testInputCRC, sizeof(test) - 1, poly24c));
testInputCRC[testLength>>3] = ((uint8_t*)&crc)[2];
testInputCRC[1+(testLength>>3)] = ((uint8_t*)&crc)[1];
testInputCRC[2+(testLength>>3)] = ((uint8_t*)&crc)[0];
printf("testInputCRC: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
testInputCRC[0], testInputCRC[1], testInputCRC[2], testInputCRC[3]);
//uint32_t trial32 = 0xffffffff;
uint32_t trial32 = 0xf10fffff;
uint8_t a[4];
//memcpy(a, &trial32, sizeof(trial32));
*(uint32_t *)a = trial32;
unsigned char trial[4];
trial[0]=0xff; trial[1]=0xff; trial[2]=0x0f; trial[3]=0xf1;
uint32_t trialcrc = crc24c(trial, 32);
uint32_t trialcrc32 = crc24c((uint8_t *)&trial32, 32);
//uint32_t trialcrc32 = crc24c(a, 32);
printf("crcbit(trial = %x\n", crcbit(trial, 4, poly24c));
printf("trialcrc = %x\n", trialcrc);
printf("trialcrc32 = %x\n", trialcrc32);
for (int i=0;i<32;i++) printf("trialcrc[%2d]=%d\ttrialcrc32[%2d]=%d\n",i,(trialcrc>>i)&1,i,(trialcrc32>>i)&1);
//uint8_t nr_polar_A[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
uint8_t nr_polar_A[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1};
uint8_t nr_polar_crc[24];
uint8_t **crc_generator_matrix = crc24c_generator_matrix(32);
nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_A,
crc_generator_matrix,
nr_polar_crc,
32,
24);
for (uint8_t i = 0; i < 24; i++){
nr_polar_crc[i] = (nr_polar_crc[i] % 2);
printf("nr_polar_crc[%d]=%d\n",i,nr_polar_crc[i]);
}
return 0;
#endif
if (logFile==NULL) {
fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName);
exit(-1);
}
#ifdef DEBUG_POLAR_TIMING
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
SNR_lin = pow(10, SNR / 10);
for (itr = 1; itr <= iterations; itr++) {
for (int j=0; j<ceil(testLength / 32.0); j++) {
for(int i=0; i<32; i++) {
testInput[j] |= ( ((uint32_t) (rand()%2)) &1);
testInput[j]<<=1;
}
}
printf("testInput: [0]->0x%08x \n", testInput[0]);
polar_encoder_timing(testInput, encoderOutput, currentPtr, cpu_freq_GHz, logFile);
}
}
fclose(logFile);
free(testInput);
free(encoderOutput);
free(modulatedInput);
free(channelOutput);
free(estimatedOutput);
return (0);
fprintf(logFile,
",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n");
#else
fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
#endif
uint8_t testArrayLength = ceil(testLength / 32.0);
uint8_t coderArrayLength = ceil(coderLength / 32.0);
uint32_t testInput[testArrayLength]; //generate randomly
uint32_t encoderOutput[coderArrayLength];
uint32_t estimatedOutput[testArrayLength]; //decoder output
memset(testInput,0,sizeof(uint32_t) * testArrayLength);
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength);
uint8_t encoderOutputByte[coderLength];
double modulatedInput[coderLength]; //channel input
double channelOutput[coderLength]; //add noise
int16_t channelOutput_int16[coderLength];
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level);
#ifdef DEBUG_DCI_POLAR_PARAMS
uint32_t dci_pdu[4];
memset(dci_pdu,0,sizeof(uint32_t)*4);
dci_pdu[0]=0x01189400;
printf("dci_pdu: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]);
uint32_t encoder_output[54];
memset(encoder_output,0,sizeof(uint32_t)*54);
uint16_t size=41;
uint16_t rnti=3;
aggregation_level=8;
t_nrPolar_params *currentPtrDCI=nr_polar_params(1, size, aggregation_level);
polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti);
// We assume no a priori knowledge available about the payload.
double aPrioriArray[currentPtr->payloadBits];
for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN;
for (int i=0; i<54; i++)
printf("encoder_output: [%2d]->0x%08x \n",i, encoder_output[i]);
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
printf("SNR %f\n",SNR);
SNR_lin = pow(10, SNR/10);
for (itr = 1; itr <= iterations; itr++) {
uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength);
double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength);
uint32_t dci_estimation[4];
memset(dci_estimation,0,sizeof(uint32_t)*4);
printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]);
nr_bit2byte_uint32_8(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte);
printf("[polartest] encoder_outputByte: ");
for (int i = 0; i < testArrayLength; i++) {
for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) {
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
testInput[i]<<=1;
}
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
}
for (int i = 0; i < currentPtrDCI->encoderLength; i++) printf("%d-", encoder_outputByte[i]);
#ifdef DEBUG_POLARTEST
printf("testInput: ");
for (int i = 0; i < testArrayLength; i++) printf("[%d]->0x%08x\t",i, testInput[i]);
printf("\n");
printf("\n");
printf("testInput[0]: ");
for (int i=0; i<32; i++) printf("[%d]=%d-",i,(testInput[0]>>i)&1);
printf("\n");
printf("testInput[1]: ");
for (int i=0; i<32; i++) printf("[%d]=%d-",i,(testInput[1]>>i)&1);
printf("\n");
for(int i=0; i<currentPtrDCI->encoderLength; i++) {
if (encoder_outputByte[i] == 0) {
channel_output[i]=1/sqrt(2);
} else {
channel_output[i]=(-1)/sqrt(2);
}
}
decoderState = polar_decoder_dci(channel_output,
dci_estimation,
currentPtrDCI,
NR_POLAR_DECODER_LISTSIZE,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
rnti);
printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]);
free(encoder_outputByte);
free(channel_output);
return 0;
#endif
#ifdef DEBUG_CRC
uint32_t crc;
unsigned int poly24c = 0xb2b11700;
uint32_t testInputCRC[4];
testInputCRC[0]=0x00291880;
//testInputCRC[0]=0x01189400;
testInputCRC[1]=0x00000000;
testInputCRC[2]=0x00000000;
testInputCRC[3]=0x00000000;
uint32_t testInputcrc=0x01189400;
uint32_t testInputcrc2=0x00291880;
uint8_t testInputCRC2[8];
nr_crc_bit2bit_uint32_8(testInputCRC, 32, testInputCRC2);
printf("testInputCRC2: [0]->%x \t [1]->%x \t [2]->%x \t [3]->%x\n"
" [4]->%x \t [5]->%x \t [6]->%x \t [7]->%x\n",
testInputCRC2[0], testInputCRC2[1], testInputCRC2[2], testInputCRC2[3],
testInputCRC2[4], testInputCRC2[5], testInputCRC2[6], testInputCRC2[7]);
unsigned int crc41 = crc24c(testInputCRC, 32);
unsigned int crc65 = crc24c(testInputCRC, 56);
printf("crc41: [0]->0x%08x\tcrc65: [0]->0x%08x\n",crc41, crc65);
int len_mod64=currentPtr->payloadBits&63;
((uint64_t*)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<<len_mod64)-1);
for (int i=0; i<32; i++) printf("crc41[%d]=%d\tcrc65[%d]=%d\n",i,(crc41>>i)&1,i,(crc65>>i)&1);
#ifdef DEBUG_POLARTEST
printf("testInput: ");
for (int i = 0; i < testArrayLength; i++) printf("[%d]->0x%08x\t",i, testInput[i]);
printf("\n");
crc = crc24c(testInputCRC, testLength)>>8;
printf("testInput[0]: ");
for (int i=0; i<32; i++) printf("[%d]=%d-",i,(testInput[0]>>i)&1);
printf("\n");
printf("testInput[1]: ");
for (int i=0; i<32; i++) printf("[%d]=%d-",i,(testInput[1]>>i)&1);
printf("\n");
for (int i=0; i<24; i++) printf("[i]=%d\n",(crc>>i)&1);
printf("crc: [0]->0x%08x\n",crc);
//crcbit(testInputCRC, sizeof(test) - 1, poly24c));
testInputCRC[testLength>>3] = ((uint8_t *)&crc)[2];
testInputCRC[1+(testLength>>3)] = ((uint8_t *)&crc)[1];
testInputCRC[2+(testLength>>3)] = ((uint8_t *)&crc)[0];
printf("testInputCRC: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
testInputCRC[0], testInputCRC[1], testInputCRC[2], testInputCRC[3]);
//uint32_t trial32 = 0xffffffff;
uint32_t trial32 = 0xf10fffff;
uint8_t a[4];
//memcpy(a, &trial32, sizeof(trial32));
*(uint32_t *)a = trial32;
unsigned char trial[4];
trial[0]=0xff;
trial[1]=0xff;
trial[2]=0x0f;
trial[3]=0xf1;
uint32_t trialcrc = crc24c(trial, 32);
uint32_t trialcrc32 = crc24c((uint8_t *)&trial32, 32);
//uint32_t trialcrc32 = crc24c(a, 32);
printf("crcbit(trial = %x\n", crcbit(trial, 4, poly24c));
printf("trialcrc = %x\n", trialcrc);
printf("trialcrc32 = %x\n", trialcrc32);
for (int i=0; i<32; i++) printf("trialcrc[%2d]=%d\ttrialcrc32[%2d]=%d\n",i,(trialcrc>>i)&1,i,(trialcrc32>>i)&1);
//uint8_t nr_polar_A[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
uint8_t nr_polar_A[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1};
uint8_t nr_polar_crc[24];
uint8_t **crc_generator_matrix = crc24c_generator_matrix(32);
nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_A,
crc_generator_matrix,
nr_polar_crc,
32,
24);
for (uint8_t i = 0; i < 24; i++) {
nr_polar_crc[i] = (nr_polar_crc[i] % 2);
printf("nr_polar_crc[%d]=%d\n",i,nr_polar_crc[i]);
}
return 0;
#endif
#ifdef DEBUG_POLAR_TIMING
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
SNR_lin = pow(10, SNR / 10);
if (matlabDebug == 1){
memset(testInput,0,sizeof(uint32_t) * testArrayLength);
/*testInput[0] |= ((uint32_t)1 << 31); testInput[0] |= ((uint32_t)1 << 28); testInput[0] |= ((uint32_t)1 << 26);
testInput[0] |= ((uint32_t)1 << 25); testInput[0] |= ((uint32_t)1 << 22); testInput[0] |= ((uint32_t)1 << 21);
testInput[0] |= ((uint32_t)1 << 19); testInput[0] |= ((uint32_t)1 << 17); testInput[0] |= ((uint32_t)1 << 15);
testInput[0] |= ((uint32_t)1 << 14); testInput[0] |= ((uint32_t)1 << 12); testInput[0] |= ((uint32_t)1 << 10);
testInput[0] |= ((uint32_t)1 << 8); testInput[0] |= ((uint32_t)1 << 5); testInput[0] |= ((uint32_t)1 << 3);
testInput[0] |= ((uint32_t)1 << 2); testInput[0] |= ((uint32_t)1 << 1);*/
for (itr = 1; itr <= iterations; itr++) {
for (int j=0; j<ceil(testLength / 32.0); j++) {
for(int i=0; i<32; i++) {
testInput[j] |= ( ((uint32_t) (rand()%2)) &1);
testInput[j]<<=1;
}
}
printf("testInput: [0]->0x%08x \n", testInput[0]);
polar_encoder_timing(testInput, encoderOutput, currentPtr, cpu_freq_GHz, logFile);
}
}
fclose(logFile);
free(testInput);
free(encoderOutput);
free(modulatedInput);
free(channelOutput);
free(estimatedOutput);
return (0);
#endif
// We assume no a priori knowledge available about the payload.
double aPrioriArray[currentPtr->payloadBits];
testInput[0] |= ((uint32_t)1 << 30); testInput[0] |= ((uint32_t)1 << 29); testInput[0] |= ((uint32_t)1 << 28);
testInput[0] |= ((uint32_t)1 << 26); testInput[0] |= ((uint32_t)1 << 23); testInput[0] |= ((uint32_t)1 << 21);
testInput[0] |= ((uint32_t)1 << 19); testInput[0] |= ((uint32_t)1 << 17); testInput[0] |= ((uint32_t)1 << 16);
testInput[0] |= ((uint32_t)1 << 14); testInput[0] |= ((uint32_t)1 << 12); testInput[0] |= ((uint32_t)1 << 10);
testInput[0] |= ((uint32_t)1 << 9); testInput[0] |= ((uint32_t)1 << 6); testInput[0] |= ((uint32_t)1 << 5);
testInput[0] |= ((uint32_t)1 << 3); testInput[0] |= ((uint32_t)1);
for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN;
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
printf("SNR %f\n",SNR);
SNR_lin = pow(10, SNR/10);
/*printf("testInput (a_31,..., a_0): ");
for (int i=31; i>=0; i--) printf("%d-",(testInput[0]>>i)&1); //a_31, a_30, ..., a_0
printf("testInput = 0x%llx\n", testInput[0]);
printf("\n");*/
for (itr = 1; itr <= iterations; itr++) {
for (int i = 0; i < testArrayLength; i++) {
for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) {
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
testInput[i]<<=1;
}
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
}
/*for (int i=0;i<32;i++){
memset(testInput,0,sizeof(uint32_t) * testArrayLength);
testInput[0] |= ((uint32_t)1 << i);
int crc = crc24c(testInput,32);
printf("[i=%d]testInput = 0x%08lx, crc = 0x%lx\n", i,testInput[0], crc);
}
memset(testInput,0,sizeof(uint32_t) * testArrayLength);
int crc = crc24c(testInput,32);
printf("testInput = 0x%08lx, crc = 0x%lx\n", testInput[0], crc);*/
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
for (int i=0; i<32; i++)
printf("%d\n",(testInput[0]>>i)&1);*/
int len_mod64=currentPtr->payloadBits&63;
((uint64_t *)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<<len_mod64)-1);
start_meas(&timeEncoder);
}
if (decoder_int16==0) {
if (polarMessageType == 0) polar_encoder(testInput, encoderOutput, currentPtr);
else polar_encoder_dci(testInput, encoderOutput, currentPtr, 0);
}
else
polar_encoder_fast((uint64_t *)testInput, encoderOutput,0, currentPtr);
uint8_t nr_pbch_interleaver[NR_POLAR_PBCH_PAYLOAD_BITS];
memset((void*)nr_pbch_interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
nr_init_pbch_interleaver(nr_pbch_interleaver);
/*for (int i=0; i<=31;i++)
printf("nr_pbch_interleaver[%d]=%d\n",i,nr_pbch_interleaver[i]);
//polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0, currentPtr);
stop_meas(&timeEncoder);
/*printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]);
printf("encoderOutput: [1]->0x%08x\n", encoderOutput[1]);*/
//Bit-to-byte:
nr_bit2byte_uint32_8(encoderOutput, coderLength, encoderOutputByte);
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
printf("nr_pbch_interleaver_operation[%d]=%d\n",i,(*(nr_pbch_interleaver+i)));*/
//BPSK modulation
for(int i=0; i<coderLength; i++) {
if (encoderOutputByte[i] == 0)
modulatedInput[i]=1/sqrt(2);
else
modulatedInput[i]=(-1)/sqrt(2);
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
start_meas(&timeEncoder);
if (decoder_int16==1)
polar_encoder_fast((uint64_t*)testInput, encoderOutput, 0, currentPtr);
else
polar_encoder(testInput, encoderOutput, currentPtr);
//polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0, currentPtr);
stop_meas(&timeEncoder);
/*printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]);
printf("encoderOutput: [1]->0x%08x\n", encoderOutput[1]);*/
if (decoder_int16==1) {
if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
}
}
//Bit-to-byte:
nr_bit2byte_uint32_8(encoderOutput, coderLength, encoderOutputByte);
start_meas(&timeDecoder);
//BPSK modulation
for(int i=0; i<coderLength; i++) {
if (encoderOutputByte[i] == 0)
modulatedInput[i]=1;
//modulatedInput[i]=1/sqrt(2);
else
modulatedInput[i]=(-1);
//modulatedInput[i]=((-1)/sqrt(2));
/*decoderState = polar_decoder(channelOutput,
estimatedOutput,
currentPtr,
NR_POLAR_DECODER_LISTSIZE,
aPrioriArray,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION);*/
if (decoder_int16==0) {
if (polarMessageType == 0)
decoderState = polar_decoder_aPriori(channelOutput,
estimatedOutput,
currentPtr,
NR_POLAR_DECODER_LISTSIZE,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
aPrioriArray);
else if (polarMessageType == 1)
decoderState = polar_decoder_dci(channelOutput,
estimatedOutput,
currentPtr,
NR_POLAR_DECODER_LISTSIZE,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
0);
}
else decoderState = polar_decoder_int16(channelOutput_int16,
(uint64_t *)estimatedOutput,
currentPtr);
stop_meas(&timeDecoder);
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(SNR_lin)));
//channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
//calculate errors
if (decoderState!=0) {
blockErrorState=-1;
nBitError=-1;
} else {
for (int j = 0; j < currentPtr->payloadBits; j++) {
if (((estimatedOutput[0]>>j) & 1) != ((testInput[0]>>j) & 1)) nBitError++;
if (decoder_int16==1) {
if (channelOutput[i] > 15)
channelOutput_int16[i] = 127;
else if (channelOutput[i] < -16)
channelOutput_int16[i] = -128;
else
channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
}
}
// printf("bit %d: %d => %d\n",j,(testInput[0]>>j)&1,(estimatedOutput[0]>>j)&1);
}
start_meas(&timeDecoder);
/*decoderState = polar_decoder(channelOutput,
estimatedOutput,
currentPtr,
NR_POLAR_DECODER_LISTSIZE,
aPrioriArray,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION);*/
if (decoder_int16 == 1)
decoderState = polar_decoder_int16(channelOutput_int16,
(uint64_t*) estimatedOutput,
currentPtr);
else
decoderState = polar_decoder_aPriori(channelOutput,
estimatedOutput, currentPtr,
NR_POLAR_DECODER_LISTSIZE,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
aPrioriArray);
stop_meas(&timeDecoder);
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/
if (nBitError>0) {
blockErrorState=1;
// printf("Error: Input %x, Output %x\n",testInput[0],estimatedOutput[0]);
}
}
//calculate errors
if (decoderState!=0) {
blockErrorState=-1;
nBitError=-1;
} else {
for (int j = 0; j < currentPtr->payloadBits; j++) {
if (((estimatedOutput[0]>>j) & 1) != ((testInput[0]>>j) & 1))
nBitError++;
// printf("bit %d: %d => %d\n",j,(testInput[0]>>j)&1,(estimatedOutput[0]>>j)&1);
}
if (nBitError>0) {
blockErrorState=1;
//printf("Error: Input %x, Output %x\n",testInput[0],estimatedOutput[0]);
}
}
//Iteration times are in microseconds.
timeEncoderCumulative+=(timeEncoder.diff/(cpu_freq_GHz*1000.0));
timeDecoderCumulative+=(timeDecoder.diff/(cpu_freq_GHz*1000.0));
fprintf(logFile,",%f,%d,%d,%f,%f\n", SNR, nBitError, blockErrorState,
(timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0)));
//Iteration times are in microseconds.
fprintf(logFile,",%f,%d,%d,%f,%f\n", SNR, nBitError, blockErrorState,
(timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0)));
if (nBitError<0) {
blockErrorCumulative++;
bitErrorCumulative+=testLength;
} else {
blockErrorCumulative+=blockErrorState;
bitErrorCumulative+=nBitError;
}
if (nBitError<0) {
blockErrorCumulative++;
bitErrorCumulative+=testLength;
} else {
blockErrorCumulative+=blockErrorState;
bitErrorCumulative+=nBitError;
}
decoderState=0;
nBitError=0;
blockErrorState=0;
}
decoderState=0;
nBitError=0;
blockErrorState=0;
//Calculate error statistics for the SNR.
printf("[ListSize=%d, Appr=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n",
decoderListSize, pathMetricAppr, SNR, ((double)blockErrorCumulative/iterations),
((double)bitErrorCumulative / (iterations*testLength)),
(double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0));
//(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);
}
//Calculate error statistics for the SNR.
printf("[ListSize=%d, Appr=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%12.6fus, t_Decoder=%12.6fus\n",
decoderListSize, pathMetricAppr, SNR, ((double)blockErrorCumulative/iterations),
((double)bitErrorCumulative / (iterations*testLength)),
(double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),
(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0));
if (blockErrorCumulative==0 && bitErrorCumulative==0)
break;
if (blockErrorCumulative==0 && bitErrorCumulative==0)
break;
blockErrorCumulative = 0;
bitErrorCumulative = 0;
timeEncoderCumulative = 0;
timeDecoderCumulative = 0;
}
blockErrorCumulative = 0; bitErrorCumulative = 0;
}
print_meas(&timeEncoder,"polar_encoder",NULL,NULL);
print_meas(&timeDecoder,"polar_decoder",NULL,NULL);
fclose(logFile);
return (0);
print_meas(&timeEncoder,"polar_encoder",NULL,NULL);
print_meas(&timeDecoder,"polar_decoder",NULL,NULL);
fclose(logFile);
return (0);
}
@@ -99,7 +99,6 @@ int main(int argc, char *argv[]) {
testInput<<=1;
}
testInput |= ( ((uint32_t) (rand()%2)) &1);
//Encoding
start_meas(&timeEncoder);
encoderOutput = encodeSmallBlock((uint16_t*)&testInput, (uint8_t)messageLength);
+1 -1
View File
@@ -455,7 +455,7 @@ int32_t nr_segmentation(unsigned char *input_buffer,
unsigned int B,
unsigned int *C,
unsigned int *K,
unsigned int *Zout,
unsigned int *Zout,
unsigned int *F);
uint32_t nr_compute_tbs(uint8_t mcs,
+5 -1
View File
@@ -32,6 +32,7 @@
#include "coding_defs.h"
#include "assertions.h"
/*ref 36-212 v8.6.0 , pp 8-9 */
/* the highest degree is set by default */
@@ -275,7 +276,7 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
break;
default:
crc_len=3;
AssertFatal(1,"Invalid crc_type \n");
}
for (int i=0; i<crc_len; i++)
@@ -309,6 +310,9 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
crc = crc8(decoded_bytes,
n-8)>>24;
break;
default:
AssertFatal(1,"Invalid crc_type \n");
}
if (crc == oldcrc)
@@ -54,7 +54,7 @@ int32_t nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t*
t_nrLDPC_lut lut;
t_nrLDPC_lut* p_lut = &lut;
printf("p_procBuf->cnProcBuf = %p\n", p_procBuf->cnProcBuf);
//printf("p_procBuf->cnProcBuf = %p\n", p_procBuf->cnProcBuf);
// Initialize decoder core(s) with correct LUTs
numLLR = nrLDPC_init(p_decParams, p_lut);
File diff suppressed because it is too large Load Diff
@@ -184,14 +184,7 @@ void updateCrcChecksum2(uint8_t **crcChecksum,
}
}
void build_decoder_tree(t_nrPolar_params *polarParams)
{
polarParams->tree.num_nodes=0;
polarParams->tree.root = add_nodes(polarParams->n,0,polarParams);
#ifdef DEBUG_NEW_IMPL
printf("root : left %p, right %p\n",polarParams->tree.root->left,polarParams->tree.root->right);
#endif
}
decoder_node_t *new_decoder_node(int first_leaf_index, int level) {
@@ -253,6 +246,15 @@ decoder_node_t *add_nodes(int level, int first_leaf_index, t_nrPolar_params *pol
return(new_node);
}
void build_decoder_tree(t_nrPolar_params *polarParams)
{
polarParams->tree.num_nodes=0;
polarParams->tree.root = add_nodes(polarParams->n,0,polarParams);
#ifdef DEBUG_NEW_IMPL
printf("root : left %p, right %p\n",polarParams->tree.root->left,polarParams->tree.root->right);
#endif
}
#if defined(__arm__) || defined(__aarch64__)
// translate 1-1 SIMD functions from SSE to NEON
#define __m128i int16x8_t
@@ -512,17 +514,19 @@ void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) {
memcpy((void*)&betav[node->Nv/2],betar,(node->Nv/2)*sizeof(int16_t));
}
void generic_polar_decoder(t_nrPolar_params *polarParams, decoder_node_t *node) {
void generic_polar_decoder(const t_nrPolar_params *pp,decoder_node_t *node) {
// Apply F to left
applyFtoleft(polarParams, node);
applyFtoleft(pp, node);
// if left is not a leaf recurse down to the left
if (node->left->leaf==0)
generic_polar_decoder(polarParams, node->left);
generic_polar_decoder(pp, node->left);
applyGtoright(polarParams, node);
if (node->right->leaf==0) generic_polar_decoder(polarParams, node->right);
applyGtoright(pp, node);
if (node->right->leaf==0) generic_polar_decoder(pp, node->right);
computeBeta(polarParams, node);
computeBeta(pp, node);
}
+178 -159
View File
@@ -80,7 +80,7 @@ struct nrPolar_params {
//messageType: 0=PBCH, 1=DCI, -1=UCI
int idx; //idx = (messageType * messageLength * aggregation_prime);
struct nrPolar_params *nextPtr;
uint8_t n_max;
uint8_t i_il;
uint8_t i_seg;
@@ -95,7 +95,7 @@ struct nrPolar_params {
uint16_t N;
uint8_t n;
uint32_t crcBit;
uint16_t *interleaving_pattern;
uint16_t *deinterleaving_pattern;
uint16_t *rate_matching_pattern;
@@ -106,7 +106,7 @@ struct nrPolar_params {
uint8_t *information_bit_pattern;
uint16_t *channel_interleaver_pattern;
uint32_t crc_polynomial;
uint8_t **crc_generator_matrix; //G_P
uint8_t **G_N;
uint64_t **G_N_tab;
@@ -116,7 +116,7 @@ struct nrPolar_params {
uint64_t cprime_tab1[32][256];
uint64_t B_tab0[32][256];
uint64_t B_tab1[32][256];
uint32_t* crc256Table;
uint32_t *crc256Table;
uint8_t **extended_crc_generator_matrix;
//lowercase: bits, Uppercase: Bits stored in bytes
//polar_encoder vectors
@@ -125,93 +125,82 @@ struct nrPolar_params {
uint8_t *nr_polar_APrime;
uint8_t *nr_polar_D;
uint8_t *nr_polar_E;
//Polar Coding vectors
uint8_t *nr_polar_A;
uint8_t *nr_polar_CPrime;
uint8_t *nr_polar_B;
uint8_t *nr_polar_U;
decoder_tree_t tree;
} __attribute__ ((__packed__));
typedef struct nrPolar_params t_nrPolar_params;
typedef t_nrPolar_params *t_nrPolar_paramsPtr;
void polar_encoder(uint32_t *input,
uint32_t *output,
t_nrPolar_paramsPtr polarParams);
uint32_t *output,
t_nrPolar_params *polarParams);
void polar_encoder_dci(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
uint16_t n_RNTI);
uint32_t *out,
t_nrPolar_params *polarParams,
uint16_t n_RNTI);
void polar_encoder_fast(uint64_t *Aprime,
uint32_t *out,
int32_t crcmask,
t_nrPolar_paramsPtr polarParams);
void polar_encoder_fast(uint64_t *A,
uint32_t *out,
int32_t crcmask,
t_nrPolar_params *polarParams);
int8_t polar_decoder(double *input,
uint8_t *output,
t_nrPolar_paramsPtr polarParams,
uint8_t listSize,
uint8_t pathMetricAppr);
int8_t polar_decoder_aPriori(double *input,
uint32_t *output,
t_nrPolar_paramsPtr polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
double *aPrioriPayload);
int8_t polar_decoder_dci(double *input,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
uint16_t n_RNTI);
uint8_t *output,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr);
uint32_t polar_decoder_int16(int16_t *input,
uint64_t *out,
t_nrPolar_params *polarParams);
uint64_t *out,
const t_nrPolar_params *polarParams);
void generic_polar_decoder(t_nrPolar_params *, decoder_node_t *);
int8_t polar_decoder_aPriori(double *input,
uint32_t *output,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
double *aPrioriPayload);
void applyFtoleft(t_nrPolar_params *polarParams, decoder_node_t *node);
int8_t polar_decoder_aPriori_timing(double *input,
uint32_t *output,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
double *aPrioriPayload,
double cpuFreqGHz,
FILE *logFile);
void applyGtoright(t_nrPolar_params *polarParams, decoder_node_t *node);
int8_t polar_decoder_dci(double *input,
uint32_t *out,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
uint16_t n_RNTI);
void computeBeta(t_nrPolar_params *polarParams, decoder_node_t *node);
void build_decoder_tree(t_nrPolar_params *polarParams);
decoder_node_t *new_decoder_node(int first_leaf_index, int level);
decoder_node_t *add_nodes(int level, int first_leaf_index, t_nrPolar_params *polarParams);
void build_polar_tables(t_nrPolar_paramsPtr polarParams);
void generic_polar_decoder(const t_nrPolar_params *,
decoder_node_t *);
void build_decoder_tree(t_nrPolar_params *pp);
void build_polar_tables(t_nrPolar_params *polarParams);
void init_polar_deinterleaver_table(t_nrPolar_params *polarParams);
void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
void nr_polar_print_polarParams(t_nrPolar_params *polarParams);
void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams);
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
t_nrPolar_params *nr_polar_params ( int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level);
uint8_t** nr_polar_kronecker_power_matrices(uint8_t n);
uint8_t **nr_polar_kronecker_power_matrices(uint8_t n);
const uint16_t* nr_polar_sequence_pattern(uint8_t n);
const uint16_t *nr_polar_sequence_pattern(uint8_t n);
/*!@fn uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max)
* @brief Computes...
@@ -219,143 +208,167 @@ const uint16_t* nr_polar_sequence_pattern(uint8_t n);
* @param E
* @param n_max */
uint32_t nr_polar_output_length(uint16_t K,
uint16_t E,
uint8_t n_max);
uint16_t E,
uint8_t n_max);
void nr_polar_channel_interleaver_pattern(uint16_t *cip,
uint8_t I_BIL,
uint16_t E);
uint8_t I_BIL,
uint16_t E);
void nr_polar_rate_matching_pattern(uint16_t *rmp,
uint16_t *J,
const uint8_t *P_i_,
uint16_t K,
uint16_t N,
uint16_t E);
uint16_t *J,
const uint8_t *P_i_,
uint16_t K,
uint16_t N,
uint16_t E);
void nr_polar_rate_matching(double *input,
double *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E);
double *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E);
void nr_polar_rate_matching_int16(int16_t *input,
int16_t *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E);
int16_t *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E);
void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_);
void nr_polar_interleaving_pattern(uint16_t K,
uint8_t I_IL,
uint16_t *PI_k_);
void nr_polar_info_bit_pattern(uint8_t *ibp,
int16_t *Q_I_N,
int16_t *Q_F_N,
uint16_t *J,
const uint16_t *Q_0_Nminus1,
uint16_t K,
uint16_t N,
uint16_t E,
uint8_t n_PC);
int16_t *Q_I_N,
int16_t *Q_F_N,
uint16_t *J,
const uint16_t *Q_0_Nminus1,
uint16_t K,
uint16_t N,
uint16_t E,
uint8_t n_PC);
void nr_polar_info_bit_extraction(uint8_t *input,
uint8_t *output,
uint8_t *pattern,
uint16_t size);
uint8_t *output,
uint8_t *pattern,
uint16_t size);
void nr_bit2byte_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out);
void nr_bit2byte_uint32_8(uint32_t *in,
uint16_t arraySize,
uint8_t *out);
void nr_byte2bit_uint8_32(uint8_t *in, uint16_t arraySize, uint32_t *out);
void nr_byte2bit_uint8_32(uint8_t *in,
uint16_t arraySize,
uint32_t *out);
void nr_crc_bit2bit_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out);
void nr_crc_bit2bit_uint32_8(uint32_t *in,
uint16_t arraySize,
uint8_t *out);
void nr_polar_bit_insertion(uint8_t *input,
uint8_t *output,
uint16_t N,
uint16_t K,
int16_t *Q_I_N,
int16_t *Q_PC_N,
uint8_t n_PC);
uint8_t *output,
uint16_t N,
uint16_t K,
int16_t *Q_I_N,
int16_t *Q_PC_N,
uint8_t n_PC);
void nr_matrix_multiplication_uint8_1D_uint8_2D(uint8_t *matrix1,
uint8_t **matrix2,
uint8_t *output,
uint16_t row,
uint16_t col);
uint8_t **matrix2,
uint8_t *output,
uint16_t row,
uint16_t col);
uint8_t ***nr_alloc_uint8_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen);
uint8_t ***nr_alloc_uint8_3D_array(uint16_t xlen,
uint16_t ylen,
uint16_t zlen);
uint8_t **nr_alloc_uint8_2D_array(uint16_t xlen, uint16_t ylen);
uint8_t **nr_alloc_uint8_2D_array(uint16_t xlen,
uint16_t ylen);
double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen);
double ***nr_alloc_double_3D_array(uint16_t xlen,
uint16_t ylen,
uint16_t zlen);
double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen);
double **nr_alloc_double_2D_array(uint16_t xlen,
uint16_t ylen);
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen);
void nr_free_double_3D_array(double ***input,
uint16_t xlen,
uint16_t ylen);
void nr_free_double_2D_array(double **input, uint16_t xlen);
void nr_free_double_2D_array(double **input,
uint16_t xlen);
void nr_free_uint8_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen);
void nr_free_uint8_3D_array(uint8_t ***input,
uint16_t xlen,
uint16_t ylen);
void nr_free_uint8_2D_array(uint8_t **input, uint16_t xlen);
void nr_free_uint8_2D_array(uint8_t **input,
uint16_t xlen);
void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len);
void nr_sort_asc_double_1D_array_ind(double *matrix,
uint8_t *ind,
uint8_t len);
void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len);
void nr_sort_asc_int16_1D_array_ind(int32_t *matrix,
int *ind,
int len);
void nr_free_double_2D_array(double **input, uint16_t xlen);
void updateLLR(double ***llr,
uint8_t **llrU,
uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen,
uint8_t approximation);
uint8_t **llrU,
uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen,
uint8_t approximation);
void updateBit(uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen);
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen);
void updatePathMetric(double *pathMetric,
double ***llr,
uint8_t listSize,
uint8_t bitValue,
uint16_t row,
uint8_t approximation);
double ***llr,
uint8_t listSize,
uint8_t bitValue,
uint16_t row,
uint8_t approximation);
void updatePathMetric2(double *pathMetric,
double ***llr,
uint8_t listSize,
uint16_t row,
uint8_t approximation);
double ***llr,
uint8_t listSize,
uint16_t row,
uint8_t approximation);
void computeLLR(double ***llr,
uint16_t row,
uint16_t col,
uint8_t i,
uint16_t offset,
uint8_t approximation);
uint16_t row,
uint16_t col,
uint8_t i,
uint16_t offset,
uint8_t approximation);
void updateCrcChecksum(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len);
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len);
void updateCrcChecksum2(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len);
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len);
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
@@ -364,14 +377,20 @@ uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits);
uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits);
//Also nr_polar_rate_matcher
static inline void nr_polar_interleaver(uint8_t *input, uint8_t *output, uint16_t *pattern, uint16_t size){
for (int i=0; i<size; i++)
output[i]=input[pattern[i]];
static inline void nr_polar_interleaver(uint8_t *input,
uint8_t *output,
uint16_t *pattern,
uint16_t size) {
for (int i=0; i<size; i++) output[i]=input[pattern[i]];
}
static inline void nr_polar_deinterleaver(uint8_t *input, uint8_t *output, uint16_t *pattern, uint16_t size){
for (int i=0; i<size; i++)
output[pattern[i]]=input[i];
static inline void nr_polar_deinterleaver(uint8_t *input,
uint8_t *output,
uint16_t *pattern,
uint16_t size) {
for (int i=0; i<size; i++) {
output[pattern[i]]=input[i];
}
}
#endif
@@ -42,306 +42,357 @@
//output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ...
void polar_encoder(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams)
{
if (polarParams->idx == 0){//PBCH
uint32_t *out,
t_nrPolar_params *polarParams) {
if (1) {//polarParams->idx == 0 || polarParams->idx == 1) { //PBCH or PDCCH
/*
uint64_t B = (((uint64_t)*in)&((((uint64_t)1)<<32)-1)) | (((uint64_t)crc24c((uint8_t*)in,polarParams->payloadBits)>>8)<<polarParams->payloadBits);
#ifdef DEBUG_POLAR_ENCODER
#ifdef DEBUG_POLAR_ENCODER
printf("polar_B %llx (crc %x)\n",B,crc24c((uint8_t*)in,polarParams->payloadBits)>>8);
#endif
nr_bit2byte_uint32_8((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*/
nr_bit2byte_uint32_8((uint32_t*)in, polarParams->payloadBits, polarParams->nr_polar_A);
#endif
nr_bit2byte_uint32_8_t((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*/
nr_bit2byte_uint32_8((uint32_t *)in, polarParams->payloadBits, polarParams->nr_polar_A);
/*
* Bytewise operations
*/
//Calculate CRC.
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_A,
polarParams->crc_generator_matrix,
polarParams->nr_polar_crc,
polarParams->payloadBits,
polarParams->crcParityBits);
for (uint8_t i = 0; i < polarParams->crcParityBits; i++)
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
//Attach CRC to the Transport Block. (a to b)
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_A,
polarParams->crc_generator_matrix,
polarParams->nr_polar_crc,
polarParams->payloadBits,
polarParams->crcParityBits);
for (uint8_t i = 0; i < polarParams->crcParityBits; i++)
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
//Attach CRC to the Transport Block. (a to b)
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
#ifdef DEBUG_POLAR_ENCODER
uint64_t B2=0;
for (int i = 0;i<polarParams->K;i++) B2 = B2 | ((uint64_t)polarParams->nr_polar_B[i] << i);
for (int i = 0; i<polarParams->K; i++) B2 = B2 | ((uint64_t)polarParams->nr_polar_B[i] << i);
printf("polar_B %llx\n",B2);
#endif
/* for (int j=0;j<polarParams->crcParityBits;j++) {
for (int i=0;i<polarParams->payloadBits;i++)
printf("%1d.%1d+",polarParams->crc_generator_matrix[i][j],polarParams->nr_polar_A[i]);
for (int i=0;i<polarParams->payloadBits;i++)
printf("%1d.%1d+",polarParams->crc_generator_matrix[i][j],polarParams->nr_polar_A[i]);
printf(" => %d\n",polarParams->nr_polar_crc[j]);
}*/
} else { //UCI
}
//Interleaving (c to c')
nr_polar_interleaver(polarParams->nr_polar_B,
polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern,
polarParams->K);
#ifdef DEBUG_POLAR_ENCODER
polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern,
polarParams->K);
#ifdef DEBUG_POLAR_ENCODER
uint64_t Cprime=0;
for (int i = 0;i<polarParams->K;i++) {
for (int i = 0; i<polarParams->K; i++) {
Cprime = Cprime | ((uint64_t)polarParams->nr_polar_CPrime[i] << i);
if (polarParams->nr_polar_CPrime[i] == 1) printf("pos %d : %llx\n",i,Cprime);
}
printf("polar_Cprime %llx\n",Cprime);
#endif
#endif
//Bit insertion (c' to u)
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
polarParams->nr_polar_U,
polarParams->N,
polarParams->K,
polarParams->Q_I_N,
polarParams->Q_PC_N,
polarParams->n_pc);
polarParams->nr_polar_U,
polarParams->N,
polarParams->K,
polarParams->Q_I_N,
polarParams->Q_PC_N,
polarParams->n_pc);
//Encoding (u to d)
/* memset(polarParams->nr_polar_U,0,polarParams->N);
polarParams->nr_polar_U[247]=1;
polarParams->nr_polar_U[253]=1;*/
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
polarParams->G_N,
polarParams->nr_polar_D,
polarParams->N,
polarParams->N);
polarParams->G_N,
polarParams->nr_polar_D,
polarParams->N,
polarParams->N);
for (uint16_t i = 0; i < polarParams->N; i++)
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
uint64_t D[8];
memset((void*)D,0,8*sizeof(int64_t));
memset((void *)D,0,8*sizeof(int64_t));
#ifdef DEBUG_POLAR_ENCODER
for (int i=0;i<polarParams->N;i++) D[i/64] |= ((uint64_t)polarParams->nr_polar_D[i])<<(i&63);
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
D[0],D[1],D[2],D[3],D[4],D[5],D[6],D[7]);
#endif
for (int i=0; i<polarParams->N; i++) D[i/64] |= ((uint64_t)polarParams->nr_polar_D[i])<<(i&63);
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
D[0],D[1],D[2],D[3],D[4],D[5],D[6],D[7]);
#endif
//Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e)
nr_polar_interleaver(polarParams->nr_polar_D,
polarParams->nr_polar_E,
polarParams->rate_matching_pattern,
polarParams->encoderLength);
polarParams->nr_polar_E,
polarParams->rate_matching_pattern,
polarParams->encoderLength);
/*
* Return bits.
*/
#ifdef DEBUG_POLAR_ENCODER
for (int i=0; i< polarParams->encoderLength;i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
#endif
for (int i=0; i< polarParams->encoderLength; i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
#endif
nr_byte2bit_uint8_32(polarParams->nr_polar_E, polarParams->encoderLength, out);
}
void polar_encoder_dci(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
uint16_t n_RNTI)
{
uint32_t *out,
t_nrPolar_params *polarParams,
uint16_t n_RNTI) {
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] in: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", in[0], in[1], in[2], in[3]);
#endif
/*
* Bytewise operations
*/
//(a to a')
nr_bit2byte_uint32_8(in, polarParams->payloadBits, polarParams->nr_polar_A);
for (int i=0; i<polarParams->crcParityBits; i++) polarParams->nr_polar_APrime[i]=1;
for (int i=0; i<polarParams->payloadBits; i++) polarParams->nr_polar_APrime[i+(polarParams->crcParityBits)]=polarParams->nr_polar_A[i];
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] A: ");
for (int i=0; i<polarParams->payloadBits; i++) printf("%d-", polarParams->nr_polar_A[i]);
printf("\n");
printf("[polar_encoder_dci] APrime: ");
for (int i=0; i<polarParams->K; i++) printf("%d-", polarParams->nr_polar_APrime[i]);
printf("\n");
printf("[polar_encoder_dci] GP: ");
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]);
printf("\n");
#endif
//Calculate CRC.
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_APrime,
polarParams->crc_generator_matrix,
polarParams->nr_polar_crc,
polarParams->K,
polarParams->crcParityBits);
polarParams->crc_generator_matrix,
polarParams->nr_polar_crc,
polarParams->K,
polarParams->crcParityBits);
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] CRC: ");
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]);
printf("\n");
#endif
//Attach CRC to the Transport Block. (a to b)
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
//Scrambling (b to c)
for (int i=0; i<16; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
( polarParams->nr_polar_B[polarParams->payloadBits+8+i] + ((n_RNTI>>(15-i))&1) ) % 2;
}
/* //(a to a')
nr_crc_bit2bit_uint32_8(in, polarParams->payloadBits, polarParams->nr_polar_aPrime);
//Parity bits computation (p)
polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits));
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] crc: 0x%08x\n", polarParams->crcBit);
for (int i=0; i<32; i++)
{
printf("%d\n",((polarParams->crcBit)>>i)&1);
}
#endif
//(a to b)
//
// Bytewise operations
//
uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0);
for (int i=0; i<arrayInd-1; i++){
for (int j=0; j<8; j++) {
polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
}
}
for (int i=0; i<((polarParams->payloadBits)%8); i++) {
polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
}
for (int i=0; i<8; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
}
//Scrambling (b to c)
for (int i=0; i<16; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2;
}*/
/* //(a to a')
nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime);
//Parity bits computation (p)
polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits));
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] crc: 0x%08x\n", polarParams->crcBit);
for (int i=0; i<32; i++)
{
printf("%d\n",((polarParams->crcBit)>>i)&1);
}
#endif
//(a to b)
//
// Bytewise operations
//
uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0);
for (int i=0; i<arrayInd-1; i++){
for (int j=0; j<8; j++) {
polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
}
}
for (int i=0; i<((polarParams->payloadBits)%8); i++) {
polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
}
for (int i=0; i<8; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
}
//Scrambling (b to c)
for (int i=0; i<16; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2;
}*/
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] B: ");
for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]);
printf("\n");
#endif
//Interleaving (c to c')
nr_polar_interleaver(polarParams->nr_polar_B,
polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern,
polarParams->K);
polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern,
polarParams->K);
//Bit insertion (c' to u)
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
polarParams->nr_polar_U,
polarParams->N,
polarParams->K,
polarParams->Q_I_N,
polarParams->Q_PC_N,
polarParams->n_pc);
polarParams->nr_polar_U,
polarParams->N,
polarParams->K,
polarParams->Q_I_N,
polarParams->Q_PC_N,
polarParams->n_pc);
//Encoding (u to d)
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
polarParams->G_N,
polarParams->nr_polar_D,
polarParams->N,
polarParams->N);
polarParams->G_N,
polarParams->nr_polar_D,
polarParams->N,
polarParams->N);
for (uint16_t i = 0; i < polarParams->N; i++)
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
//Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e)
nr_polar_interleaver(polarParams->nr_polar_D,
polarParams->nr_polar_E,
polarParams->rate_matching_pattern,
polarParams->encoderLength);
polarParams->nr_polar_E,
polarParams->rate_matching_pattern,
polarParams->encoderLength);
/*
* Return bits.
*/
nr_byte2bit_uint8_32(polarParams->nr_polar_E, polarParams->encoderLength, out);
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] E: ");
for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]);
uint8_t outputInd = ceil(polarParams->encoderLength / 32.0);
printf("\n[polar_encoder_dci] out: ");
for (int i = 0; i < outputInd; i++) {
printf("[%d]->0x%08x\t", i, out[i]);
}
#endif
}
static inline void polar_rate_matching(t_nrPolar_paramsPtr polarParams,void *in,void *out) __attribute__((always_inline));
static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,void *out) __attribute__((always_inline));
static inline void polar_rate_matching(t_nrPolar_paramsPtr polarParams,void *in,void *out) {
static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,void *out) {
if (polarParams->groupsize == 8)
for (int i=0;i<polarParams->encoderLength>>3;i++) ((uint8_t*)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]];
else
for (int i=0;i<polarParams->encoderLength>>4;i++) {
((uint16_t*)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
// handle rate matching with a single 128 bit word using bit shuffling
// can be done with SIMD intrisics if needed
if (polarParams->groupsize < 8) {
AssertFatal(polarParams->encoderLength<=128,"Need to handle groupsize<8 and N>128\n");
uint128_t *out128=(uint128_t*)out;
uint128_t *in128=(uint128_t*)in;
*out128=0;
uint128_t tmp0;
#ifdef DEBUG_POLAR_ENCODER
uint128_t tmp1;
#endif
for (int i=0; i<polarParams->encoderLength; i++) {
#ifdef DEBUG_POLAR_ENCODER
printf("%u<-%u : %llx.%llx =>",i,polarParams->rate_matching_pattern[i],((uint64_t *)out)[1],((uint64_t *)out)[0]);
#endif
tmp0 = (*in128&(((uint128_t)1)<<polarParams->rate_matching_pattern[i]));
if (tmp0!=0) {
*out128 = *out128 | ((uint128_t)1)<<i;
#ifdef DEBUG_POLAR_ENCODER
tmp1 = ((uint128_t)1)<<i;
printf("%llx.%llx<->%llx.%llx => %llx.%llx\n",
((uint64_t *)&tmp0)[1],((uint64_t *)&tmp0)[0],
((uint64_t *)&tmp1)[1],((uint64_t *)&tmp1)[0],
((uint64_t *)out)[1],((uint64_t *)out)[0]);
#endif
}
}
}
// These are based on LUTs for byte and short word groups
else if (polarParams->groupsize == 8)
for (int i=0; i<polarParams->encoderLength>>3; i++) ((uint8_t *)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]];
else // groupsize==16
for (int i=0; i<polarParams->encoderLength>>4; i++) {
((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
}
}
void build_polar_tables(t_nrPolar_paramsPtr polarParams) {
void build_polar_tables(t_nrPolar_params *polarParams) {
// build table b -> c'
AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 64, is not supported yet\n",polarParams->K);
int bit_i,ip;
int numbytes = polarParams->K>>3;
int residue = polarParams->K&7;
int numbits;
if (residue>0) numbytes++;
for (int byte=0;byte<numbytes;byte++) {
for (int byte=0; byte<numbytes; byte++) {
if (byte<(polarParams->K>>3)) numbits=8;
else numbits=residue;
for (int val=0;val<256;val++) {
for (int val=0; val<256; val++) {
polarParams->cprime_tab0[byte][val] = 0;
polarParams->cprime_tab1[byte][val] = 0;
for (int i=0;i<numbits;i++) {
// flip bit endian of B bitstring
ip=polarParams->deinterleaving_pattern[polarParams->K-1-((8*byte)+i)];
AssertFatal(ip<128,"ip = %d\n",ip);
bit_i=(val>>i)&1;
if (ip<64) polarParams->cprime_tab0[byte][val] |= (((uint64_t)bit_i)<<ip);
else polarParams->cprime_tab1[byte][val] |= (((uint64_t)bit_i)<<(ip&63));
for (int i=0; i<numbits; i++) {
// flip bit endian of B bitstring
ip=polarParams->deinterleaving_pattern[polarParams->K-1-((8*byte)+i)];
AssertFatal(ip<128,"ip = %d\n",ip);
bit_i=(val>>i)&1;
if (ip<64) polarParams->cprime_tab0[byte][val] |= (((uint64_t)bit_i)<<ip);
else polarParams->cprime_tab1[byte][val] |= (((uint64_t)bit_i)<<(ip&63));
}
}
}
AssertFatal(polarParams->N==512,"N = %d, not done yet\n",polarParams->N);
AssertFatal(polarParams->N==512 || polarParams->N==256 || polarParams->N==128,"N = %d, not done yet\n",polarParams->N);
// build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to 64 bit packed vectors.
// keep only rows of G which correspond to information/crc bits
polarParams->G_N_tab = (uint64_t**)malloc(polarParams->K * sizeof(int64_t*));
polarParams->G_N_tab = (uint64_t **)malloc(polarParams->K * sizeof(int64_t *));
int k=0;
for (int i=0;i<polarParams->N;i++) {
for (int i=0; i<polarParams->N; i++) {
if (polarParams->information_bit_pattern[i] > 0) {
polarParams->G_N_tab[k] = (uint64_t*)memalign(32,(polarParams->N/64)*sizeof(uint64_t));
memset((void*)polarParams->G_N_tab[k],0,(polarParams->N/64)*sizeof(uint64_t));
for (int j=0;j<polarParams->N;j++)
polarParams->G_N_tab[k][j/64] |= ((uint64_t)polarParams->G_N[i][j])<<(j&63);
polarParams->G_N_tab[k] = (uint64_t *)memalign(32,(polarParams->N/64)*sizeof(uint64_t));
memset((void *)polarParams->G_N_tab[k],0,(polarParams->N/64)*sizeof(uint64_t));
for (int j=0; j<polarParams->N; j++)
polarParams->G_N_tab[k][j/64] |= ((uint64_t)polarParams->G_N[i][j])<<(j&63);
#ifdef DEBUG_POLAR_ENCODER
printf("Bit %d Selecting row %d of G : ",k,i);
for (int j=0;j<polarParams->N;j+=4) printf("%1x",polarParams->G_N[i][j]+(polarParams->G_N[i][j+1]*2)+(polarParams->G_N[i][j+2]*4)+(polarParams->G_N[i][j+3]*8));
for (int j=0; j<polarParams->N; j+=4) printf("%1x",polarParams->G_N[i][j]+(polarParams->G_N[i][j+1]*2)+(polarParams->G_N[i][j+2]*4)+(polarParams->G_N[i][j+3]*8));
printf("\n");
#endif
k++;
@@ -352,63 +403,73 @@ void build_polar_tables(t_nrPolar_paramsPtr polarParams) {
int iplast=polarParams->rate_matching_pattern[0];
int ccnt=0;
int groupcnt=0;
#ifdef DEBUG_POLAR_ENCODER
int firstingroup_out=0;
int firstingroup_in=iplast;
#endif
int mingroupsize = 1024;
// compute minimum group size of rate-matching pattern
for (int outpos=1; outpos<polarParams->encoderLength; outpos++) {
ip=polarParams->rate_matching_pattern[outpos];
#ifdef DEBUG_POLAR_ENCODER
printf("rm: outpos %d, inpos %d\n",outpos,ip);
#endif
if ((ip - iplast) == 1) ccnt++;
else {
groupcnt++;
#ifdef DEBUG_POLAR_ENCODER
printf("group %d (size %d): (%d:%d) => (%d:%d)\n",groupcnt,ccnt+1,
firstingroup_in,firstingroup_in+ccnt,
firstingroup_out,firstingroup_out+ccnt);
firstingroup_in,firstingroup_in+ccnt,
firstingroup_out,firstingroup_out+ccnt);
#endif
if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1;
ccnt=0;
#ifdef DEBUG_POLAR_ENCODER
firstingroup_out=outpos;
firstingroup_in=ip;
#endif
}
iplast=ip;
}
AssertFatal(mingroupsize==8 || mingroupsize==16,"mingroupsize %d, needs to be handled\n",mingroupsize);
groupcnt++;
if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1;
#ifdef DEBUG_POLAR_ENCODER
printf("group %d (size %d): (%d:%d) => (%d:%d)\n",groupcnt,ccnt+1,
firstingroup_in,firstingroup_in+ccnt,
firstingroup_out,firstingroup_out+ccnt);
#endif
AssertFatal(mingroupsize==4 || mingroupsize==8 || mingroupsize==16,"mingroupsize %d, needs to be handled\n",mingroupsize);
polarParams->groupsize=mingroupsize;
int shift=3;
if (mingroupsize == 16) shift=4;
polarParams->rm_tab=(int*)malloc(sizeof(int)*polarParams->encoderLength/mingroupsize);
else if (mingroupsize == 4) shift=2;
polarParams->rm_tab=(int *)malloc(sizeof(int)*polarParams->encoderLength/mingroupsize);
// rerun again to create groups
int tcnt=0;
for (int outpos=0;outpos<polarParams->encoderLength; outpos+=mingroupsize,tcnt++)
for (int outpos=0; outpos<polarParams->encoderLength; outpos+=mingroupsize,tcnt++)
polarParams->rm_tab[tcnt] = polarParams->rate_matching_pattern[outpos]>>shift;
}
void polar_encoder_fast(uint64_t *Aprime,
uint32_t *out,
int32_t crcmask,
t_nrPolar_paramsPtr polarParams) {
void polar_encoder_fast(uint64_t *A,
uint32_t *out,
int32_t crcmask,
t_nrPolar_params *polarParams) {
AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits);
uint64_t B[4]={0,0,0,0}, Cprime[4]={0,0,0,0};
uint64_t B[4]= {0,0,0,0},Cprime[4]= {0,0,0,0};
int bitlen = polarParams->payloadBits;
#ifdef DEBUG_POLAR_MATLAB
if (polarParams->K<65) printf("[polar_encoder_fast]A[0] = 0x%llx\n", (unsigned long long)(Aprime[0])); //(unsigned long long)(Aprime[0]&(((uint64_t)1<<bitlen)-1)),
#endif
// append crc
AssertFatal(bitlen<129,"support for payloads <= 128 bits\n");
AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
//int bitlen0=bitlen;
uint64_t tcrc=0;
// A bit string should be stored as 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1,
@@ -418,42 +479,43 @@ void polar_encoder_fast(uint64_t *Aprime,
// CRC reads in each byte in bit positions 7 down to 0, for PBCH/PDCCH we need to read in a_{A-1} down to a_{0}, A = length of bit string (e.g. 32 for PBCH)
if (bitlen<=32) {
uint8_t A32_flip[4];
uint32_t AprimeTmp= (uint32_t)(((uint32_t)*Aprime)<<(32-bitlen));
A32_flip[0]=((uint8_t*)&AprimeTmp)[3]; //a'_0, a'_1, ..., a'_7
A32_flip[1]=((uint8_t*)&AprimeTmp)[2];
A32_flip[2]=((uint8_t*)&AprimeTmp)[1];
A32_flip[3]=((uint8_t*)&AprimeTmp)[0];
uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen));
A32_flip[0]=((uint8_t *)&Aprime)[3];
A32_flip[1]=((uint8_t *)&Aprime)[2];
A32_flip[2]=((uint8_t *)&Aprime)[1];
A32_flip[3]=((uint8_t *)&Aprime)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,bitlen)>>8)));
}
else if (bitlen<=64) {
} else if (bitlen<=64) {
uint8_t A64_flip[8];
uint64_t AprimeTmp= (uint32_t)(((uint64_t)*Aprime)<<(64-bitlen));
A64_flip[0]=((uint8_t*)&AprimeTmp)[7];
A64_flip[1]=((uint8_t*)&AprimeTmp)[6];
A64_flip[2]=((uint8_t*)&AprimeTmp)[5];
A64_flip[3]=((uint8_t*)&AprimeTmp)[4];
A64_flip[4]=((uint8_t*)&AprimeTmp)[3];
A64_flip[5]=((uint8_t*)&AprimeTmp)[2];
A64_flip[6]=((uint8_t*)&AprimeTmp)[1];
A64_flip[7]=((uint8_t*)&AprimeTmp)[0];
uint64_t Aprime= (uint32_t)(((uint64_t)*A)<<(64-bitlen));
A64_flip[0]=((uint8_t *)&Aprime)[7];
A64_flip[1]=((uint8_t *)&Aprime)[6];
A64_flip[2]=((uint8_t *)&Aprime)[5];
A64_flip[3]=((uint8_t *)&Aprime)[4];
A64_flip[4]=((uint8_t *)&Aprime)[3];
A64_flip[5]=((uint8_t *)&Aprime)[2];
A64_flip[6]=((uint8_t *)&Aprime)[1];
A64_flip[7]=((uint8_t *)&Aprime)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8)));
}
else if (bitlen<=128) {
uint8_t A128_flip[16];
uint128_t AprimeTmp= (uint32_t)(((uint128_t)*Aprime)<<(128-bitlen));
A128_flip[0]=((uint8_t*)&AprimeTmp)[15]; A128_flip[1]=((uint8_t*)&AprimeTmp)[14];
A128_flip[2]=((uint8_t*)&AprimeTmp)[13]; A128_flip[3]=((uint8_t*)&AprimeTmp)[12];
A128_flip[4]=((uint8_t*)&AprimeTmp)[11]; A128_flip[5]=((uint8_t*)&AprimeTmp)[10];
A128_flip[6] =((uint8_t*)&AprimeTmp)[9]; A128_flip[7] =((uint8_t*)&AprimeTmp)[8];
A128_flip[8] =((uint8_t*)&AprimeTmp)[7]; A128_flip[9] =((uint8_t*)&AprimeTmp)[6];
A128_flip[10]=((uint8_t*)&AprimeTmp)[5]; A128_flip[11]=((uint8_t*)&AprimeTmp)[4];
A128_flip[12]=((uint8_t*)&AprimeTmp)[3]; A128_flip[13]=((uint8_t*)&AprimeTmp)[2];
A128_flip[14]=((uint8_t*)&AprimeTmp)[1]; A128_flip[15]=((uint8_t*)&AprimeTmp)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,bitlen)>>8)));
uint8_t A128_flip[16];
uint128_t Aprime= (uint32_t)(((uint128_t)*A)<<(128-bitlen));
A128_flip[0]=((uint8_t*)&Aprime)[15]; A128_flip[1]=((uint8_t*)&Aprime)[14];
A128_flip[2]=((uint8_t*)&Aprime)[13]; A128_flip[3]=((uint8_t*)&Aprime)[12];
A128_flip[4]=((uint8_t*)&Aprime)[11]; A128_flip[5]=((uint8_t*)&Aprime)[10];
A128_flip[6] =((uint8_t*)&Aprime)[9]; A128_flip[7] =((uint8_t*)&Aprime)[8];
A128_flip[8] =((uint8_t*)&Aprime)[7]; A128_flip[9] =((uint8_t*)&Aprime)[6];
A128_flip[10]=((uint8_t*)&Aprime)[5]; A128_flip[11]=((uint8_t*)&Aprime)[4];
A128_flip[12]=((uint8_t*)&Aprime)[3]; A128_flip[13]=((uint8_t*)&Aprime)[2];
A128_flip[14]=((uint8_t*)&Aprime)[1]; A128_flip[15]=((uint8_t*)&Aprime)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,bitlen)>>8)));
}
int n;
int quadwlen = (polarParams->K>>6); // this is number of quadwords (64-bits) in the bit string
// this is number of quadwords in the bit string
int quadwlen = (polarParams->K>>6);
if ((polarParams->K&63) > 0) quadwlen++;
// Create the B bit string as
@@ -462,17 +524,13 @@ void polar_encoder_fast(uint64_t *Aprime,
//??? b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0
for (n=0;n<quadwlen;n++) if (n==0) B[n] = (Aprime[n] << polarParams->crcParityBits) | tcrc;
else B[n] = (Aprime[n] << polarParams->crcParityBits) | (Aprime[n-1]>>(64-polarParams->crcParityBits));
#ifdef DEBUG_POLAR_MATLAB
// B = pbchB
for (int i = 0; i < quadwlen; i++) printf("[polar_encoder_fast]B[%d] = 0x%llx\n", i, (unsigned long long)(B[i]));
#endif
for (n=0; n<quadwlen; n++) if (n==0) B[n] = (A[n] << polarParams->crcParityBits) | tcrc;
else B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits));
uint8_t *Bbyte = (uint8_t *)B;
uint8_t *Bbyte = (uint8_t*)B;
// for each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position
if (polarParams->K<65)
if (polarParams->K<65)
Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] |
polarParams->cprime_tab0[1][Bbyte[1]] |
polarParams->cprime_tab0[2][Bbyte[2]] |
@@ -481,9 +539,8 @@ void polar_encoder_fast(uint64_t *Aprime,
polarParams->cprime_tab0[5][Bbyte[5]] |
polarParams->cprime_tab0[6][Bbyte[6]] |
polarParams->cprime_tab0[7][Bbyte[7]];
else if (polarParams->K < 129) {
for (int i=0;i<1+(polarParams->K/8);i++) {
for (int i=0; i<1+(polarParams->K/8); i++) {
Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]];
Cprime[1] |= polarParams->cprime_tab1[i][Bbyte[i]];
}
@@ -495,80 +552,155 @@ void polar_encoder_fast(uint64_t *Aprime,
#endif
#ifdef DEBUG_POLAR_ENCODER
if (polarParams->K<65)
if (polarParams->K<65)
printf("A %llx B %llx Cprime %llx (payload bits %d,crc %x)\n",
(unsigned long long)(Aprime[0]&(((uint64_t)1<<bitlen)-1)),
(unsigned long long)(B[0]),
(unsigned long long)(Cprime[0]),
polarParams->payloadBits,
tcrc);
(unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)),
(unsigned long long)(B[0]),
(unsigned long long)(Cprime[0]),
polarParams->payloadBits,
tcrc);
else if (polarParams->K<129) {
if (bitlen<64)
printf("A %llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n",
(unsigned long long)(Aprime[0]&(((uint64_t)1<<bitlen)-1)),
(unsigned long long)(B[1]),(unsigned long long)(B[0]),
(unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
polarParams->payloadBits,
tcrc);
else
(unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)),
(unsigned long long)(B[1]),(unsigned long long)(B[0]),
(unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
polarParams->payloadBits,
tcrc);
else
printf("A %llx|%llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n",
(unsigned long long)(Aprime[1]&(((uint64_t)1<<(bitlen-64))-1)),(unsigned long long)(Aprime[0]),
(unsigned long long)(B[1]),(unsigned long long)(B[0]),
(unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
polarParams->payloadBits,
crc24c((uint8_t*)Aprime,bitlen)>>8);
(unsigned long long)(A[1]&(((uint64_t)1<<(bitlen-64))-1)),(unsigned long long)(A[0]),
(unsigned long long)(B[1]),(unsigned long long)(B[0]),
(unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
polarParams->payloadBits,
crc24c((uint8_t *)A,bitlen)>>8);
}
#endif
/* printf("Bbytes : %x.%x.%x.%x.%x.%x.%x.%x\n",Bbyte[0],Bbyte[1],Bbyte[2],Bbyte[3],Bbyte[4],Bbyte[5],Bbyte[6],Bbyte[7]);
printf("%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",polarParams->cprime_tab[0][Bbyte[0]] ,
polarParams->cprime_tab[1][Bbyte[1]] ,
polarParams->cprime_tab[2][Bbyte[2]] ,
polarParams->cprime_tab[3][Bbyte[3]] ,
polarParams->cprime_tab[4][Bbyte[4]] ,
polarParams->cprime_tab[5][Bbyte[5]] ,
polarParams->cprime_tab[6][Bbyte[6]] ,
polarParams->cprime_tab[7][Bbyte[7]]);*/
// now do Gu product (here using 64-bit XORs, we can also do with SIMD after)
// here we're reading out the bits LSB -> MSB, is this correct w.r.t. 3GPP ?
uint64_t Cprime_i;
uint64_t D[8]={0,0,0,0,0,0,0,0};
/* printf("%llx Cprime_0 (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",Cprime_i,Cprime &1,
polarParams->G_N_tab[0][0],
polarParams->G_N_tab[0][1],
polarParams->G_N_tab[0][2],
polarParams->G_N_tab[0][3],
polarParams->G_N_tab[0][4],
polarParams->G_N_tab[0][5],
polarParams->G_N_tab[0][6],
polarParams->G_N_tab[0][7]);*/
uint64_t D[8]= {0,0,0,0,0,0,0,0};
int off=0;
int len=polarParams->K;
for (int j=0;j<(1+(polarParams->K>>6));j++,off+=64,len-=64) {
for (int i=0;i<((len>63) ? 64 : len);i++) {
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
#ifdef DEBUG_POLAR_ENCODER
printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
Cprime_i,off+i,(Cprime[j]>>i) &1,
polarParams->G_N_tab[off+i][0],
polarParams->G_N_tab[off+i][1],
polarParams->G_N_tab[off+i][2],
polarParams->G_N_tab[off+i][3],
polarParams->G_N_tab[off+i][4],
polarParams->G_N_tab[off+i][5],
polarParams->G_N_tab[off+i][6],
polarParams->G_N_tab[off+i][7]);
#endif
uint64_t *Gi=polarParams->G_N_tab[off+i];
D[0] ^= (Cprime_i & Gi[0]);
D[1] ^= (Cprime_i & Gi[1]);
D[2] ^= (Cprime_i & Gi[2]);
D[3] ^= (Cprime_i & Gi[3]);
D[4] ^= (Cprime_i & Gi[4]);
D[5] ^= (Cprime_i & Gi[5]);
D[6] ^= (Cprime_i & Gi[6]);
D[7] ^= (Cprime_i & Gi[7]);
if (polarParams->N==512) {
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
for (int i=0; i<((len>63) ? 64 : len); i++) {
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
/*
#ifdef DEBUG_POLAR_ENCODER
printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
Cprime_i,off+i,(Cprime[j]>>i) &1,
polarParams->G_N_tab[off+i][0],
polarParams->G_N_tab[off+i][1],
polarParams->G_N_tab[off+i][2],
polarParams->G_N_tab[off+i][3],
polarParams->G_N_tab[off+i][4],
polarParams->G_N_tab[off+i][5],
polarParams->G_N_tab[off+i][6],
polarParams->G_N_tab[off+i][7]);
#endif
*/
uint64_t *Gi=polarParams->G_N_tab[off+i];
D[0] ^= (Cprime_i & Gi[0]);
D[1] ^= (Cprime_i & Gi[1]);
D[2] ^= (Cprime_i & Gi[2]);
D[3] ^= (Cprime_i & Gi[3]);
D[4] ^= (Cprime_i & Gi[4]);
D[5] ^= (Cprime_i & Gi[5]);
D[6] ^= (Cprime_i & Gi[6]);
D[7] ^= (Cprime_i & Gi[7]);
#ifdef DEBUG_POLAR_ENCODER
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
D[0],
D[1],
D[2],
D[3],
D[4],
D[5],
D[6],
D[7]);
#endif
}
}
}
else if (polarParams->N==256) {
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
for (int i=0; i<((len>63) ? 64 : len); i++) {
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
/*
#ifdef DEBUG_POLAR_ENCODER
printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx\n",
Cprime_i,off+i,(Cprime[j]>>i) &1,
polarParams->G_N_tab[off+i][0],
polarParams->G_N_tab[off+i][1],
polarParams->G_N_tab[off+i][2],
polarParams->G_N_tab[off+i][3],
#endif
*/
uint64_t *Gi=polarParams->G_N_tab[off+i];
D[0] ^= (Cprime_i & Gi[0]);
D[1] ^= (Cprime_i & Gi[1]);
D[2] ^= (Cprime_i & Gi[2]);
D[3] ^= (Cprime_i & Gi[3]);
#ifdef DEBUG_POLAR_ENCODER
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n", D[0], D[1], D[2], D[3], D[4], D[5], D[6], D[7]);
printf("D %llx,%llx,%llx,%llx\n",
D[0],
D[1],
D[2],
D[3]);
#endif
#ifdef DEBUG_POLAR_MATLAB
// D = pbchD
for (int i = 0; i < 8; i++) printf("[polar_encoder_fast]D[%d] = 0x%016llx\n", i, (unsigned long long)(D[i]));
#endif
polar_rate_matching(polarParams,(void*)D,(void*)out);
#ifdef DEBUG_POLAR_MATLAB
// out = pbchF
for (int i = 0; i < (NR_POLAR_PBCH_E/32); i++) printf("[polar_encoder_fast]F[%d] = 0x%08lx\n", i, (unsigned long)(out[i]));
}
}
}
else if (polarParams->N==128) {
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
for (int i=0; i<((len>63) ? 64 : len); i++) {
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
#ifdef DEBUG_POLAR_ENCODER
printf("%llx Cprime_%d (%d+%d) (%llx) G %llx,%llx\n",
Cprime_i,off+i,off,i,(Cprime[j]>>i) &1,
polarParams->G_N_tab[off+i][0],
polarParams->G_N_tab[off+i][1]);
#endif
uint64_t *Gi=polarParams->G_N_tab[off+i];
D[0] ^= (Cprime_i & Gi[0]);
D[1] ^= (Cprime_i & Gi[1]);
#ifdef DEBUG_POLAR_ENCODER
printf("D %llx,%llx\n",
D[0],
D[1]);
#endif
}
}
}
memset((void*)out,0,polarParams->encoderLength>>3);
polar_rate_matching(polarParams,(void *)D,(void *)out);
}
@@ -28,322 +28,320 @@
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_bit_insertion(uint8_t *input,
uint8_t *output,
uint16_t N,
uint16_t K,
int16_t *Q_I_N,
int16_t *Q_PC_N,
uint8_t n_PC)
uint8_t *output,
uint16_t N,
uint16_t K,
int16_t *Q_I_N,
int16_t *Q_PC_N,
uint8_t n_PC)
{
uint16_t k=0;
uint8_t flag;
if (n_PC>0) {
/*
*
*/
} else {
for (int n=0; n<=N-1; n++) {
flag=0;
for (int m=0; m<=(K+n_PC)-1; m++) {
if ( n == Q_I_N[m]) {
flag=1;
break;
}
}
if (flag) { // n ϵ Q_I_N
output[n]=input[k];
k++;
} else {
output[n] = 0;
}
}
if (n_PC>0) {
/*
*
*/
} else {
for (int n=0; n<=N-1; n++) {
flag=0;
for (int m=0; m<=(K+n_PC)-1; m++) {
if ( n == Q_I_N[m]) {
flag=1;
break;
}
}
if (flag) { // n ϵ Q_I_N
output[n]=input[k];
k++;
} else {
output[n] = 0;
}
}
}
}
uint32_t nr_polar_output_length(uint16_t K,
uint16_t E,
uint8_t n_max)
uint16_t E,
uint8_t n_max)
{
uint8_t n_1, n_2, n_min=5, n;
double R_min=1.0/8;
uint8_t n_1, n_2, n_min=5, n;
double R_min=1.0/8;
if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) {
n_1 = ceil(log2(E))-1;
} else {
n_1 = ceil(log2(E));
}
n_2 = ceil(log2(K/R_min));
n=n_max;
if (n>n_1) n=n_1;
if (n>n_2) n=n_2;
if (n<n_min) n=n_min;
if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) {
n_1 = ceil(log2(E))-1;
} else {
n_1 = ceil(log2(E));
}
n_2 = ceil(log2(K/R_min));
n=n_max;
if (n>n_1) n=n_1;
if (n>n_2) n=n_2;
if (n<n_min) n=n_min;
return ((uint32_t) pow(2.0,n)); //=polar_code_output_length
/* printf("nr_polar_output_length: K %d, E %d, n %d (n_max %d,n_min %d, n_1 %d,n_2 %d)\n",
K,E,n,n_max,n_min,n_1,n_2);
exit(-1);*/
return ((uint32_t) pow(2.0,n)); //=polar_code_output_length
}
void nr_polar_channel_interleaver_pattern(uint16_t *cip,
uint8_t I_BIL,
uint16_t E)
uint8_t I_BIL,
uint16_t E)
{
if (I_BIL == 1) {
uint16_t T=0, k;
while( ((T/2)*(T+1)) < E ) T++;
int16_t **v = malloc(T * sizeof(*v));
for (int i = 0; i <= T-1; i++) v[i] = malloc((T-i) * sizeof(*(v[i])));
k=0;
for (int i = 0; i <= T-1; i++) {
for (int j = 0; j <= (T-1)-i; j++) {
if (k<E) {
v[i][j] = k;
} else {
v[i][j] = (-1);
}
k++;
}
}
k=0;
for (int j = 0; j <= T-1; j++) {
for (int i = 0; i <= (T-1)-j; i++) {
if ( v[i][j] != (-1) ) {
cip[k]=v[i][j];
k++;
}
}
}
for (int i = 0; i <= T-1; i++) free(v[i]);
free(v);
if (I_BIL == 1) {
uint16_t T=0, k;
while( ((T/2)*(T+1)) < E ) T++;
int16_t **v = malloc(T * sizeof(*v));
for (int i = 0; i <= T-1; i++) v[i] = malloc((T-i) * sizeof(*(v[i])));
k=0;
for (int i = 0; i <= T-1; i++) {
for (int j = 0; j <= (T-1)-i; j++) {
if (k<E) {
v[i][j] = k;
} else {
for (int i=0; i<=E-1; i++) cip[i]=i;
v[i][j] = (-1);
}
k++;
}
}
k=0;
for (int j = 0; j <= T-1; j++) {
for (int i = 0; i <= (T-1)-j; i++) {
if ( v[i][j] != (-1) ) {
cip[k]=v[i][j];
k++;
}
}
}
for (int i = 0; i <= T-1; i++) free(v[i]);
free(v);
} else {
for (int i=0; i<=E-1; i++) cip[i]=i;
}
}
void nr_polar_info_bit_pattern(uint8_t *ibp,
int16_t *Q_I_N,
int16_t *Q_F_N,
uint16_t *J,
const uint16_t *Q_0_Nminus1,
uint16_t K,
uint16_t N,
uint16_t E,
uint8_t n_PC)
int16_t *Q_I_N,
int16_t *Q_F_N,
uint16_t *J,
const uint16_t *Q_0_Nminus1,
uint16_t K,
uint16_t N,
uint16_t E,
uint8_t n_PC)
{
int16_t *Q_Ftmp_N = malloc(sizeof(int16_t) * (N + 1)); // Last element shows the final
int16_t *Q_Itmp_N = malloc(sizeof(int16_t) * (N + 1)); // array index assigned a value.
int16_t *Q_Ftmp_N = malloc(sizeof(int16_t) * (N + 1)); // Last element shows the final
int16_t *Q_Itmp_N = malloc(sizeof(int16_t) * (N + 1)); // array index assigned a value.
for (int i = 0; i <= N; i++) {
Q_Ftmp_N[i] = -1; // Empty array.
Q_Itmp_N[i] = -1;
for (int i = 0; i <= N; i++) {
Q_Ftmp_N[i] = -1; // Empty array.
Q_Itmp_N[i] = -1;
}
uint8_t flag;
uint16_t limit, ind;
if (E < N) {
if ((K / (double) E) <= (7.0 / 16)) { //puncturing
for (int n = 0; n <= N - E - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
if ((E / (double) N) >= (3.0 / 4)) {
limit = ceil((double) (3 * N - 2 * E) / 4);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
uint8_t flag;
uint16_t limit, ind;
if (E < N) {
if ((K / (double) E) <= (7.0 / 16)) { //puncturing
for (int n = 0; n <= N - E - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
if ((E / (double) N) >= (3.0 / 4)) {
limit = ceil((double) (3 * N - 2 * E) / 4);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
} else {
limit = ceil((double) (9 * N - 4 * E) / 16);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
}
} else { //shortening
for (int n = E; n <= N - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
}
} else {
limit = ceil((double) (9 * N - 4 * E) / 16);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
}
} else { //shortening
for (int n = E; n <= N - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
}
}
//Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
for (int n = 0; n <= N - 1; n++) {
flag = 1;
for (int m = 0; m <= Q_Ftmp_N[N]; m++) {
if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) {
flag = 0;
break;
}
}
if (flag) {
Q_Itmp_N[Q_Itmp_N[N] + 1] = Q_0_Nminus1[n];
Q_Itmp_N[N]++;
}
}
//Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
for (int n = 0; n <= N - 1; n++) {
flag = 1;
for (int m = 0; m <= Q_Ftmp_N[N]; m++) {
if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) {
flag = 0;
break;
}
}
if (flag) {
Q_Itmp_N[Q_Itmp_N[N] + 1] = Q_0_Nminus1[n];
Q_Itmp_N[N]++;
}
}
//Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N
for (int n = 0; n <= (K + n_PC) - 1; n++) {
ind = Q_Itmp_N[N] + n - ((K + n_PC) - 1);
Q_I_N[n] = Q_Itmp_N[ind];
}
//Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N
for (int n = 0; n <= (K + n_PC) - 1; n++) {
ind = Q_Itmp_N[N] + n - ((K + n_PC) - 1);
Q_I_N[n] = Q_Itmp_N[ind];
}
//Q_F_N = Q_0_N-1 \ Q_I_N
for (int n = 0; n <= N - 1; n++) {
flag = 1;
for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (Q_0_Nminus1[n] == Q_I_N[m]) {
flag = 0;
break;
}
}
if (flag) {
Q_F_N[Q_F_N[N] + 1] = Q_0_Nminus1[n];
Q_F_N[N]++;
}
}
//Q_F_N = Q_0_N-1 \ Q_I_N
for (int n = 0; n <= N - 1; n++) {
flag = 1;
for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (Q_0_Nminus1[n] == Q_I_N[m]) {
flag = 0;
break;
}
}
if (flag) {
Q_F_N[Q_F_N[N] + 1] = Q_0_Nminus1[n];
Q_F_N[N]++;
}
}
//Information Bit Pattern
for (int n = 0; n <= N - 1; n++) {
ibp[n] = 0;
//Information Bit Pattern
for (int n = 0; n <= N - 1; n++) {
ibp[n] = 0;
for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (n == Q_I_N[m]) {
ibp[n] = 1;
break;
}
}
}
for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (n == Q_I_N[m]) {
ibp[n] = 1;
break;
}
}
}
free(Q_Ftmp_N);
free(Q_Itmp_N);
free(Q_Ftmp_N);
free(Q_Itmp_N);
}
void nr_polar_info_bit_extraction(uint8_t *input,
uint8_t *output,
uint8_t *pattern,
uint16_t size)
uint8_t *output,
uint8_t *pattern,
uint16_t size)
{
uint16_t j = 0;
for (int i = 0; i < size; i++) {
if (pattern[i] > 0) {
output[j] = input[i];
j++;
}
}
uint16_t j = 0;
for (int i = 0; i < size; i++) {
if (pattern[i] > 0) {
output[j] = input[i];
j++;
}
}
}
void nr_polar_rate_matching_pattern(uint16_t *rmp,
uint16_t *J,
const uint8_t *P_i_,
uint16_t K,
uint16_t N,
uint16_t E)
uint16_t *J,
const uint8_t *P_i_,
uint16_t K,
uint16_t N,
uint16_t E)
{
uint8_t i;
uint16_t *d, *y, ind;
d = (uint16_t *)malloc(sizeof(uint16_t) * N);
y = (uint16_t *)malloc(sizeof(uint16_t) * N);
uint8_t i;
uint16_t *d, *y, ind;
d = (uint16_t *)malloc(sizeof(uint16_t) * N);
y = (uint16_t *)malloc(sizeof(uint16_t) * N);
for (int m=0; m<=N-1; m++) d[m]=m;
for (int m=0; m<=N-1; m++) d[m]=m;
for (int m=0; m<=N-1; m++){
i=floor((32*m)/N);
J[m] = (P_i_[i]*(N/32)) + (m%(N/32));
y[m] = d[J[m]];
}
for (int m=0; m<=N-1; m++){
i=floor((32*m)/N);
J[m] = (P_i_[i]*(N/32)) + (m%(N/32));
y[m] = d[J[m]];
}
if (E>=N) { //repetition
for (int k=0; k<=E-1; k++) {
ind = (k%N);
rmp[k]=y[ind];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k+N-E];
}
} else { //shortening
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k];
}
}
}
if (E>=N) { //repetition
for (int k=0; k<=E-1; k++) {
ind = (k%N);
rmp[k]=y[ind];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k+N-E];
}
} else { //shortening
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k];
}
}
}
free(d);
free(y);
free(d);
free(y);
}
void nr_polar_rate_matching(double *input,
double *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E)
double *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E)
{
if (E>=N) { //repetition
for (int i=0; i<=N-1; i++) output[i]=0;
for (int i=0; i<=E-1; i++){
output[rmp[i]]+=input[i];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int i=0; i<=N-1; i++) output[i]=0;
} else { //shortening
for (int i=0; i<=N-1; i++) output[i]=INFINITY;
}
if (E>=N) { //repetition
for (int i=0; i<=N-1; i++) output[i]=0;
for (int i=0; i<=E-1; i++){
output[rmp[i]]+=input[i];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int i=0; i<=N-1; i++) output[i]=0;
} else { //shortening
for (int i=0; i<=N-1; i++) output[i]=INFINITY;
}
for (int i=0; i<=E-1; i++){
output[rmp[i]]=input[i];
}
}
for (int i=0; i<=E-1; i++){
output[rmp[i]]=input[i];
}
}
}
void nr_polar_rate_matching_int16(int16_t *input,
int16_t *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E)
int16_t *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E)
{
if (E>=N) { //repetition
for (int i=0; i<=N-1; i++) output[i]=0;
for (int i=0; i<=E-1; i++){
output[rmp[i]]+=input[i];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int i=0; i<=N-1; i++) output[i]=0;
} else { //shortening
for (int i=0; i<=N-1; i++) output[i]=32767;//instead of INFINITY, to prevent [-Woverflow]
}
if (E>=N) { //repetition
memset((void*)output,0,N*sizeof(int16_t));
for (int i=0; i<=E-1; i++) output[rmp[i]]+=input[i];
} else {
if ( (K/(double)E) <= (7.0/16) ) memset((void*)output,0,N*sizeof(int16_t)); //puncturing
else { //shortening
for (int i=0; i<=N-1; i++) output[i]=32767;//instead of INFINITY, to prevent [-Woverflow]
}
for (int i=0; i<=E-1; i++){
output[rmp[i]]=input[i];
}
}
for (int i=0; i<=E-1; i++) output[rmp[i]]=input[i];
}
}
@@ -48,8 +48,8 @@ uint16_t decodeSmallBlock(int8_t *in, uint8_t len){
int16_t Rhat[NR_SMALL_BLOCK_CODED_BITS] = {0}, Rhatabs[NR_SMALL_BLOCK_CODED_BITS] = {0};
uint16_t maxVal;
uint8_t maxInd = 0;
for (int j = 0; j < NR_SMALL_BLOCK_CODED_BITS; ++j)
int jmax = (1<<(len-1));
for (int j = 0; j < jmax; ++j)
for (int k = 0; k < NR_SMALL_BLOCK_CODED_BITS; ++k)
Rhat[j] += in[k] * hadamard32InterleavedTransposed[j][k];
@@ -67,7 +67,7 @@ uint16_t decodeSmallBlock(int8_t *in, uint8_t len){
}
#endif
maxVal = Rhatabs[0];
for (int k = 1; k < NR_SMALL_BLOCK_CODED_BITS; ++k){
for (int k = 1; k < jmax; ++k){
if (Rhatabs[k] > maxVal){
maxVal = Rhatabs[k];
maxInd = k;
@@ -77,7 +77,7 @@ uint16_t decodeSmallBlock(int8_t *in, uint8_t len){
out = properOrderedBasis[maxInd] | ( (Rhat[maxInd] > 0) ? (uint16_t)0 : (uint16_t)1 );
#ifdef DEBUG_DECODESMALLBLOCK
for (int k = 0; k < NR_SMALL_BLOCK_CODED_BITS; ++k)
for (int k = 0; k < jmax; ++k)
printf("[decodeSmallBlock]Rhat[%d]=%d %d %d %d\n",k, Rhat[k], maxVal, maxInd, ((uint32_t)out>>k)&1);
printf("[decodeSmallBlock]0x%x 0x%x\n", out, properOrderedBasis[maxInd]);
#endif
+152 -178
View File
@@ -37,201 +37,175 @@
#include "PHY/NR_TRANSPORT/nr_dci.h"
static int intcmp(const void *p1,const void *p2) {
return(*(int16_t*)p1 > *(int16_t*)p2);
return(*(int16_t *)p1 > *(int16_t *)p2);
}
void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level)
{
t_nrPolar_paramsPtr currentPtr = *polarParams;
uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level);
static void nr_polar_init(t_nrPolar_params * *polarParams,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level) {
t_nrPolar_params *currentPtr = *polarParams;
uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level);
//Parse the list. If the node is already created, return without initialization.
while (currentPtr != NULL) {
//printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength);
if (currentPtr->idx == (messageType * messageLength * aggregation_prime)) return;
else currentPtr = currentPtr->nextPtr;
}
//Parse the list. If the node is already created, return without initialization.
while (currentPtr != NULL) {
//printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength);
if (currentPtr->idx == (messageType * messageLength * aggregation_prime)) return;
else currentPtr = currentPtr->nextPtr;
}
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
//Else, initialize and add node to the end of the linked list.
t_nrPolar_paramsPtr newPolarInitNode = malloc(sizeof(t_nrPolar_params));
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
//Else, initialize and add node to the end of the linked list.
t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params));
if (newPolarInitNode != NULL) {
if (newPolarInitNode != NULL) {
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
newPolarInitNode->nextPtr = NULL;
//printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level);
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
newPolarInitNode->nextPtr = (t_nrPolar_params *)NULL;
if (messageType == 0) { //PBCH
newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX;
newPolarInitNode->i_il = NR_POLAR_PBCH_I_IL;
newPolarInitNode->i_seg = NR_POLAR_PBCH_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_PBCH_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_PBCH_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_PBCH_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_PBCH_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = NR_POLAR_PBCH_PAYLOAD_BITS;
newPolarInitNode->encoderLength = NR_POLAR_PBCH_E;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P
//printf("Initializing polar parameters for PBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength);
} else if (messageType == 1) { //DCI
newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX;
newPolarInitNode->i_il = NR_POLAR_DCI_I_IL;
newPolarInitNode->i_seg = NR_POLAR_DCI_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_DCI_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_DCI_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_DCI_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_DCI_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->encoderLength = aggregation_level*108;
newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
//printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level);
} else if (messageType == -1) { //UCI
} else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
}
//printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level);
newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode.
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K, newPolarInitNode->encoderLength, newPolarInitNode->n_max);
newPolarInitNode->n = log2(newPolarInitNode->N);
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
//polar_encoder vectors:
newPolarInitNode->nr_polar_crc = malloc(sizeof(uint8_t) * newPolarInitNode->crcParityBits);
newPolarInitNode->nr_polar_aPrime = malloc(sizeof(uint8_t) * ((ceil((newPolarInitNode->payloadBits)/32.0)*4)+3));
newPolarInitNode->nr_polar_APrime = malloc(sizeof(uint8_t) * newPolarInitNode->K);
newPolarInitNode->nr_polar_D = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->nr_polar_E = malloc(sizeof(uint8_t) * newPolarInitNode->encoderLength);
//Polar Coding vectors
newPolarInitNode->nr_polar_U = malloc(sizeof(uint8_t) * newPolarInitNode->N); //Decoder: nr_polar_uHat
newPolarInitNode->nr_polar_CPrime = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_cHat
newPolarInitNode->nr_polar_B = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_bHat
newPolarInitNode->nr_polar_A = malloc(sizeof(uint8_t) * newPolarInitNode->payloadBits); //Decoder: nr_polar_aHat
newPolarInitNode->Q_0_Nminus1 = nr_polar_sequence_pattern(newPolarInitNode->n);
newPolarInitNode->interleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
nr_polar_interleaving_pattern(newPolarInitNode->K,
newPolarInitNode->i_il,
newPolarInitNode->interleaving_pattern);
newPolarInitNode->deinterleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
if (messageType == 0) { //PBCH
newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX;
newPolarInitNode->i_il = NR_POLAR_PBCH_I_IL;
newPolarInitNode->i_seg = NR_POLAR_PBCH_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_PBCH_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_PBCH_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_PBCH_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_PBCH_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = NR_POLAR_PBCH_PAYLOAD_BITS;
newPolarInitNode->encoderLength = NR_POLAR_PBCH_E;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P
//printf("Initializing polar parameters for PBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength);
} else if (messageType == 1) { //DCI
newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX;
newPolarInitNode->i_il = NR_POLAR_DCI_I_IL;
newPolarInitNode->i_seg = NR_POLAR_DCI_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_DCI_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_DCI_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_DCI_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_DCI_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->encoderLength = aggregation_level*108;
newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
//printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level);
} else if (messageType == -1) { //UCI
for (int i=0; i<newPolarInitNode->K; i++)
newPolarInitNode->deinterleaving_pattern[newPolarInitNode->interleaving_pattern[i]] = i;
} else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
}
newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
uint16_t *J = malloc(sizeof(uint16_t) * newPolarInitNode->N);
nr_polar_rate_matching_pattern(newPolarInitNode->rate_matching_pattern,
J,
nr_polar_subblock_interleaver_pattern,
newPolarInitNode->K,
newPolarInitNode->N,
newPolarInitNode->encoderLength);
newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc));
newPolarInitNode->Q_F_N = malloc( sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value.
newPolarInitNode->Q_PC_N = malloc( sizeof(int16_t) * (newPolarInitNode->n_pc));
newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode.
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K, newPolarInitNode->encoderLength, newPolarInitNode->n_max);
newPolarInitNode->n = log2(newPolarInitNode->N);
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
for (int i = 0; i <= newPolarInitNode->N; i++)
newPolarInitNode->Q_F_N[i] = -1; // Empty array.
//polar_encoder vectors:
newPolarInitNode->nr_polar_crc = malloc(sizeof(uint8_t) * newPolarInitNode->crcParityBits);
newPolarInitNode->nr_polar_aPrime = malloc(sizeof(uint8_t) * ((ceil((newPolarInitNode->payloadBits)/32.0)*4)+3));
newPolarInitNode->nr_polar_APrime = malloc(sizeof(uint8_t) * newPolarInitNode->K);
newPolarInitNode->nr_polar_D = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->nr_polar_E = malloc(sizeof(uint8_t) * newPolarInitNode->encoderLength);
nr_polar_info_bit_pattern(newPolarInitNode->information_bit_pattern,
newPolarInitNode->Q_I_N,
newPolarInitNode->Q_F_N,
J,
newPolarInitNode->Q_0_Nminus1,
newPolarInitNode->K,
newPolarInitNode->N,
newPolarInitNode->encoderLength,
newPolarInitNode->n_pc);
// sort the Q_I_N array in ascending order (first K positions)
qsort((void *)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp);
newPolarInitNode->channel_interleaver_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
nr_polar_channel_interleaver_pattern(newPolarInitNode->channel_interleaver_pattern,
newPolarInitNode->i_bil,
newPolarInitNode->encoderLength);
free(J);
build_decoder_tree(newPolarInitNode);
build_polar_tables(newPolarInitNode);
init_polar_deinterleaver_table(newPolarInitNode);
//printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
} else {
AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_params * could not be created");
}
//Polar Coding vectors
newPolarInitNode->nr_polar_U = malloc(sizeof(uint8_t) * newPolarInitNode->N); //Decoder: nr_polar_uHat
newPolarInitNode->nr_polar_CPrime = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_cHat
newPolarInitNode->nr_polar_B = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_bHat
newPolarInitNode->nr_polar_A = malloc(sizeof(uint8_t) * newPolarInitNode->payloadBits); //Decoder: nr_polar_aHat
newPolarInitNode->Q_0_Nminus1 = nr_polar_sequence_pattern(newPolarInitNode->n);
newPolarInitNode->interleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
nr_polar_interleaving_pattern(newPolarInitNode->K,
newPolarInitNode->i_il,
newPolarInitNode->interleaving_pattern);
newPolarInitNode->deinterleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
for (int i=0;i<newPolarInitNode->K;i++)
newPolarInitNode->deinterleaving_pattern[newPolarInitNode->interleaving_pattern[i]] = i;
newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
uint16_t *J = malloc(sizeof(uint16_t) * newPolarInitNode->N);
nr_polar_rate_matching_pattern(newPolarInitNode->rate_matching_pattern,
J,
nr_polar_subblock_interleaver_pattern,
newPolarInitNode->K,
newPolarInitNode->N,
newPolarInitNode->encoderLength);
newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc));
newPolarInitNode->Q_F_N = malloc( sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value.
newPolarInitNode->Q_PC_N = malloc( sizeof(int16_t) * (newPolarInitNode->n_pc));
for (int i = 0; i <= newPolarInitNode->N; i++)
newPolarInitNode->Q_F_N[i] = -1; // Empty array.
nr_polar_info_bit_pattern(newPolarInitNode->information_bit_pattern,
newPolarInitNode->Q_I_N,
newPolarInitNode->Q_F_N,
J,
newPolarInitNode->Q_0_Nminus1,
newPolarInitNode->K,
newPolarInitNode->N,
newPolarInitNode->encoderLength,
newPolarInitNode->n_pc);
// sort the Q_I_N array in ascending order (first K positions)
qsort((void*)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp);
newPolarInitNode->channel_interleaver_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
nr_polar_channel_interleaver_pattern(newPolarInitNode->channel_interleaver_pattern,
newPolarInitNode->i_bil,
newPolarInitNode->encoderLength);
free(J);
build_decoder_tree(newPolarInitNode);
build_polar_tables(newPolarInitNode);
init_polar_deinterleaver_table(newPolarInitNode);
//printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
} else {
AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_paramsPtr could not be created");
}
currentPtr = *polarParams;
//If polarParams is empty:
if (currentPtr == NULL)
{
*polarParams = newPolarInitNode;
//printf("Creating first polarParams entry index %d, %p\n",newPolarInitNode->idx,*polarParams);
return;
}
//Else, add node to the end of the linked list.
while (currentPtr->nextPtr != NULL) {
currentPtr = currentPtr->nextPtr;
}
currentPtr->nextPtr= newPolarInitNode;
printf("Adding new polarParams entry to list index %d,%p\n", newPolarInitNode->idx, currentPtr->nextPtr);
return;
//Fixme: the list is not thread safe
//The defect is not critical: we always append (never delete items) and adding two times the same is fine
newPolarInitNode->nextPtr=*polarParams;
*polarParams=newPolarInitNode;
return;
}
void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams)
{
uint8_t i = 0;
if (polarParams == NULL) {
printf("polarParams is empty.\n");
} else {
while (polarParams != NULL){
printf("polarParams[%d] = %d\n", i, polarParams->idx);
polarParams = polarParams->nextPtr;
i++;
}
}
return;
void nr_polar_print_polarParams(t_nrPolar_params *polarParams) {
uint8_t i = 0;
if (polarParams == NULL) {
printf("polarParams is empty.\n");
} else {
while (polarParams != NULL) {
printf("polarParams[%d] = %d\n", i, polarParams->idx);
polarParams = polarParams->nextPtr;
i++;
}
}
return;
}
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level)
{
t_nrPolar_paramsPtr currentPtr = NULL;
t_nrPolar_params *nr_polar_params ( int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level) {
static t_nrPolar_params *polarList = NULL;
nr_polar_init(&polarList, messageType,messageLength,aggregation_level);
t_nrPolar_params *polarParams=polarList;
const int tag=messageType * messageLength * nr_polar_aggregation_prime(aggregation_level);
while (polarParams != NULL) {
if (polarParams->idx ==
(messageType * messageLength * (nr_polar_aggregation_prime(aggregation_level)) )) {
currentPtr = polarParams;
break;
} else {
polarParams = polarParams->nextPtr;
}
}
return currentPtr;
while (polarParams != NULL) {
if (polarParams->idx == tag)
return polarParams;
polarParams = polarParams->nextPtr;
}
AssertFatal(false,"Polar Init tables internal failure\n");
return NULL;
}
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level)
{
if (aggregation_level == 0) return 0;
else if (aggregation_level == 1) return NR_POLAR_AGGREGATION_LEVEL_1_PRIME;
else if (aggregation_level == 2) return NR_POLAR_AGGREGATION_LEVEL_2_PRIME;
else if (aggregation_level == 4) return NR_POLAR_AGGREGATION_LEVEL_4_PRIME;
else if (aggregation_level == 8) return NR_POLAR_AGGREGATION_LEVEL_8_PRIME;
else return NR_POLAR_AGGREGATION_LEVEL_16_PRIME; //aggregation_level == 16
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level) {
if (aggregation_level == 0) return 0;
else if (aggregation_level == 1) return NR_POLAR_AGGREGATION_LEVEL_1_PRIME;
else if (aggregation_level == 2) return NR_POLAR_AGGREGATION_LEVEL_2_PRIME;
else if (aggregation_level == 4) return NR_POLAR_AGGREGATION_LEVEL_4_PRIME;
else if (aggregation_level == 8) return NR_POLAR_AGGREGATION_LEVEL_8_PRIME;
else return NR_POLAR_AGGREGATION_LEVEL_16_PRIME; //aggregation_level == 16
}
+2
View File
@@ -183,6 +183,7 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
#endif
}
if (rvidx !=0){
while(k<E) {
for (ind=0; (ind<Ncb)&&(k<E); ind++) {
if (soft_input[ind] != NR_NULL) {
@@ -201,6 +202,7 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
#endif
}
}
}
return 0;
}
+9 -9
View File
@@ -34,7 +34,7 @@ int32_t nr_segmentation(unsigned char *input_buffer,
unsigned int B,
unsigned int *C,
unsigned int *K,
unsigned int *Zout,
unsigned int *Zout, // [hna] Zout is Zc
unsigned int *F)
{
@@ -126,7 +126,7 @@ else
} else {
//msg("nr_segmentation.c: Illegal codeword size !!!\n");
return(-1);
return -1;
}
*Zout = *K;
*K = *K*Kb;
@@ -140,10 +140,11 @@ else
if ((input_buffer) && (output_buffers)) {
s=0;
s = 0;
for (r=0; r<*C; r++) {
k = 0;
Kprime = Bprime_by_C;
while (k<((Kprime - L)>>3)) {
@@ -153,10 +154,11 @@ else
s++;
}
if (*F>0)
for (k=Kprime>>3; k<(*K)>>3; k++) {
output_buffers[r][k] = NR_NULL;
if (*F>0) {
for (k=Kprime>>3; k<(*K)>>3; k++) {
output_buffers[r][k] = 0;
//printf("r %d filler bits [%d] = %d Kprime %d \n", r,k, output_buffers[r][k], Kprime);
}
}
if (*C > 1) { // add CRC
@@ -165,12 +167,10 @@ else
output_buffers[r][1+((Kprime-L)>>3)] = ((uint8_t*)&crc)[1];
output_buffers[r][2+((Kprime-L)>>3)] = ((uint8_t*)&crc)[0];
}
k=0;
}
}
return(0);
return 0;
}
+160 -195
View File
@@ -33,7 +33,8 @@
#include "assertions.h"
#include <math.h>
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h"
@@ -41,104 +42,87 @@ extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
extern int32_t get_uldl_offset(int nr_bandP);
int l1_north_init_gNB() {
int i,j;
if (RC.nb_nr_L1_inst > 0 && RC.nb_nr_L1_CC != NULL && RC.gNB != NULL)
{
if (RC.nb_nr_L1_inst > 0 && RC.nb_nr_L1_CC != NULL && RC.gNB != NULL) {
AssertFatal(RC.nb_nr_L1_inst>0,"nb_nr_L1_inst=%d\n",RC.nb_nr_L1_inst);
AssertFatal(RC.nb_nr_L1_CC!=NULL,"nb_nr_L1_CC is null\n");
AssertFatal(RC.gNB!=NULL,"RC.gNB is null\n");
LOG_I(PHY,"%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
for (i=0;i<RC.nb_nr_L1_inst;i++) {
for (i=0; i<RC.nb_nr_L1_inst; i++) {
AssertFatal(RC.gNB[i]!=NULL,"RC.gNB[%d] is null\n",i);
AssertFatal(RC.nb_nr_L1_CC[i]>0,"RC.nb_nr_L1_CC[%d]=%d\n",i,RC.nb_nr_L1_CC[i]);
LOG_I(PHY,"%s() RC.nb_nr_L1_CC[%d]:%d\n", __FUNCTION__, i, RC.nb_nr_L1_CC[i]);
for (j=0;j<RC.nb_nr_L1_CC[i];j++) {
for (j=0; j<RC.nb_nr_L1_CC[i]; j++) {
AssertFatal(RC.gNB[i][j]!=NULL,"RC.gNB[%d][%d] is null\n",i,j);
if ((RC.gNB[i][j]->if_inst = NR_IF_Module_init(i))<0) return(-1);
if ((RC.gNB[i][j]->if_inst = NR_IF_Module_init(i))<0) return(-1);
LOG_I(PHY,"%s() RC.gNB[%d][%d] installing callbacks\n", __FUNCTION__, i, j);
RC.gNB[i][j]->if_inst->NR_PHY_config_req = nr_phy_config_request;
RC.gNB[i][j]->if_inst->NR_Schedule_response = nr_schedule_response;
}
}
}
else
{
} else {
LOG_I(PHY,"%s() Not installing PHY callbacks - RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC:%p RC.gNB:%p\n", __FUNCTION__, RC.nb_nr_L1_inst, RC.nb_nr_L1_CC, RC.gNB);
}
return(0);
}
int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
unsigned char is_secondary_gNB,
unsigned char abstraction_flag)
{
unsigned char is_secondary_gNB,
unsigned char abstraction_flag) {
// shortcuts
NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
nfapi_nr_config_request_t* cfg = &gNB->gNB_config;
NR_gNB_COMMON* const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH** const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS* const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH* const prach_vars = &gNB->prach_vars;
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;
int i, UE_id;
int i, UE_id;
LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__);
gNB->total_dlsch_bitrate = 0;
gNB->total_transmitted_bits = 0;
gNB->total_system_throughput = 0;
gNB->check_for_MUMIMO_transmissions=0;
while(gNB->configured == 0) usleep(10000);
init_dfts();
/*
LOG_I(PHY,"[gNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n",
gNB->Mod_id,
fp->N_RB_DL,fp->phich_config_common.phich_resource,
fp->phich_config_common.phich_duration,
fp->nb_antennas_tx, fp->nb_antennas_rx,
fp->prach_config_common.rootSequenceIndex,
fp->prach_config_common.prach_Config_enabled,
fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
fp->prach_config_common.prach_ConfigInfo.highSpeedFlag,
fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset
);*/
/*
LOG_I(PHY,"[gNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n",
gNB->Mod_id,
fp->N_RB_DL,fp->phich_config_common.phich_resource,
fp->phich_config_common.phich_duration,
fp->nb_antennas_tx, fp->nb_antennas_rx,
fp->prach_config_common.rootSequenceIndex,
fp->prach_config_common.prach_Config_enabled,
fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
fp->prach_config_common.prach_ConfigInfo.highSpeedFlag,
fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset
);*/
LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id);
crcTableInit();
init_dfts();
// PBCH DMRS gold sequences generation
nr_init_pbch_dmrs(gNB);
// Polar encoder init for PBCH
nr_polar_init(&gNB->nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE,
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL);
//PDCCH DMRS init
gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t**));
gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
for (int slot=0; slot<fp->slots_per_frame; slot++) {
pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t*));
pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot);
for (int symb=0; symb<fp->symbols_per_slot; symb++){
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
pdcch_dmrs[slot][symb] = (uint32_t *)malloc16(NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
}
@@ -146,127 +130,117 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
//PDSCH DMRS init
gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
//PDSCH DMRS init
gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t***));
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
for (int slot=0; slot<fp->slots_per_frame; slot++) {
pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t**));
for (int slot=0; slot<fp->slots_per_frame; slot++) {
pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
for (int symb=0; symb<fp->symbols_per_slot; symb++){
pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_MAX_NB_CODEWORDS*sizeof(uint32_t*));
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_MAX_NB_CODEWORDS*sizeof(uint32_t *));
AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++) {
pdsch_dmrs[slot][symb][q] = (uint32_t*)malloc16(NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
pdsch_dmrs[slot][symb][q] = (uint32_t *)malloc16(NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d codeword %d - malloc failed\n", slot, symb, q);
}
}
}
nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
/// Transport init necessary for NR synchro
init_nr_transport(gNB);
/*
lte_gold(fp,gNB->lte_gold_table,fp->Nid_cell);
generate_pcfich_reg_mapping(fp);
generate_phich_reg_mapping(fp);*/
/*
lte_gold(fp,gNB->lte_gold_table,fp->Nid_cell);
generate_pcfich_reg_mapping(fp);
generate_phich_reg_mapping(fp);*/
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
gNB->first_run_timing_advance[UE_id] =
1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
// clear whole structure
bzero( &gNB->UE_stats[UE_id], sizeof(LTE_eNB_UE_stats) );
gNB->physicalConfigDedicated[UE_id] = NULL;
}
gNB->first_run_I0_measurements = 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
gNB->first_run_I0_measurements =
1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
common_vars->rxdata = (int32_t **)NULL;
common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*));
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*));
for (i=0;i<15;i++){
common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) );
for (i=0;i<15;i++){
common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) ); // [hna] samples_per_frame without CP
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
i,common_vars->txdataF[i],
fp->samples_per_frame_wCP*sizeof(int32_t));
i,common_vars->txdataF[i],
fp->samples_per_frame_wCP*sizeof(int32_t));
}
// Channel estimates for SRS
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
srs_vars[UE_id].srs_ch_estimates = (int32_t**)malloc16( 64*sizeof(int32_t*) );
srs_vars[UE_id].srs_ch_estimates_time = (int32_t**)malloc16( 64*sizeof(int32_t*) );
srs_vars[UE_id].srs_ch_estimates = (int32_t **)malloc16( 64*sizeof(int32_t *) );
srs_vars[UE_id].srs_ch_estimates_time = (int32_t **)malloc16( 64*sizeof(int32_t *) );
for (i=0; i<64; i++) {
srs_vars[UE_id].srs_ch_estimates[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size );
srs_vars[UE_id].srs_ch_estimates_time[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
srs_vars[UE_id].srs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size );
srs_vars[UE_id].srs_ch_estimates_time[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
}
} //UE_id
/*generate_ul_ref_sigs_rx();
init_ulsch_power_LUT();*/
// SRS
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
srs_vars[UE_id].srs = (int32_t*)malloc16_clear(2*fp->ofdm_symbol_size*sizeof(int32_t));
srs_vars[UE_id].srs = (int32_t *)malloc16_clear(2*fp->ofdm_symbol_size*sizeof(int32_t));
}
// PRACH
prach_vars->prachF = (int16_t*)malloc16_clear( 1024*2*sizeof(int16_t) );
prach_vars->prachF = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) );
// assume maximum of 64 RX antennas for PRACH receiver
prach_vars->prach_ifft[0] = (int32_t**)malloc16_clear(64*sizeof(int32_t*));
for (i=0;i<64;i++) prach_vars->prach_ifft[0][i] = (int32_t*)malloc16_clear(1024*2*sizeof(int32_t));
prach_vars->prach_ifft[0] = (int32_t **)malloc16_clear(64*sizeof(int32_t *));
prach_vars->rxsigF[0] = (int16_t**)malloc16_clear(64*sizeof(int16_t*));
for (i=0; i<64; i++) prach_vars->prach_ifft[0][i] = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
prach_vars->rxsigF[0] = (int16_t **)malloc16_clear(64*sizeof(int16_t *));
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
//FIXME
pusch_vars[UE_id] = (LTE_eNB_PUSCH*)malloc16_clear( NUMBER_OF_UE_MAX*sizeof(LTE_eNB_PUSCH) );
pusch_vars[UE_id]->rxdataF_ext = (int32_t**)malloc16( 2*sizeof(int32_t*) );
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t**)malloc16( 2*sizeof(int32_t*) );
pusch_vars[UE_id]->drs_ch_estimates = (int32_t**)malloc16( 2*sizeof(int32_t*) );
pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t**)malloc16( 2*sizeof(int32_t*) );
pusch_vars[UE_id]->rxdataF_comp = (int32_t**)malloc16( 2*sizeof(int32_t*) );
pusch_vars[UE_id]->ul_ch_mag = (int32_t**)malloc16( 2*sizeof(int32_t*) );
pusch_vars[UE_id]->ul_ch_magb = (int32_t**)malloc16( 2*sizeof(int32_t*) );
pusch_vars[UE_id] = (LTE_eNB_PUSCH *)malloc16_clear( NUMBER_OF_UE_MAX*sizeof(LTE_eNB_PUSCH) );
pusch_vars[UE_id]->rxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->drs_ch_estimates = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( 2*sizeof(int32_t *) );
for (i=0; i<2; i++) {
// RK 2 times because of output format of FFT!
// FIXME We should get rid of this
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t*)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
}
pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
}
pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
} //UE_id
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
gNB->UE_stats_ptr[UE_id] = &gNB->UE_stats[UE_id];
gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
return (0);
}
/*
void phy_config_request(PHY_Config_t *phy_config) {
@@ -277,7 +251,7 @@ void phy_config_request(PHY_Config_t *phy_config) {
NR_DL_FRAME_PARMS *fp;
PHICH_RESOURCE_t phich_resource_table[4]={oneSixth,half,one,two};
int eutra_band = cfg->nfapi_config.rf_bands.rf_band[0];
int eutra_band = cfg->nfapi_config.rf_bands.rf_band[0];
int dl_Bandwidth = cfg->rf_config.dl_carrier_bandwidth.value;
int ul_Bandwidth = cfg->rf_config.ul_carrier_bandwidth.value;
int Nid_cell = cfg->sch_config.physical_cell_id.value;
@@ -286,7 +260,7 @@ void phy_config_request(PHY_Config_t *phy_config) {
uint32_t dl_CarrierFreq = cfg->nfapi_config.earfcn.value;
LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,gNB_tx_antenna_ports %d,Ncp %d,DL freq %u)\n",
Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq );
Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq );
AssertFatal(RC.gNB != NULL, "PHY instance pointer doesn't exist\n");
AssertFatal(RC.gNB[Mod_id] != NULL, "PHY instance %d doesn't exist\n",Mod_id);
@@ -312,25 +286,23 @@ void phy_config_request(PHY_Config_t *phy_config) {
}*/
void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
{
void phy_free_nr_gNB(PHY_VARS_gNB *gNB) {
//NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
//nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_gNB_COMMON* const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH** const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS* const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH* const prach_vars = &gNB->prach_vars;
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
int i, UE_id;
for (i = 0; i < 15; i++) {
free_and_zero(common_vars->txdataF[i]);
/* rxdataF[i] is not allocated -> don't free */
/* rxdataF[i] is not allocated -> don't free */
}
free_and_zero(common_vars->txdataF);
free_and_zero(common_vars->rxdataF);
// PDCCH DMRS sequences
free_and_zero(pdcch_dmrs);
@@ -340,6 +312,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(srs_vars[UE_id].srs_ch_estimates[i]);
free_and_zero(srs_vars[UE_id].srs_ch_estimates_time[i]);
}
free_and_zero(srs_vars[UE_id].srs_ch_estimates);
free_and_zero(srs_vars[UE_id].srs_ch_estimates_time);
} //UE_id
@@ -351,8 +324,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(prach_vars->prachF);
for (i = 0; i < 64; i++) free_and_zero(prach_vars->prach_ifft[0][i]);
free_and_zero(prach_vars->prach_ifft[0]);
free_and_zero(prach_vars->prach_ifft[0]);
free_and_zero(prach_vars->rxsigF[0]);
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
@@ -365,6 +338,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]);
free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]);
}
free_and_zero(pusch_vars[UE_id]->rxdataF_ext);
free_and_zero(pusch_vars[UE_id]->rxdataF_ext2);
free_and_zero(pusch_vars[UE_id]->drs_ch_estimates);
@@ -387,11 +361,11 @@ void install_schedule_handlers(IF_Module_t *if_inst)
/// this function is a temporary addition for NR configuration
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell)
{
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell,uint64_t position_in_burst) {
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config;
//overwrite for new NR parameters
gNB_config->nfapi_config.rf_bands.rf_band[0] = 78;
gNB_config->nfapi_config.nrarfcn.value = 620000;
@@ -404,31 +378,25 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,
gNB_config->sch_config.n_ssb_crb.value = (N_RB_DL-20);
gNB_config->sch_config.ssb_subcarrier_offset.value = 0;
gNB_config->sch_config.physical_cell_id.value=Nid_cell;
gNB_config->sch_config.ssb_scg_position_in_burst.value=position_in_burst;
gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED;
gNB->mac_enabled = 1;
fp->dl_CarrierFreq = from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
fp->threequarter_fs = 0;
nr_init_frame_parms(gNB_config, fp);
gNB->configured = 1;
LOG_I(PHY,"gNB configured\n");
}
void nr_phy_config_request(NR_PHY_Config_t *phy_config)
{
void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
uint8_t Mod_id = phy_config->Mod_id;
int CC_id = phy_config->CC_id;
NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id][CC_id]->frame_parms;
nfapi_nr_config_request_t *gNB_config = &RC.gNB[Mod_id][CC_id]->gNB_config;
gNB_config->nfapi_config.rf_bands.rf_band[0] = phy_config->cfg->nfapi_config.rf_bands.rf_band[0]; //22
gNB_config->nfapi_config.nrarfcn.value = phy_config->cfg->nfapi_config.nrarfcn.value; //6600
gNB_config->subframe_config.numerology_index_mu.value = phy_config->cfg->subframe_config.numerology_index_mu.value;//1
@@ -438,105 +406,102 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config)
gNB_config->sch_config.ssb_subcarrier_offset.value = phy_config->cfg->sch_config.ssb_subcarrier_offset.value;//0;
gNB_config->sch_config.n_ssb_crb.value = (phy_config->cfg->rf_config.dl_carrier_bandwidth.value-20);
gNB_config->sch_config.physical_cell_id.value = phy_config->cfg->sch_config.physical_cell_id.value;
gNB_config->sch_config.ssb_scg_position_in_burst.value= phy_config->cfg->sch_config.ssb_scg_position_in_burst.value;
if (phy_config->cfg->subframe_config.duplex_mode.value == 0) {
gNB_config->subframe_config.duplex_mode.value = TDD;
}
else {
} else {
gNB_config->subframe_config.duplex_mode.value = FDD;
}
RC.gNB[Mod_id][CC_id]->mac_enabled = 1;
fp->dl_CarrierFreq = from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
fp->threequarter_fs = 0;
LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,DL freq %u)\n",
Mod_id,
CC_id,
gNB_config->nfapi_config.rf_bands.rf_band[0],
gNB_config->rf_config.dl_carrier_bandwidth.value,
gNB_config->rf_config.ul_carrier_bandwidth.value,
gNB_config->sch_config.physical_cell_id.value,
fp->dl_CarrierFreq );
Mod_id,
CC_id,
gNB_config->nfapi_config.rf_bands.rf_band[0],
gNB_config->rf_config.dl_carrier_bandwidth.value,
gNB_config->rf_config.ul_carrier_bandwidth.value,
gNB_config->sch_config.physical_cell_id.value,
fp->dl_CarrierFreq );
nr_init_frame_parms(gNB_config, fp);
if (RC.gNB[Mod_id][CC_id]->configured == 1){
if (RC.gNB[Mod_id][CC_id]->configured == 1) {
LOG_E(PHY,"Already gNB already configured, do nothing\n");
return;
}
RC.gNB[Mod_id][CC_id]->configured = 1;
LOG_I(PHY,"gNB %d/%d configured\n",Mod_id,CC_id);
}
void init_nr_transport(PHY_VARS_gNB *gNB) {
int i;
int j;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
LOG_I(PHY, "Initialise nr transport\n");
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
for (j=0; j<2; j++) {
gNB->dlsch[i][j] = new_gNB_dlsch(1,16,NSOFT,0,fp,cfg);
if (!gNB->dlsch[i][j]) {
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
exit(-1);
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
exit(-1);
}/* else {
gNB->dlsch[i][j]->rnti=0;
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti);
gNB->dlsch[i][j]->rnti=0;
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti);
}*/
///////////////////////// Initializing gNB ULSCH /////////////////////////
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
// ULSCH for RA
if(i==0) {
gNB->ulsch[i][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0);
if (!gNB->ulsch[i][j]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}
}
// ULSCH for data
gNB->ulsch[i+1][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0);
if (!gNB->ulsch[i+1][j]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}
//////////////////////////////////////////////////////////////////////////
}
//LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
//gNB->ulsch[1+i] = new_gNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
/*if (!gNB->ulsch[1+i]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}*/
// this is the transmission mode for the signalling channels
// this will be overwritten with the real transmission mode by the RRC once the UE is connected
//gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2;
}
// ULSCH for RA
//gNB->ulsch[0] = new_gNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0);
/*if (!gNB->ulsch[0]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}*/
gNB->dlsch_SI = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
LOG_D(PHY,"gNB %d.%d : SI %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_SI);
gNB->dlsch_ra = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
LOG_D(PHY,"gNB %d.%d : RA %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_ra);
gNB->dlsch_MCH = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
LOG_D(PHY,"gNB %d.%d : MCH %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_MCH);
gNB->rx_total_gain_dB=130;
for(i=0; i<NUMBER_OF_UE_MAX; i++)
gNB->mu_mimo_mode[i].dl_pow_off = 2;
gNB->check_for_total_transmissions = 0;
gNB->check_for_MUMIMO_transmissions = 0;
gNB->FULL_MUMIMO_transmissions = 0;
gNB->check_for_SUMIMO_transmissions = 0;
//fp->pucch_config_common.deltaPUCCH_Shift = 1;
}
+12 -7
View File
@@ -361,8 +361,13 @@ void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,
uint16_t max_harq_tx )
{
int num_of_threads,num_of_code_words;
PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
phy_vars_ue->ulsch[eNB_id]->Mlimit = max_harq_tx;
for (num_of_threads=0;num_of_threads<RX_NB_TH_MAX;num_of_threads++)
for (num_of_code_words=0;num_of_code_words<NR_MAX_NB_CODEWORDS;num_of_code_words++)
phy_vars_ue->ulsch[eNB_id][num_of_threads][num_of_code_words]->Mlimit = max_harq_tx;
}
extern uint16_t beta_cqi[16];
@@ -670,7 +675,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
// many memory allocation sizes are hard coded
AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[eNB_id]" );
AssertFatal( ue->n_connected_eNB <= NUMBER_OF_CONNECTED_eNB_MAX, "n_connected_eNB is too large" );
AssertFatal( nb_connected_eNB <= NUMBER_OF_CONNECTED_eNB_MAX, "n_connected_eNB is too large" );
// init phy_vars_ue
for (i=0; i<4; i++) {
@@ -919,15 +924,15 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) {
for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
for (j=0; j<2; j++) {
for (k=0; k<2; k++) {
AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n");
for (k=0; k<RX_NB_TH_MAX; k++) {
AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n");
LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]);
LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[i][j]);
AssertFatal((ue->ulsch[k][i][j] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NUMBER_OF_HARQ_PID_MAX, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n");
LOG_D(PHY,"ulsch[%d][%d][%d] => %p\n",k,i,j,ue->ulsch[k][i][j]);
}
}
//AssertFatal((ue->ulsch[i] = new_ue_ulsch(ue->frame_parms.N_RB_UL, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n");
ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
+86 -2
View File
@@ -27,6 +27,59 @@ uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3,
uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 16, 32};
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index)
{
int mu = fp->numerology_index;
int symbol = 0;
uint8_t n, n_temp;
nr_ssb_type_e type = fp->ssb_type;
int case_AC[2] = {2,8};
int case_BD[4] = {4,8,16,20};
int case_E[8] = {8, 12, 16, 20, 32, 36, 40, 44};
switch(mu) {
case NR_MU_0: // case A
n = i_ssb >> 1;
symbol = case_AC[i_ssb % 2] + 14*n;
break;
case NR_MU_1:
if (type == 1){ // case B
n = i_ssb >> 2;
symbol = case_BD[i_ssb % 4] + 28*n;
}
if (type == 2){ // case C
n = i_ssb >> 1;
symbol = case_AC[i_ssb % 2] + 14*n;
}
break;
case NR_MU_3: // case D
n_temp = i_ssb >> 2;
n = n_temp + (n_temp >> 2);
symbol = case_BD[i_ssb % 4] + 28*n;
break;
case NR_MU_4: // case E
n_temp = i_ssb >> 3;
n = n_temp + (n_temp >> 2);
symbol = case_E[i_ssb % 8] + 56*n;
break;
default:
AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
}
if (half_frame_index)
symbol += (5 * fp->symbols_per_slot * fp->slots_per_subframe);
return symbol;
}
int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
int mu,
int Ncp,
@@ -46,18 +99,29 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
fp->numerology_index = mu;
fp->Ncp = Ncp;
fp->N_RB_DL = N_RB_DL;
switch(mu) {
case NR_MU_0: //15kHz scs
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0];
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_0];
fp->ssb_type = nr_ssb_type_A;
break;
case NR_MU_1: //30kHz scs
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1];
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_1];
// selection of SS block pattern according to TS 38101-1 Table 5.4.3.3-1 for SCS 30kHz
if (fp->eutra_band == 5 || fp->eutra_band == 66)
fp->ssb_type = nr_ssb_type_B;
else{
if (fp->eutra_band == 41 || ( fp->eutra_band > 76 && fp->eutra_band < 80) )
fp->ssb_type = nr_ssb_type_C;
else
AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->eutra_band, mu);
}
switch(N_RB_DL){
case 11:
case 24:
@@ -144,11 +208,13 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
case NR_MU_3:
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
fp->ssb_type = nr_ssb_type_D;
break;
case NR_MU_4:
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4];
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_4];
fp->ssb_type = nr_ssb_type_E;
break;
default:
@@ -156,6 +222,9 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
}
fp->slots_per_frame = 10* fp->slots_per_subframe;
fp->nb_antenna_ports_eNB = 1; // default value until overwritten by RRCConnectionReconfiguration
fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
@@ -166,6 +235,16 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
fp->samples_per_frame = 10 * fp->samples_per_subframe;
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
// definition of Lmax according to ts 38.213 section 4.1
if (fp->dl_CarrierFreq < 6e9){
if(fp->frame_type && (fp->ssb_type==2))
fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8;
else
fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8;
}
else
fp->Lmax = 64;
// Initial bandwidth part configuration -- full carrier bandwidth
fp->initial_bwp_dl.bwp_id = 0;
fp->initial_bwp_dl.scs = fp->subcarrier_spacing;
@@ -181,7 +260,9 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
NR_DL_FRAME_PARMS *fp)
{
fp->eutra_band = config->nfapi_config.rf_bands.rf_band[0];
fp->frame_type = !(config->subframe_config.duplex_mode.value);
fp->L_ssb = config->sch_config.ssb_scg_position_in_burst.value;
return nr_init_frame_parms0(fp,
config->subframe_config.numerology_index_mu.value,
config->subframe_config.dl_cyclic_prefix_type.value,
@@ -219,3 +300,6 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
LOG_I(PHY,"fp->initial_bwp_dl.location=%d\n",fp->initial_bwp_dl.location);
LOG_I(PHY,"fp->initial_bwp_dl.ofdm_symbol_size=%d\n",fp->initial_bwp_dl.ofdm_symbol_size);
}
+3 -1
View File
@@ -376,6 +376,7 @@ void phy_config_request(PHY_Config_t *phy_config);
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index);
int nr_init_frame_parms(nfapi_nr_config_request_t* config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,int mu,int Ncp,int N_RB_DL,int n_ssb_crb,int ssb_subcarrier_offset);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
@@ -383,13 +384,14 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag);
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char abstraction_flag);
void nr_phy_config_request(NR_PHY_Config_t *gNB);
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell);
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell,uint64_t position_in_burst);
void phy_free_nr_gNB(PHY_VARS_gNB *gNB);
int l1_north_init_gNB(void);
void init_nr_transport(PHY_VARS_gNB *gNB);
void init_dfts(void);
/** @} */
#endif
+1 -2
View File
@@ -53,8 +53,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue,
unsigned char Ns,
int sample_offset,
int no_prefix,
int reset_freq_est,
NR_CHANNEL_EST_t channel);
NR_CHANNEL_EST_t channel);
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
unsigned char l,
+34 -61
View File
@@ -39,28 +39,40 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
unsigned char Ns,
int sample_offset,
int no_prefix,
int reset_freq_est,
NR_CHANNEL_EST_t channel)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_COMMON *common_vars = &ue->common_vars;
uint8_t eNB_id = 0;//ue_common_vars->eNb_id;
unsigned char aa;
unsigned char symbol = l;//+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
if (ue->is_synchronized) {
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
}
else {
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
}
//unsigned int subframe_offset;//,subframe_offset_F;
unsigned int slot_offset;
//int i;
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
unsigned int rx_offset;
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[Ns>>1]][0];
uint16_t coreset_start_subcarrier = frame_parms->first_carrier_offset+((int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_vars->coreset[0].rb_offset)*NR_NB_SC_PER_RB;
uint16_t nb_rb_coreset = 24;
uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset+516;
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[Ns]][0];
uint16_t coreset_start_subcarrier = frame_parms->first_carrier_offset;//+((int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_vars->coreset[0].rb_offset)*NR_NB_SC_PER_RB;
uint16_t nb_rb_coreset = 0;
uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset;//+516;
uint16_t nb_rb_pdsch = 50;
uint8_t p=0;
uint8_t l0 = 2;
uint8_t l0 = pdcch_vars->coreset[0].duration;
uint64_t coreset_freq_dom = pdcch_vars->coreset[0].frequencyDomainResources;
for (int i = 0; i < 45; i++) {
if (((coreset_freq_dom & 0x1FFFFFFFFFFF) >> i) & 0x1) nb_rb_coreset++;
}
nb_rb_coreset = 6 * nb_rb_coreset;
//printf("corset duration %d nb_rb_coreset %d\n", l0, nb_rb_coreset);
void (*dft)(int16_t *,int16_t *, int);
int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
@@ -104,9 +116,9 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
}
if (no_prefix) {
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot*frame_parms->slots_per_subframe) * (Ns>>1);
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
} else {
slot_offset = (frame_parms->samples_per_subframe) * (Ns>>1);
slot_offset = (frame_parms->samples_per_slot) * (Ns);
}
/*if (l<0 || l>=7-frame_parms->Ncp) {
@@ -122,7 +134,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
rx_offset = sample_offset + slot_offset + nb_prefix_samples0 - SOFFSET;
// Align with 256 bit
@@ -130,8 +142,8 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
#ifdef DEBUG_FEP
// if (ue->frame <100)
/*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol,
nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples);
/*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx,Ns, symbol,
nb_prefix_samples,nb_prefix_samples0,slot_offset,sample_offset,rx_offset,frame_length_samples);
#endif
if (l==0) {
@@ -146,14 +158,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
(void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples],
frame_parms->ofdm_symbol_size*sizeof(int));
dft((int16_t *)tmp_dft_in,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
#if UE_TIMING_TRACE
start_meas(&ue->rx_dft_stats);
#endif
dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
#endif
@@ -175,11 +187,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
(void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
frame_parms->ofdm_symbol_size*sizeof(int));
dft((int16_t *)tmp_dft_in,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
}
#if UE_TIMING_TRACE
stop_meas(&ue->rx_dft_stats);
@@ -198,56 +210,17 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
switch(channel){
case NR_PBCH_EST:
#ifdef DEBUG_FEP
printf("Channel estimation eNB %d, slot %d, symbol %d\n",eNB_id,Ns,l);
#endif
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats);
#endif
nr_pbch_channel_estimation(ue,eNB_id,0,
Ns,
l,
symbol);
//}
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats);
#endif
// do frequency offset estimation here!
// use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1})
#ifdef DEBUG_FEP
printf("Frequency offset estimation\n");
#endif
if (l==(4-frame_parms->Ncp)) {
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_freq_offset_estimation_stats);
#endif
/*lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[0],
frame_parms,
l,
&common_vars->freq_offset,
reset_freq_est);*/
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_freq_offset_estimation_stats);
#endif
}
break;
case NR_PDCCH_EST:
#ifdef DEBUG_FEP
printf("PDCCH Channel estimation eNB %d, aatx %d, slot %d, symbol %d start_sc %d\n",eNB_id,aa,Ns,l,coreset_start_subcarrier);
printf("PDCCH Channel estimation aatx %d, slot %d, symbol %d start_sc %d\n",aa,Ns,l,coreset_start_subcarrier);
#endif
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats);
#endif
nr_pdcch_channel_estimation(ue,eNB_id,0,
nr_pdcch_channel_estimation(ue,0,
Ns,
l,
symbol,
@@ -261,7 +234,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
case NR_PDSCH_EST:
#ifdef DEBUG_FEP
printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l);
printf("Channel estimation aatx %d, slot %d, symbol %d\n",aa,Ns,l);
#endif
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats);
@@ -270,7 +243,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
ue->frame_parms.nushift = (p>>1)&1;;
if (symbol ==l0)
nr_pdsch_channel_estimation(ue,eNB_id,0,
nr_pdsch_channel_estimation(ue,0,
Ns,
p,
l,
+1
View File
@@ -32,6 +32,7 @@
//#define NR_PBCH_DMRS_LENGTH_DWORD 5
//#define NR_PBCH_DMRS_LENGTH 144
//#define DEBUG_PDCCH
#include "refsig_defs_ue.h"
#include "PHY/defs_nr_UE.h"
+2 -2
View File
@@ -32,13 +32,13 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB)
Nid = cfg->sch_config.physical_cell_id.value;
Lmax = (fp->dl_CarrierFreq < 3e9)? 4:8;
Lmax = fp->Lmax;
N_hf = (Lmax == 4)? 2:1;
for (n_hf = 0; n_hf < N_hf; n_hf++) {
for (l = 0; l < Lmax ; l++) {
i_ssb = l & (Lmax-1);
i_ssb2 = (i_ssb<<2) + n_hf;
i_ssb2 = i_ssb + (n_hf<<2);
reset = 1;
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
+2 -3
View File
@@ -29,15 +29,14 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue)
unsigned char Lmax, l, n_hf, N_hf;
Nid = ue->frame_parms.Nid_cell;
Lmax = 8; //(fp->dl_CarrierFreq < 3e9)? 4:8;
Lmax = ue->frame_parms.Lmax;
N_hf = (Lmax == 4)? 2:1;
for (n_hf = 0; n_hf < N_hf; n_hf++) {
for (l = 0; l < Lmax ; l++) {
i_ssb = l & (Lmax-1);
i_ssb2 = (i_ssb<<2) + n_hf;
i_ssb2 = i_ssb + (n_hf<<2);
x1 = 1 + (1<<31);
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
+3 -1
View File
@@ -137,7 +137,9 @@ int set_pss_nr(int ofdm_symbol_size);
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change);
int pss_search_time_nr(int **rxdata, ///rx data in time domain
NR_DL_FRAME_PARMS *frame_parms,
int *eNB_id);
int fo_flag,
int *eNB_id,
int *f_off);
#endif
#undef EXTERN
+176 -147
View File
@@ -20,7 +20,7 @@
*/
/*! \file PHY/NR_TRANSPORT/nr_dci.c
* \brief Implements DCI encoding and PDCCH TX procedures (38.212/38.213/38.214). V15.2.0 2018-06.
* \brief Implements DCI encoding and PDCCH TX procedures (38.212/38.213/38.214). V15.4.0 2019-01.
* \author Guy De Souza
* \date 2018
* \version 0.1
@@ -35,20 +35,18 @@
//#define DEBUG_PDCCH_DMRS
//#define DEBUG_DCI
//#define DEBUG_CHANNEL_CODING
#define PDCCH_TEST_POLAR_TEMP_FIX
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type,
uint16_t N_RB,
nfapi_nr_config_request_t* config)
{
nfapi_nr_rnti_type_e rnti_type,
uint16_t N_RB,
nfapi_nr_config_request_t *config) {
uint16_t size = 0;
switch(format) {
/*Only sizes for 0_0 and 1_0 are correct at the moment*/
/*Only sizes for 0_0 and 1_0 are correct at the moment*/
case NFAPI_NR_UL_DCI_FORMAT_0_0:
/// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
size += 20;
@@ -83,7 +81,6 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
/// fixed: Format identifier 1, VRB2PRB 1, MCS 5, NDI 1, RV 2, HARQ PID 4, DAI 2, PUCCH TPC 2, PUCCH RInd 3, PDSCH to HARQ TInd 3 Time Domain assgnmt 4 -- 28
size += 28;
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment
break;
case NFAPI_NR_DL_DCI_FORMAT_1_1:
@@ -96,7 +93,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
// PRB bundling size indicator
// Rate matching indicator
// ZP CSI-RS trigger
/// TB1- MCS 5, NDI 1, RV 2
/// TB1- MCS 5, NDI 1, RV 2
size += 8;
// TB2
size += 4 ; // HARQ PID
@@ -110,7 +107,6 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
// CBGTI
// CBGFI
size += 1; // DMRS sequence init
break;
case NFAPI_NR_DL_DCI_FORMAT_2_0:
@@ -125,8 +121,8 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
case NFAPI_NR_DL_DCI_FORMAT_2_3:
break;
default:
AssertFatal(1==0, "Invalid NR DCI format %d\n", format);
default:
AssertFatal(1==0, "Invalid NR DCI format %d\n", format);
}
return size;
@@ -136,11 +132,9 @@ void nr_pdcch_scrambling(uint32_t *in,
uint16_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out) {
uint32_t *out) {
uint8_t reset;
uint32_t x1, x2, s=0;
reset = 1;
x2 = (n_RNTI<<16) + Nid;
@@ -148,193 +142,228 @@ void nr_pdcch_scrambling(uint32_t *in,
if ((i&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
if (i){
in++;
out++;
if (i) {
in++;
out++;
}
}
(*out) ^= ((((*in)>>(i&0x1f))&1) ^ ((s>>(i&0x1f))&1))<<(i&0x1f);
// printf("nr_pdcch_scrambling: in %d => out %d\n",((*in)>>(i&0x1f))&1,((*out)>>(i&0x1f))&1);
}
(*out) ^= ((((*in)>>(i&0x1f))&1) ^ ((s>>(i&0x1f))&1))<<(i&0x1f);
//printf("nr_pdcch_scrambling: in %d seq 0x%08x => out %d\n",((*in)>>(i&0x1f))&1,s,((*out)>>(i&0x1f))&1);
}
}
uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
t_nrPolar_paramsPtr *nrPolar_params,
uint32_t **gold_pdcch_dmrs,
int32_t* txdataF,
int32_t *txdataF,
int16_t amp,
NR_DL_FRAME_PARMS frame_parms,
nfapi_nr_config_request_t config)
{
nfapi_nr_config_request_t config) {
int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration
uint8_t idx=0;
//uint16_t a;
uint32_t dmrs_seq[NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD];
uint16_t dmrs_offset=0;
uint16_t cset_start_sc;
uint8_t cset_start_symb, cset_nsymb;
int k,l,k_prime,dci_idx, dmrs_idx;
nr_cce_t cce;
nr_reg_t reg;
nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE];
/*First iteration: single DCI*/
NR_gNB_DCI_ALLOC_t dci_alloc = pdcch_vars.dci_alloc[0];
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params;
uint16_t dmrs_length = dci_alloc.L*36; //2(QPSK)*3(per RB)*6(REG per CCE)
uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE)
/*The coreset is initialised
* in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset
* in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0
* or the rb_offset for other coresets
* in time: by its first slot and its first symbol*/
uint16_t cset_start_sc = frame_parms.first_carrier_offset + ((int)floor(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_params.rb_offset)*NR_NB_SC_PER_RB;
// uint8_t cset_start_symb = pdcch_params.first_slot*frame_parms.symbols_per_slot + pdcch_params.first_symbol;
uint8_t cset_start_symb = pdcch_params.first_symbol;
uint8_t cset_nsymb = pdcch_params.n_symb;
dci_idx = 0;
if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
cset_start_sc = frame_parms.first_carrier_offset + (frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB +
pdcch_params.rb_offset)*NR_NB_SC_PER_RB;
} else
cset_start_sc = frame_parms.first_carrier_offset + pdcch_params.rb_offset*NR_NB_SC_PER_RB;
cset_start_symb = pdcch_params.first_symbol;
cset_nsymb = pdcch_params.n_symb;
dci_idx = 0;
LOG_I(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb);
// DMRS length is per OFDM symbol
uint16_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)?
(pdcch_params.n_rb*6) : (dci_alloc.L*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE)
uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE)
LOG_I(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length);
/// DMRS QPSK modulation
/*There is a need to shift from which index the pregenerated DMRS sequence is used
* see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/
if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
gold_pdcch_dmrs += ((int)floor(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_params.rb_offset)*3/32;
/*There is a need to shift from which index the pregenerated DMRS sequence is used
* see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/
if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) {
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_params.n_symb; symb++)
gold_pdcch_dmrs[symb] += (pdcch_params.rb_offset*3)>>5;
dmrs_offset = (pdcch_params.rb_offset*3)&0x1f;
LOG_I(PHY, "PDCCH DMRS offset %d\n", dmrs_offset);
}
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_params.n_symb; symb++) {
for (int i=0; i<dmrs_length>>1; i++) {
idx = ((((gold_pdcch_dmrs[symb][(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((gold_pdcch_dmrs[symb][((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
mod_dmrs[symb][i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
mod_dmrs[symb][(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
#ifdef DEBUG_PDCCH_DMRS
printf("symb %d i %d idx %d gold seq %u b0-b1 %d-%d mod_dmrs %d %d\n", symb, i, idx, gold_pdcch_dmrs[symb][(i<<1)>>5],
(((gold_pdcch_dmrs[symb][(i<<1)>>5])>>((i<<1)&0x1f))&1), (((gold_pdcch_dmrs[symb][((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1),
mod_dmrs[symb][(i<<1)], mod_dmrs[symb][(i<<1)+1]);
#endif
}
if (dmrs_offset) {
// a non zero offset requires the DMRS sequence to be rearranged
memset(dmrs_seq,0, NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
for (int i=0; i<dmrs_length; i++) {
dmrs_seq[(i>>5)] |= ((gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]>>((i+dmrs_offset)&0x1f))&1)<<(i&0x1f);
#ifdef DEBUG_PDCCH_DMRS
//printf("out 0x%08x in 0x%08x \n", dmrs_seq[(i>>5)], gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]);
#endif
}
nr_modulation(dmrs_seq, dmrs_length, MOD_QPSK, mod_dmrs[symb]);
} else
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, MOD_QPSK, mod_dmrs[symb]);
#ifdef DEBUG_PDCCH_DMRS
for (int i=0; i<dmrs_length>>1; i++)
if (dmrs_offset)
printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, dmrs_seq[i>>5],
mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
else
printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
#endif
}
/// DCI payload processing
// CRC attachment + Scrambling + Channel coding + Rate matching
// CRC attachment + Scrambling + Channel coding + Rate matching
uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? ((pdcch_params.scrambling_id)?pdcch_params.rnti:0) : 0;
uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value;
//#ifdef PDCCH_TEST_POLAR_TEMP_FIX
// nr_polar_init(&currentPtr, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
// t_nrPolar_paramsPtr currentPtr = nr_polar_params(*nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
//#else
nr_polar_init(nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
t_nrPolar_paramsPtr currentPtr = nr_polar_params(*nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
//#endif
//polar_encoder_dci(dci_alloc.dci_pdu, encoder_output, currentPtr, pdcch_params.rnti);
uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.rnti:0;
uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)?
pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value;
t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti,currentPtr);
#ifdef DEBUG_CHANNEL_CODING
printf("polar rnti %d\n",pdcch_params.rnti);
for (int i=0;i<54;i++) printf("Encoded Payload: [%d]->0x%08x \n", i,encoder_output[i]);
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1]);
printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5);
printf("DCI PDU: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1], dci_alloc.dci_pdu[2], dci_alloc.dci_pdu[3]);
printf("Encoded Payload: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
encoder_output[0], encoder_output[1], encoder_output[2], encoder_output[3]);
for (int i=0; i<encoded_length>>5; i++)
printf("[%d]->0x%08x \t", i,encoder_output[i]);
printf("\n");
#endif
/// Scrambling
uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]={0};
uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0};
nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output);
#ifdef DEBUG_CHANNEL_CODING
printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \
printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \
[6]->0x%08x \t [7]->0x%08x \t [8]->0x%08x \t [9]->0x%08x\t [10]->0x%08x\t [11]->0x%08x\n",
scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5],
scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] );
scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5],
scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] );
#endif
// QPSK modulation
/// QPSK modulation
int16_t mod_dci[NR_MAX_DCI_SIZE>>1];
for (int i=0; i<encoded_length>>1; i++) {
idx = ((((scrambled_output[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((scrambled_output[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
mod_dci[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
mod_dci[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
nr_modulation(scrambled_output, encoded_length, MOD_QPSK, mod_dci);
#ifdef DEBUG_DCI
printf("i %d idx %d b0-b1 %d-%d mod_dci %d %d\n", i, idx, (((scrambled_output[(i<<1)>>5])>>((i<<1)&0x1f))&1),
(((scrambled_output[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), mod_dci[(i<<1)], mod_dci[(i<<1)+1]);
for (int i=0; i<encoded_length>>1; i++)
printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] );
#endif
}
/// Resource mapping
if (cset_start_sc >= frame_parms.ofdm_symbol_size)
cset_start_sc -= frame_parms.ofdm_symbol_size;
if (cset_start_sc >= frame_parms.ofdm_symbol_size)
cset_start_sc -= frame_parms.ofdm_symbol_size;
/*Reorder REG list for a freq first mapping*/
uint8_t symb_idx[NR_MAX_CSET_DURATION] = {0,0,0};
uint8_t nb_regs = dci_alloc.L*NR_NB_REG_PER_CCE;
uint8_t regs_per_symb = nb_regs/cset_nsymb;
/*Reorder REG list for a freq first mapping*/
uint8_t symb_idx[NR_MAX_CSET_DURATION] = {0,0,0};
uint8_t nb_regs = dci_alloc.L*NR_NB_REG_PER_CCE;
uint8_t regs_per_symb = nb_regs/cset_nsymb;
for (int cce_idx=0; cce_idx<dci_alloc.L; cce_idx++){
cce = dci_alloc.cce_list[cce_idx];
for (int reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) {
reg = cce.reg_list[reg_idx];
reg_mapping_list[reg.symb_idx*regs_per_symb + symb_idx[reg.symb_idx]++] = reg;
}
for (int cce_idx=0; cce_idx<dci_alloc.L; cce_idx++) {
cce = dci_alloc.cce_list[cce_idx];
for (int reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) {
reg = cce.reg_list[reg_idx];
reg_mapping_list[reg.symb_idx*regs_per_symb + symb_idx[reg.symb_idx]++] = reg;
}
}
#ifdef DEBUG_DCI
printf("\n Ordered REG list:\n");
for (int i=0; i<nb_regs; i++)
printf("%d\t",reg_mapping_list[i].reg_idx );
printf("\n");
#endif
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS) {
/*in this case the DMRS are mapped on all the coreset*/
for (l=cset_start_symb; l<cset_start_symb+ cset_nsymb; l++) {
dmrs_idx = 0;
k = cset_start_sc + 1;
while (dmrs_idx<3*pdcch_params.n_rb) {
((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS
printf("symbol %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] , ((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
#endif
k+=4;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
dmrs_idx++;
}
}
}
printf("\n Ordered REG list:\n");
/*Now mapping the encoded DCI based on newly constructed REG list
* and the DMRS for the precoder granularity same as REG bundle*/
for (int reg_idx=0; reg_idx<nb_regs; reg_idx++) {
reg = reg_mapping_list[reg_idx];
k = cset_start_sc + reg.start_sc_idx;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
l = cset_start_symb + reg.symb_idx;
dmrs_idx = (reg.reg_idx/cset_nsymb)*3;
k_prime = 0;
for (int m=0; m<NR_NB_SC_PER_RB; m++) {
if ( m == (k_prime<<2)+1) { // DMRS if not already mapped
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_SAME_AS_REG_BUNDLE) {
((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS
printf("l %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] , ((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
for (int i=0; i<nb_regs; i++)
printf("%d\t",reg_mapping_list[i].reg_idx );
printf("\n");
#endif
k_prime++;
dmrs_idx++;
}
}
else { // DCI payload
((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15;
//printf("dci output %d %d\n",(a * mod_dci[dci_idx<<1]) >> 15, (a * mod_dci[(dci_idx<<1) + 1]) >> 15);
dci_idx++;
}
k++;
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS) {
/*in this case the DMRS are mapped on all the coreset*/
for (l=cset_start_symb; l<cset_start_symb+ cset_nsymb; l++) {
dmrs_idx = 0;
k = cset_start_sc + 1;
while (dmrs_idx<3*pdcch_params.n_rb) {
((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = ((amp>>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS
printf("symbol %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
#endif
k+=4;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
dmrs_idx++;
}
}
}
/*Now mapping the encoded DCI based on newly constructed REG list
* and the DMRS for the precoder granularity same as REG bundle*/
for (int reg_idx=0; reg_idx<nb_regs; reg_idx++) {
reg = reg_mapping_list[reg_idx];
k = cset_start_sc + reg.start_sc_idx;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
l = cset_start_symb + reg.symb_idx;
dmrs_idx = (reg.reg_idx/cset_nsymb)*3;
k_prime = 0;
for (int m=0; m<NR_NB_SC_PER_RB; m++) {
if ( m == (k_prime<<2)+1) { // DMRS if not already mapped
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_SAME_AS_REG_BUNDLE) {
((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = ((amp>>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS
printf("l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
#endif
dmrs_idx++;
}
k_prime++;
} else { // DCI payload
((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15;
#ifdef DEBUG_DCI
printf("l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
#endif
dci_idx++;
}
k++;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
}
}
return 0;
}
+6 -7
View File
@@ -28,14 +28,13 @@
typedef unsigned __int128 uint128_t;
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type,
uint16_t N_RB,
nfapi_nr_config_request_t* config);
nfapi_nr_rnti_type_e rnti_type,
uint16_t N_RB,
nfapi_nr_config_request_t *config);
uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
t_nrPolar_paramsPtr *nrPolar_params,
uint32_t **gold_pdcch_dmrs,
int32_t* txdataF,
int32_t *txdataF,
int16_t amp,
NR_DL_FRAME_PARMS frame_parms,
nfapi_nr_config_request_t config);
@@ -44,7 +43,7 @@ void nr_pdcch_scrambling(uint32_t *in,
uint16_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out);
uint32_t *out);
void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
int frame,
@@ -54,7 +53,7 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
nfapi_nr_dl_config_dci_dl_pdu *pdu,
nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu);
void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m);
void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t *dci_alloc, uint16_t n_shift, uint8_t m);
#endif //__PHY_NR_TRANSPORT_DCI__H
+130 -74
View File
@@ -36,7 +36,6 @@
#include "nr_dlsch.h"
void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m) {
nr_cce_t* cce;
@@ -48,6 +47,8 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m
uint8_t R = pdcch_params->interleaver_size;
uint16_t N_reg = pdcch_params->n_rb * pdcch_params->n_symb;
uint16_t Y, N_cce, M_s_max, n_CI=0, tmp, C;
uint16_t n_RNTI = (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params->rnti:0;
uint32_t A[3]={39827,39829,39839};
if (pdcch_params->config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1)
AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L);
@@ -59,13 +60,16 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m
if (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON)
Y = 0;
else { //NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC
Y = (A[0]*n_RNTI)%65537; // Candidate 0, antenna port 0
}
uint8_t cond = N_reg%(bsize*R);
AssertFatal(cond==0, "CCE to REG interleaving: Invalid configuration leading to non integer C\n");
C = N_reg/(bsize*R);
if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
AssertFatal((N_reg%(bsize*R))==0, "CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %d, bsize %d R %d)\n",
N_reg, bsize, R);
C = N_reg/(bsize*R);
}
tmp = L * (( Y + (m*N_cce)/(L*M_s_max) + n_CI ) % (N_cce/L));
tmp = L * (( Y + (m*N_cce)/(L*M_s_max) + n_CI ) % CEILIDIV(N_cce,L));
LOG_I(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d tmp %d\n", m, bsize, R, tmp);
for (uint8_t cce_idx=0; cce_idx<L; cce_idx++) {
@@ -109,6 +113,13 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m
}
}
/*static inline uint64_t dci_field(uint64_t field, uint8_t size) {
uint64_t ret = 0;
for (int i=0; i<size; i++)
ret |= ((field>>i)&1)<<(size-i-1);
return ret;
}*/
void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
int frame,
int subframe,
@@ -154,51 +165,66 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
case NFAPI_NR_DL_DCI_FORMAT_1_0:
switch(params_rel15->rnti_type) {
case NFAPI_NR_RNTI_RA:
// printf("dci_pdu %llx\n",(unsigned long long int)*dci_pdu);
// Freq domain assignment
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
pos=fsize;
*dci_pdu |= ((pdu_rel15->frequency_domain_assignment&((1<<fsize)-1)) << (dci_alloc->size-pos));
#ifdef DEBUG_FILL_DCI
printf("frequency-domain assignment %d (%d bits)=> %d (%llx)\n",pdu_rel15->frequency_domain_assignment,fsize,dci_alloc->size-pos,(unsigned long long int)*dci_pdu);
printf("frequency-domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->frequency_domain_assignment,fsize,dci_alloc->size-pos,*dci_pdu);
#endif
// Time domain assignment
pos+=4;
*dci_pdu |= ((pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos));
*dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos));
#ifdef DEBUG_FILL_DCI
printf("time-domain assignment %d (3 bits)=> %d (%llx)\n",pdu_rel15->time_domain_assignment,dci_alloc->size-pos,(unsigned long long int)*dci_pdu);
printf("time-domain assignment %d (3 bits)=> %d (0x%lx)\n",pdu_rel15->time_domain_assignment,dci_alloc->size-pos,*dci_pdu);
#endif
// VRB to PRB mapping
pos++;
*dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&0x1)<<(dci_alloc->size-pos);
*dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&0x1)<<(dci_alloc->size-pos);
#ifdef DEBUG_FILL_DCI
printf("vrb to prb mapping %d (1 bits)=> %d (%llx)\n",pdu_rel15->vrb_to_prb_mapping,dci_alloc->size-pos,(unsigned long long int)*dci_pdu);
printf("vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",pdu_rel15->vrb_to_prb_mapping,dci_alloc->size-pos,*dci_pdu);
#endif
// MCS
pos+=5;
*dci_pdu |= (pdu_rel15->mcs&0x1f)<<(dci_alloc->size-pos);
*dci_pdu |= ((uint64_t)pdu_rel15->mcs&0x1f)<<(dci_alloc->size-pos);
#ifdef DEBUG_FILL_DCI
printf("mcs %d (5 bits)=> %d (%llx)\n",pdu_rel15->mcs,dci_alloc->size-pos,(unsigned long long int)*dci_pdu);
printf("mcs %d (5 bits)=> %d (0x%lx)\n",pdu_rel15->mcs,dci_alloc->size-pos,*dci_pdu);
#endif
// TB scaling
pos+=2;
*dci_pdu |= (pdu_rel15->tb_scaling&0x3)<<(dci_alloc->size-pos);
*dci_pdu |= ((uint64_t)pdu_rel15->tb_scaling&0x3)<<(dci_alloc->size-pos);
#ifdef DEBUG_FILL_DCI
printf("tb_scaling %d (2 bits)=> %d (%llx)\n",pdu_rel15->tb_scaling,dci_alloc->size-pos,(unsigned long long int)*dci_pdu);
printf("tb_scaling %d (2 bits)=> %d (0x%lx)\n",pdu_rel15->tb_scaling,dci_alloc->size-pos,*dci_pdu);
#endif
break;
case NFAPI_NR_RNTI_C:
case NFAPI_NR_RNTI_C:
// indicating a DL DCI format 1bit
pos++;
*dci_pdu |= (pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos);
*dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos);
#ifdef DEBUG_FILL_DCI
printf("Format indicator %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->format_indicator,1,dci_alloc->size-pos,*dci_pdu);
#endif
// Freq domain assignment (275rb >> fsize = 16)
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
pos+=fsize;
*dci_pdu |= ((pdu_rel15->frequency_domain_assignment&((1<<fsize)-1)) << (dci_alloc->size-pos));
*dci_pdu |= (((uint64_t)pdu_rel15->frequency_domain_assignment&((1<<fsize)-1)) << (dci_alloc->size-pos));
if (((pdu_rel15->frequency_domain_assignment+1)&1) ==0) //fsize are all 1 38.212 p86
#ifdef DEBUG_FILL_DCI
printf("Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->frequency_domain_assignment,fsize,dci_alloc->size-pos,*dci_pdu);
#endif
uint16_t is_ra = 1;
for (int i=0; i<fsize; i++)
if (!((pdu_rel15->frequency_domain_assignment>>i)&1)) {
is_ra = 0;
break;
}
if (is_ra) //fsize are all 1 38.212 p86
{
// ra_preamble_index 6 bits
pos+=6;
@@ -223,44 +249,73 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
// Time domain assignment 4bit
pos+=4;
*dci_pdu |= ((pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos));
*dci_pdu |= ((pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos));
#ifdef DEBUG_FILL_DCI
printf("Time domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->time_domain_assignment,4,dci_alloc->size-pos,*dci_pdu);
#endif
// VRB to PRB mapping 1bit
pos++;
*dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos);
#ifdef DEBUG_FILL_DCI
printf("VRB to PRB %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->vrb_to_prb_mapping,1,dci_alloc->size-pos,*dci_pdu);
#endif
// MCS 5bit //bit over 32, so dci_pdu ++
pos+=5;
*dci_pdu |= (pdu_rel15->mcs&0x1f)<<(dci_alloc->size-pos);
#ifdef DEBUG_FILL_DCI
printf("MCS %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->mcs,5,dci_alloc->size-pos,*dci_pdu);
#endif
// New data indicator 1bit
pos++;
*dci_pdu |= (pdu_rel15->ndi&1)<<(dci_alloc->size-pos);
#ifdef DEBUG_FILL_DCI
printf("NDI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->ndi,1,dci_alloc->size-pos,*dci_pdu);
#endif
// Redundancy version 2bit
pos+=2;
*dci_pdu |= (pdu_rel15->rv&0x3)<<(dci_alloc->size-pos);
#ifdef DEBUG_FILL_DCI
printf("RV %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->rv,2,dci_alloc->size-pos,*dci_pdu);
#endif
// HARQ process number 4bit
pos+=4;
*dci_pdu |= ((pdu_rel15->harq_pid&0xf)<<(dci_alloc->size-pos));
*dci_pdu |= ((pdu_rel15->harq_pid&0xf)<<(dci_alloc->size-pos));
#ifdef DEBUG_FILL_DCI
printf("HARQ_PID %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->harq_pid,4,dci_alloc->size-pos,*dci_pdu);
#endif
// Downlink assignment index 2bit
pos+=2;
*dci_pdu |= ((pdu_rel15->dai&3)<<(dci_alloc->size-pos));
#ifdef DEBUG_FILL_DCI
printf("DAI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->dai,2,dci_alloc->size-pos,*dci_pdu);
#endif
// TPC command for scheduled PUCCH 2bit
pos+=2;
*dci_pdu |= ((pdu_rel15->tpc&3)<<(dci_alloc->size-pos));
*dci_pdu |= ((pdu_rel15->tpc&3)<<(dci_alloc->size-pos));
#ifdef DEBUG_FILL_DCI
printf("TPC %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->tpc,2,dci_alloc->size-pos,*dci_pdu);
#endif
// PUCCH resource indicator 3bit
pos+=3;
*dci_pdu |= ((pdu_rel15->pucch_resource_indicator&0x7)<<(dci_alloc->size-pos));
*dci_pdu |= ((pdu_rel15->pucch_resource_indicator&0x7)<<(dci_alloc->size-pos));
#ifdef DEBUG_FILL_DCI
printf("PUCCH RI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->pucch_resource_indicator,3,dci_alloc->size-pos,*dci_pdu);
#endif
// PDSCH-to-HARQ_feedback timing indicator 3bit
pos+=3;
*dci_pdu |= ((pdu_rel15->pdsch_to_harq_feedback_timing_indicator&0x7)<<(dci_alloc->size-pos));
*dci_pdu |= ((pdu_rel15->pdsch_to_harq_feedback_timing_indicator&0x7)<<(dci_alloc->size-pos));
#ifdef DEBUG_FILL_DCI
printf("PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->pdsch_to_harq_feedback_timing_indicator,3,dci_alloc->size-pos,*dci_pdu);
#endif
} //end else
break;
@@ -269,26 +324,26 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
// Short Messages Indicator – 2 bits
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->short_messages_indicator>>(1-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->short_messages_indicator>>(1-i))&1)<<(dci_alloc->size-pos++);
// Short Messages – 8 bits
for (int i=0; i<8; i++)
*dci_pdu |= ((pdu_rel15->short_messages>>(7-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->short_messages>>(7-i))&1)<<(dci_alloc->size-pos++);
// Freq domain assignment 0-16 bit
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
for (int i=0; i<fsize; i++)
*dci_pdu |= ((pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
// Time domain assignment 4 bit
for (int i=0; i<4; i++)
*dci_pdu |= ((pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
// VRB to PRB mapping 1 bit
*dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
// MCS 5 bit
for (int i=0; i<5; i++)
*dci_pdu |= ((pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
// TB scaling 2 bit
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->tb_scaling>>(1-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->tb_scaling>>(1-i))&1)<<(dci_alloc->size-pos++);
break;
@@ -300,49 +355,49 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
*dci_pdu |= ((pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
// Time domain assignment 4 bit
for (int i=0; i<4; i++)
*dci_pdu |= ((pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
// VRB to PRB mapping 1 bit
*dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
// MCS 5bit //bit over 32, so dci_pdu ++
for (int i=0; i<5; i++)
*dci_pdu |= ((pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
// Redundancy version 2bit
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
break;
case NFAPI_NR_RNTI_TC:
// indicating a DL DCI format 1bit
*dci_pdu |= (pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++);
// Freq domain assignment 0-16 bit
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
for (int i=0; i<fsize; i++)
*dci_pdu |= ((pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
// Time domain assignment 4 bit
for (int i=0; i<4; i++)
*dci_pdu |= ((pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
// VRB to PRB mapping 1 bit
*dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
// MCS 5bit //bit over 32, so dci_pdu ++
for (int i=0; i<5; i++)
*dci_pdu |= ((pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
// New data indicator 1bit
*dci_pdu |= (pdu_rel15->ndi&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++);
// Redundancy version 2bit
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
// HARQ process number 4bit
for (int i=0; i<4; i++)
*dci_pdu |= ((pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
// Downlink assignment index – 2 bits
// Downlink assignment index – 2 bits
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->dai>>(1-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->dai>>(1-i))&1)<<(dci_alloc->size-pos++);
// TPC command for scheduled PUCCH – 2 bits
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
// LOG_I(PHY, "DCI PDU: [0]->0x%08llx \t [1]->0x%08llx \t [2]->0x%08llx \t [3]->0x%08llx\n",
@@ -351,49 +406,50 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
// PDSCH-to-HARQ_feedback timing indicator – 3 bits
for (int i=0; i<3; i++)
*dci_pdu |= ((pdu_rel15->pdsch_to_harq_feedback_timing_indicator>>(2-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->pdsch_to_harq_feedback_timing_indicator>>(2-i))&1)<<(dci_alloc->size-pos++);
break;
}
break;
case NFAPI_NR_UL_DCI_FORMAT_0_0:
switch(params_rel15->rnti_type)
{
case NFAPI_NR_RNTI_C:
// indicating a DL DCI format 1bit
*dci_pdu |= (pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++);
// Freq domain assignment max 16 bit
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
for (int i=0; i<fsize; i++)
*dci_pdu |= ((pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
// Time domain assignment 4bit
for (int i=0; i<4; i++)
*dci_pdu |= ((pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
// Frequency hopping flag – 1 bit
*dci_pdu |= (pdu_rel15->frequency_hopping_flag&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->frequency_hopping_flag&1)<<(dci_alloc->size-pos++);
// MCS 5 bit
for (int i=0; i<5; i++)
*dci_pdu |= ((pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
// New data indicator 1bit
*dci_pdu |= (pdu_rel15->ndi&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++);
// Redundancy version 2bit
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
// HARQ process number 4bit
for (int i=0; i<4; i++)
*dci_pdu |= ((pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
// TPC command for scheduled PUSCH – 2 bits
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
// Padding bits
for(int a = pos;a<32;a++)
*dci_pdu |= (pdu_rel15->padding&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->padding&1)<<(dci_alloc->size-pos++);
// UL/SUL indicator – 1 bit
if (cfg->pucch_config.pucch_GroupHopping.value)
*dci_pdu |= (pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++);
break;
@@ -407,39 +463,39 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
*dci_pdu |= ((pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
// Time domain assignment 4bit
for (int i=0; i<4; i++)
*dci_pdu |= ((pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
// Frequency hopping flag – 1 bit
*dci_pdu |= (pdu_rel15->frequency_hopping_flag&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->frequency_hopping_flag&1)<<(dci_alloc->size-pos++);
// MCS 5 bit
for (int i=0; i<5; i++)
*dci_pdu |= ((pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
// New data indicator 1bit
*dci_pdu |= (pdu_rel15->ndi&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++);
// Redundancy version 2bit
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
// HARQ process number 4bit
for (int i=0; i<4; i++)
*dci_pdu |= ((pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
// TPC command for scheduled PUSCH – 2 bits
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
*dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
// Padding bits
for(int a = pos;a<32;a++)
*dci_pdu |= (pdu_rel15->padding&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->padding&1)<<(dci_alloc->size-pos++);
// UL/SUL indicator – 1 bit
if (cfg->pucch_config.pucch_GroupHopping.value)
*dci_pdu |= (pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++);
*dci_pdu |= ((uint64_t)pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++);
break;
}
break;
}
LOG_I(PHY, "DCI PDU: [0]->0x%16llxx \t [1]->0x%16llx \n",(long long unsigned int)dci_pdu[0], (long long unsigned int)dci_pdu[1]);
LOG_I(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]);
LOG_I(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx);
/// DLSCH struct
+5 -7
View File
@@ -338,11 +338,9 @@ ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol);
for (int l=rel15->start_symbol; l<rel15->start_symbol+rel15->nb_symbols; l++) {
k = start_sc;
for (int i=0; i<rel15->n_prb*NR_NB_SC_PER_RB; i++) {
// Note the dmrs index modulo 2048 only works for that symbol size -- to be fixed soon
// Also the different amplitudes are for debug purposes and temporary
if ((l == dmrs_symbol) && (k == ((start_sc+get_pdsch_dmrs_idx(n, k_prime, delta, dmrs_type))&((1<<11)-1)))) {
((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*(amp>>1)*mod_dmrs[dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*(amp>>1)*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
if ((l == dmrs_symbol) && (k == ((start_sc+get_pdsch_dmrs_idx(n, k_prime, delta, dmrs_type))%(frame_parms.ofdm_symbol_size)))) {
((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1],
@@ -356,8 +354,8 @@ dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_s
else {
((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1] = ((amp<<1) * tx_layers[ap][m<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp<<1) * tx_layers[ap][(m<<1) + 1]) >> 15;
((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * tx_layers[ap][m<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, k, ((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1],
+31 -12
View File
@@ -69,7 +69,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
#endif
if (dlsch->harq_processes[i]->b) {
free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES);
free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); //this should be MAX_NR_DLSCH_PAYLOAD_BYTES
dlsch->harq_processes[i]->b = NULL;
#ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
@@ -195,8 +195,11 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
if (abstraction_flag==0) {
for (r=0; r<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling; r++) {
// account for filler in first segment and CRCs for multiple segment case
// [hna] 8448 is the maximum CB size in NR
// 68*348 = 68*(maximum size of Zc)
// In section 5.3.2 in 38.212, the for loop is up to N + 2*Zc (maximum size of N is 66*Zc, therefore 68*Zc)
dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448);
dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384);
dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output
if (dlsch->harq_processes[i]->c[r]) {
bzero(dlsch->harq_processes[i]->c[r],8448);
} else {
@@ -272,22 +275,22 @@ int nr_dlsch_encoding(unsigned char *a,
unsigned int G;
unsigned int crc=1;
uint8_t harq_pid = dlsch->harq_ids[slot];
nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
uint16_t nb_rb = rel15.n_prb;
uint8_t nb_symb_sch = rel15.nb_symbols;
uint32_t A, Z;
uint32_t A, Z, F=0;
uint32_t *pz = &Z;
uint8_t mod_order = rel15.modulation_order;
uint16_t Kr=0,r,r_offset=0,Kr_bytes;
uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
uint8_t kb,BG=1;
uint8_t BG=1;
uint32_t E;
uint8_t Ilbrm = 0;
uint32_t Tbslbrm = 950984; //max tbs
uint8_t nb_re_dmrs = rel15.nb_re_dmrs;
uint16_t length_dmrs = 1;
float Coderate = 0.0;
/*
uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char
@@ -301,7 +304,9 @@ int nr_dlsch_encoding(unsigned char *a,
A = rel15.transport_block_size;
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15.nb_layers);
LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order);
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, rel15.nb_layers);
@@ -327,6 +332,7 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->B = A+24;
// dlsch->harq_processes[harq_pid]->b = a;
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
nr_segmentation(dlsch->harq_processes[harq_pid]->b,
@@ -334,21 +340,23 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->B,
&dlsch->harq_processes[harq_pid]->C,
&dlsch->harq_processes[harq_pid]->K,
pz,
pz, // [hna] pz is Zc
&dlsch->harq_processes[harq_pid]->F);
kb = dlsch->harq_processes[harq_pid]->K/(*pz);
if ( kb==22){
BG = 1;
F = dlsch->harq_processes[harq_pid]->F;
Coderate = (float) A /(float) G;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
BG = 2;
}
else{
BG = 2;
BG = 1;
}
Kr = dlsch->harq_processes[harq_pid]->K;
Kr_bytes = Kr>>3;
//printf("segment Z %d kb %d k %d Kr %d BG %d\n", *pz,kb,dlsch->harq_processes[harq_pid]->K,Kr,BG);
//printf("segment Z %d k %d Kr %d BG %d\n", *pz,dlsch->harq_processes[harq_pid]->K,Kr,BG);
//start_meas(te_stats);
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
@@ -385,6 +393,7 @@ int nr_dlsch_encoding(unsigned char *a,
//stop_meas(te_stats);
//printf("end ldpc encoder -- output\n");
//write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4);
#ifdef DEBUG_DLSCH_CODING
write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4);
write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[0][0],(3*8*Kr_bytes)+12,1,4);
@@ -393,6 +402,14 @@ int nr_dlsch_encoding(unsigned char *a,
}
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
if (dlsch->harq_processes[harq_pid]->F>0) {
for (int k=(Kr-F-2*(*pz)); k<Kr-2*(*pz); k++) {
dlsch->harq_processes[harq_pid]->d[r][k] = NR_NULL;
//if (k<(Kr-F+8))
//printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]);
}
}
#ifdef DEBUG_DLSCH_CODING
printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
r,
@@ -418,6 +435,7 @@ int nr_dlsch_encoding(unsigned char *a,
rel15.redundancy_version,
E);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset);
@@ -431,6 +449,7 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->f+r_offset);
//stop_meas(i_stats);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset);
@@ -444,5 +463,5 @@ int nr_dlsch_encoding(unsigned char *a,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0);
return 0;
}
+151 -164
View File
@@ -43,21 +43,20 @@
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31};
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31
};
int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config,
NR_DL_FRAME_PARMS *frame_parms)
{
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms) {
int k,l;
//int16_t a;
int16_t mod_dmrs[NR_PBCH_DMRS_LENGTH<<1];
uint8_t idx=0;
uint8_t nushift = config->sch_config.physical_cell_id.value &3;
LOG_D(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift);
/// QPSK modulation
@@ -66,79 +65,75 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
mod_dmrs[m<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
mod_dmrs[(m<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
#ifdef DEBUG_PBCH_DMRS
printf("m %d idx %d gold seq %d b0-b1 %d-%d mod_dmrs %d %d\n", m, idx, gold_pbch_dmrs[(m<<1)>>5], (((gold_pbch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&1),
(((gold_pbch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), mod_dmrs[(m<<1)], mod_dmrs[(m<<1)+1]);
printf("m %d idx %d gold seq %d b0-b1 %d-%d mod_dmrs %d %d\n", m, idx, gold_pbch_dmrs[(m<<1)>>5], (((gold_pbch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&1),
(((gold_pbch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), mod_dmrs[(m<<1)], mod_dmrs[(m<<1)+1]);
#endif
}
/// Resource mapping
// PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3
///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l = ssb_start_symbol + 1;
// PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3
///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l = ssb_start_symbol + 1;
for (int m = 0; m < 60; m++) {
for (int m = 0; m < 60; m++) {
#ifdef DEBUG_PBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l);
printf("m %d at k %d of l %d\n", m, k, l);
#endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
#ifdef DEBUG_PBCH_DMRS
printf("(%d,%d)\n",
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
printf("(%d,%d)\n",
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
k+=4;
k+=4;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
///symbol 2 [0+u:4:44+nushift ; 192+nu:4:236+nushift] -- 24 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l++;
///symbol 2 [0+u:4:44+nushift ; 192+nu:4:236+nushift] -- 24 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l++;
for (int m = 60; m < 84; m++) {
for (int m = 60; m < 84; m++) {
#ifdef DEBUG_PBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l);
printf("m %d at k %d of l %d\n", m, k, l);
#endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
#ifdef DEBUG_PBCH_DMRS
printf("(%d,%d)\n",
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
printf("(%d,%d)\n",
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
k+=(m==71)?148:4; // Jump from 44+nu to 192+nu
k+=(m==71)?148:4; // Jump from 44+nu to 192+nu
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l++;
///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l++;
for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) {
for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) {
#ifdef DEBUG_PBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l);
printf("m %d at k %d of l %d\n", m, k, l);
#endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
#ifdef DEBUG_PBCH_DMRS
printf("(%d,%d)\n",
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
printf("(%d,%d)\n",
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
k+=4;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
k+=4;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
#ifdef DEBUG_PBCH_DMRS
write_output("txdataF_pbch_dmrs.m", "txdataF_pbch_dmrs", txdataF[0], frame_parms->samples_per_frame_wCP>>1, 1, 1);
@@ -186,6 +181,7 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
pbch->pbch_a_prime ^= (((pbch->pbch_a_interleaved>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
k++; /// k increase only when payload bit is not special bit
}
@@ -206,11 +202,11 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
void nr_init_pbch_interleaver(uint8_t *interleaver) {
uint8_t j_sfn=0, j_hrf=10, j_ssb=11, j_other=14;
memset((void*)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
memset((void *)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
for (uint8_t i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
if (!i) // choice bit:1
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
else if (i<7) //Sfn bits:6
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++);
else if (i<24) // other:17
@@ -221,11 +217,9 @@ void nr_init_pbch_interleaver(uint8_t *interleaver) {
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_hrf);
else // Ssb bits:3
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_ssb++);
}
int nr_generate_pbch(NR_gNB_PBCH *pbch,
t_nrPolar_paramsPtr polar_params,
uint8_t *pbch_pdu,
uint8_t *interleaver,
int32_t *txdataF,
@@ -235,10 +229,8 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t Lmax,
uint8_t ssb_index,
int sfn,
nfapi_nr_config_request_t* config,
NR_DL_FRAME_PARMS *frame_parms)
{
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms) {
int k,l,m;
//int16_t a;
int16_t mod_pbch_e[NR_POLAR_PBCH_E];
@@ -247,22 +239,23 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t nushift;
uint32_t unscrambling_mask;
uint64_t a_reversed=0;
LOG_I(PHY, "PBCH generation started\n");
///Payload generation
memset((void*)pbch, 0, sizeof(NR_gNB_PBCH));
memset((void *)pbch, 0, sizeof(NR_gNB_PBCH));
pbch->pbch_a=0;
for (int i=0; i<NR_PBCH_PDU_BITS; i++)
pbch->pbch_a |= ((pbch_pdu[2-(i>>3)]>>(7-(i&7)))&1)<<i;
#ifdef DEBUG_PBCH_ENCODING
for (int i=0; i<3; i++)
printf("pbch_pdu[%d]: 0x%02x\n", i, pbch_pdu[i]);
printf("PBCH payload = 0x%08x\n",pbch->pbch_a);
#endif
// Extra byte generation
// Extra byte generation
for (int i=0; i<4; i++)
pbch->pbch_a |= ((sfn>>(3-i))&1)<<(24+i); // resp. 4th, 3rd, 2nd ans 1st lsb of sfn
@@ -276,12 +269,12 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
LOG_I(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a);
// Payload interleaving
// Payload interleaving
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) {
pbch->pbch_a_interleaved |= ((pbch->pbch_a>>i)&1)<<(*(interleaver+i));
#ifdef DEBUG_PBCH_ENCODING
printf("i %d out 0x%08x ilv %d (in>>i)&1) %d\n", i, pbch->pbch_a_interleaved, *(interleaver+i), (pbch->pbch_a>>i)&1);
printf("i %d out 0x%08x ilv %d (in>>i)&1) %d\n", i, pbch->pbch_a_interleaved, *(interleaver+i), (pbch->pbch_a>>i)&1);
#endif
}
@@ -289,8 +282,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
printf("Interleaving:\n");
printf("pbch_a_interleaved: 0x%08x\n", pbch->pbch_a_interleaved);
#endif
// Scrambling
// Scrambling
unscrambling_mask = (Lmax ==64)? 0x100006D:0x1000041;
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = (((sfn>>2)&1)<<1) ^ ((sfn>>1)&1);
@@ -301,148 +293,143 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
printf("pbch_a_prime: 0x%08x\n", pbch->pbch_a_prime);
#endif
// Encoder reversal
// Encoder reversal
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
a_reversed |= (((uint64_t)pbch->pbch_a_prime>>i)&1)<<(31-i);
/// CRC, coding and rate matching
polar_encoder_fast (&a_reversed, (uint32_t*)pbch->pbch_e, 0, polar_params);
polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0,
nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL)
);
#ifdef DEBUG_PBCH_ENCODING
printf("Channel coding:\n");
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]);
printf("\n");
#endif
/// Scrambling
M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0);
#ifdef DEBUG_PBCH_ENCODING
printf("Scrambling:\n");
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]);
printf("\n");
#endif
/// QPSK modulation
for (int i=0; i<NR_POLAR_PBCH_E>>1; i++){
for (int i=0; i<NR_POLAR_PBCH_E>>1; i++) {
idx = (((pbch->pbch_e[(i<<1)>>5]>>((i<<1)&0x1f))&1)<<1) ^ ((pbch->pbch_e[((i<<1)+1)>>5]>>(((i<<1)+1)&0x1f))&1);
mod_pbch_e[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
mod_pbch_e[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1)+1];
#ifdef DEBUG_PBCH
printf("i %d idx %d mod_pbch %d %d\n", i, idx, mod_pbch_e[2*i], mod_pbch_e[2*i+1]);
printf("i %d idx %d mod_pbch %d %d\n", i, idx, mod_pbch_e[2*i], mod_pbch_e[2*i+1]);
#endif
}
/// Resource mapping
nushift = config->sch_config.physical_cell_id.value &3;
// PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS
///symbol 1 [0:239] -- 180 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
l = ssb_start_symbol + 1;
m = 0;
// PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS
///symbol 1 [0:239] -- 180 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
l = ssb_start_symbol + 1;
m = 0;
for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) { //skip DMRS
k++;
continue;
}
else {
for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) { //skip DMRS
k++;
continue;
} else {
#ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++;
m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++;
m++;
}
///symbol 2 [0:47 ; 192:239] -- 72 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
l++;
m=180;
for (int ssb_sc_idx = 0; ssb_sc_idx < 48; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) {
k++;
continue;
}
else {
#ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++;
m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
k += 144;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
m=216;
///symbol 2 [0:47 ; 192:239] -- 72 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
l++;
m=180;
for (int ssb_sc_idx = 192; ssb_sc_idx < 240; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) {
k++;
continue;
}
else {
for (int ssb_sc_idx = 0; ssb_sc_idx < 48; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) {
k++;
continue;
} else {
#ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++;
m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++;
m++;
}
///symbol 3 [0:239] -- 180 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
l++;
m=252;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) {
k += 144;
if ((ssb_sc_idx&3) == nushift) {
k++;
continue;
}
else {
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
m=216;
for (int ssb_sc_idx = 192; ssb_sc_idx < 240; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) {
k++;
continue;
} else {
#ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++;
m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++;
m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
///symbol 3 [0:239] -- 180 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
l++;
m=252;
for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) {
k++;
continue;
} else {
#ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++;
m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
return 0;
}
-1
View File
@@ -59,7 +59,6 @@ int nr_generate_pss( int16_t *d_pss,
/// Resource mapping
a = amp;
// PSS occupies a predefined position (subcarriers 56-182, symbol 0) within the SSB block starting from
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; //and
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
+4 -5
View File
@@ -36,7 +36,7 @@ int nr_generate_pss( int16_t *d_pss,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config,
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
@@ -49,7 +49,7 @@ int nr_generate_sss( int16_t *d_sss,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config,
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
@@ -62,7 +62,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config,
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
@@ -85,7 +85,6 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
@returns 0 on success
*/
int nr_generate_pbch(NR_gNB_PBCH *pbch,
t_nrPolar_paramsPtr polar_params,
uint8_t *pbch_pdu,
uint8_t *interleaver,
int32_t *txdataF,
@@ -95,7 +94,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t Lmax,
uint8_t ssb_index,
int sfn,
nfapi_nr_config_request_t* config,
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
@@ -38,7 +38,7 @@
#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS
#define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
#define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
#define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056)
#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*6) // 14 symbols, 273 RB
#define MAX_NUM_NR_RE (14*273*12)
+49
View File
@@ -0,0 +1,49 @@
/*
* 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.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/NR_TRANSPORT/nr_ulsch.h
* \brief functions used for PUSCH/ULSCH physical and transport channels for gNB
* \author Ahmed Hussein
* \date 2019
* \version 0.1
* \company Fraunhofer IIS
* \email: ahmed.hussein@iis.fraunhofer.de
* \note
* \warning
*/
#include "PHY/defs_gNB.h"
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint16_t nb_symb_sch,
uint8_t nr_tti_rx,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t llr8_flag);
@@ -0,0 +1,611 @@
/*
* 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.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/NR_TRANSPORT/nr_ulsch_decoding.c
* \brief Top-level routines for decoding LDPC (ULSCH) transport channels from 38.212, V15.4.0 2018-12
* \author Ahmed Hussein
* \date 2019
* \version 0.1
* \company Fraunhofer IIS
* \email: ahmed.hussein@iis.fraunhofer.de
* \note
* \warning
*/
// [from gNB coding]
#include "PHY/defs_gNB.h"
#include "PHY/phy_extern.h"
#include "PHY/CODING/coding_extern.h"
#include "PHY/CODING/coding_defs.h"
#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "SCHED_NR/sched_nr.h"
#include "defs.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
#include <syscall.h>
//#define DEBUG_ULSCH_DECODING
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
static uint64_t nb_total_decod =0;
static uint64_t nb_error_decod =0;
//extern double cpuf;
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
{
int i,r;
if (ulsch) {
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
if (ulsch->harq_processes[i]) {
if (ulsch->harq_processes[i]->b) {
free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES);
ulsch->harq_processes[i]->b = NULL;
}
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS; r++) {
free16(ulsch->harq_processes[i]->c[r],(8448)*sizeof(uint8_t));
ulsch->harq_processes[i]->c[r] = NULL;
}
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS; r++) {
if (ulsch->harq_processes[i]->d[r]) {
free16(ulsch->harq_processes[i]->d[r],(68*384)*sizeof(int16_t));
ulsch->harq_processes[i]->d[r] = NULL;
}
}
for (r=0; r<(MAX_NUM_NR_ULSCH_SEGMENTS); r++) {
if (ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]){
nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
}
}
free16(ulsch->harq_processes[i],sizeof(NR_UL_gNB_HARQ_t));
ulsch->harq_processes[i] = NULL;
}
}
free16(ulsch,sizeof(NR_gNB_ULSCH_t));
ulsch = NULL;
}
}
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag)
{
NR_gNB_ULSCH_t *ulsch;
uint8_t exit_flag = 0,i,r;
unsigned char bw_scaling =1;
switch (N_RB_UL) {
case 106:
bw_scaling =2;
break;
default:
bw_scaling =1;
break;
}
ulsch = (NR_gNB_ULSCH_t *)malloc16(sizeof(NR_gNB_ULSCH_t));
if (ulsch) {
memset(ulsch,0,sizeof(NR_gNB_ULSCH_t));
ulsch->max_ldpc_iterations = max_ldpc_iterations;
ulsch->Mlimit = 4;
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
ulsch->harq_processes[i] = (NR_UL_gNB_HARQ_t *)malloc16(sizeof(NR_UL_gNB_HARQ_t));
if (ulsch->harq_processes[i]) {
memset(ulsch->harq_processes[i],0,sizeof(NR_UL_gNB_HARQ_t));
ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
if (ulsch->harq_processes[i]->b)
memset(ulsch->harq_processes[i]->b,0,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
else
exit_flag=3;
if (abstraction_flag == 0) {
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling; r++) {
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448*sizeof(uint8_t));
if (ulsch->harq_processes[i]->c[r])
memset(ulsch->harq_processes[i]->c[r],0,8448*sizeof(uint8_t));
else
exit_flag=2;
ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16((68*384)*sizeof(int16_t));
if (ulsch->harq_processes[i]->d[r])
memset(ulsch->harq_processes[i]->d[r],0,(68*384)*sizeof(int16_t));
else
exit_flag=2;
}
}
} else {
exit_flag=1;
}
}
if (exit_flag==0)
return(ulsch);
}
printf("new_gNB_ulsch with size %zu: exit_flag = %u\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag);
free_gNB_ulsch(ulsch);
return(NULL);
}
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint16_t nb_symb_sch,
uint8_t nr_tti_rx,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t llr8_flag)
{
uint32_t A,E;
uint32_t G;
uint32_t ret,offset;
int32_t no_iteration_ldpc, length_dec;
uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
uint8_t crc_type;
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15;
t_nrLDPC_dec_params decParams;
t_nrLDPC_dec_params* p_decParams = &decParams;
t_nrLDPC_time_stats procTime;
t_nrLDPC_time_stats* p_procTime = &procTime ;
t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
int16_t z [68*384];
int8_t l [68*384];
int16_t inv_d [68*384];
uint8_t kc;
uint8_t Ilbrm = 0;
uint32_t Tbslbrm = 950984;
uint16_t nb_rb = 30; //to update
uint8_t nb_re_dmrs = 6;
uint16_t length_dmrs = 1;
double Coderate = 0.0;
uint32_t i,j;
__m128i *pv = (__m128i*)&z;
__m128i *pl = (__m128i*)&l;
if (!ulsch_llr) {
printf("ulsch_decoding.c: NULL ulsch_llr pointer\n");
return(ulsch->max_ldpc_iterations);
}
if (!harq_process) {
printf("ulsch_decoding.c: NULL harq_process pointer\n");
return(ulsch->max_ldpc_iterations);
}
if (!frame_parms) {
printf("ulsch_decoding.c: NULL frame_parms pointer\n");
return(ulsch->max_ldpc_iterations);
}
nb_rb = nfapi_ulsch_pdu_rel15->number_rbs;
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
harq_process->TBS = nr_compute_tbs(nfapi_ulsch_pdu_rel15->mcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->n_layers);
A = harq_process->TBS;
ret = ulsch->max_ldpc_iterations;
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->Qm,nfapi_ulsch_pdu_rel15->n_layers);
G = harq_process->G;
LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nfapi_ulsch_pdu_rel15->mcs, nfapi_ulsch_pdu_rel15->n_layers, nb_symb_sch,nb_rb);
if (harq_process->round == 0) {
// This is a new packet, so compute quantities regarding segmentation
harq_process->B = A+24;
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
nr_segmentation(NULL,
NULL,
harq_process->B,
&harq_process->C,
&harq_process->K,
&harq_process->Z, // [hna] Z is Zc
&harq_process->F);
p_decParams->Z = harq_process->Z;
#ifdef DEBUG_ULSCH_DECODING
printf("ulsch decoding nr segmentation Z %d\n", p_decParams->Z);
if (!frame%100)
printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
#endif
}
Coderate = (float) A /(float) G;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
p_decParams->BG = 2;
if (Coderate < 0.3333) {
p_decParams->R = 15;
kc = 52;
}
else if (Coderate <0.6667) {
p_decParams->R = 13;
kc = 32;
}
else {
p_decParams->R = 23;
kc = 17;
}
} else {
p_decParams->BG = 1;
if (Coderate < 0.6667) {
p_decParams->R = 13;
kc = 68;
}
else if (Coderate <0.8889) {
p_decParams->R = 23;
kc = 35;
}
else {
p_decParams->R = 89;
kc = 27;
}
}
//printf("coderate %f kc %d \n", Coderate, kc);
p_decParams->numMaxIter = ulsch->max_ldpc_iterations;
p_decParams->outMode= 0;
err_flag = 0;
r_offset = 0;
unsigned char bw_scaling =1;
switch (frame_parms->N_RB_UL) {
case 106:
bw_scaling =2;
break;
default:
bw_scaling =1;
break;
}
if (harq_process->C > MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling) {
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling);
return((1+ulsch->max_ldpc_iterations));
}
#ifdef DEBUG_ULSCH_DECODING
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
#endif
opp_enabled=1;
Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb"
Kr_bytes = Kr>>3;
K_bytes_F = Kr_bytes-(harq_process->F>>3);
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, nfapi_ulsch_pdu_rel15->n_layers);
for (r=0; r<harq_process->C; r++) {
E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r);
#if gNB_TIMING_TRACE
start_meas(ulsch_deinterleaving_stats);
#endif
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////// ulsch_llr =====> harq_process->e //////////////////////////////
nr_deinterleaving_ldpc(E,
nfapi_ulsch_pdu_rel15->Qm,
harq_process->e[r],
ulsch_llr+r_offset);
//for (int i =0; i<16; i++)
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
#if gNB_TIMING_TRACE
stop_meas(ulsch_deinterleaving_stats);
#endif
#if gNB_TIMING_TRACE
start_meas(ulsch_rate_unmatching_stats);
#endif
#ifdef DEBUG_ULSCH_DECODING
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
harq_pid,r, G,
Kr*3,
harq_process->TBS,
nfapi_ulsch_pdu_rel15->Qm,
nfapi_ulsch_pdu_rel15->number_rbs,
nfapi_ulsch_pdu_rel15->n_layers,
nfapi_ulsch_pdu_rel15->rv,
harq_process->round);
#endif
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
p_decParams->BG,
p_decParams->Z,
harq_process->d[r],
harq_process->e[r],
harq_process->C,
nfapi_ulsch_pdu_rel15->rv,
(harq_process->round==0)?1:0,
E)==-1) {
#if gNB_TIMING_TRACE
stop_meas(ulsch_rate_unmatching_stats);
#endif
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
return(ulsch->max_ldpc_iterations);
} else {
#if gNB_TIMING_TRACE
stop_meas(ulsch_rate_unmatching_stats);
#endif
}
r_offset += E;
#ifdef DEBUG_ULSCH_DECODING
if (r==0) {
write_output("decoder_llr.m","decllr",ulsch_llr,G,1,0);
write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0);
}
printf("decoder input(segment %d) :",r);
int i;
for (i=0;i<(3*8*Kr_bytes)+12;i++)
printf("%d : %d\n",i,harq_process->d[r][i]);
printf("\n");
#endif
// printf("Clearing c, %p\n",harq_process->c[r]);
memset(harq_process->c[r],0,Kr_bytes);
// printf("done\n");
if (harq_process->C == 1) {
crc_type = CRC24_A;
length_dec = harq_process->B;
}
else {
crc_type = CRC24_B;
length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
}
if (err_flag == 0) {
#if gNB_TIMING_TRACE
start_meas(ulsch_turbo_decoding_stats);
#endif
//LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A);
memset(pv,0,2*harq_process->Z*sizeof(int16_t));
memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
}
for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
}
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) {
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
(int8_t*)&pl[0],
llrProcBuf,
p_nrLDPC_procBuf[r],
p_procTime);
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
printf("Segment %d CRC OK\n",r);
ret = 2;
} else {
printf("CRC NOK\n");
ret = 1+ulsch->max_ldpc_iterations;
}
nb_total_decod++;
if (no_iteration_ldpc > ulsch->max_ldpc_iterations){
nb_error_decod++;
}
ret=no_iteration_ldpc;
for (int m=0; m < Kr>>3; m ++) {
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
}
#ifdef DEBUG_ULSCH_DECODING
//printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
for (int k=0;k<A>>3;k++)
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret);
//write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
#endif
#if gNB_TIMING_TRACE
stop_meas(ulsch_turbo_decoding_stats);
#endif
}
if ((err_flag == 0) && (ret>=(1+ulsch->max_ldpc_iterations))) {
// a Code segment is in error so break;
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
err_flag = 1;
}
//////////////////////////////////////////////////////////////////////////////////////////
}
int32_t frame_rx_prev = frame;
int32_t tti_rx_prev = nr_tti_rx - 1;
if (tti_rx_prev < 0) {
frame_rx_prev--;
tti_rx_prev += 10*frame_parms->ttis_per_subframe;
}
frame_rx_prev = frame_rx_prev%1024;
if (err_flag == 1) {
#if gNB_DEBUG_TRACE
LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
#endif
// harq_process->harq_ack.ack = 0;
// harq_process->harq_ack.harq_id = harq_pid;
// harq_process->harq_ack.send_harq_status = 1;
// harq_process->errors[harq_process->round]++;
harq_process->round++;
if (harq_process->round >= ulsch->Mlimit) {
harq_process->status = SCH_IDLE;
harq_process->round = 0;
harq_process->handled = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
}
if(is_crnti) {
LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
}
harq_process->handled = 1;
return((1+ulsch->max_ldpc_iterations));
} else {
#if gNB_DEBUG_TRACE
LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
#endif
harq_process->status = SCH_IDLE;
harq_process->round = 0;
// harq_process->handled = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
// harq_process->harq_ack.ack = 1;
// harq_process->harq_ack.harq_id = harq_pid;
// harq_process->harq_ack.send_harq_status = 1;
if(is_crnti)
{
LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
}
}
// Reassembly of Transport block here
offset = 0;
Kr = harq_process->K;
Kr_bytes = Kr>>3;
for (r=0; r<harq_process->C; r++) {
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));
#ifdef DEBUG_ULSCH_DECODING
printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes);
printf("copied %d bytes to b sequence (harq_pid %d)\n",
(Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
printf("b[0] = %x,c[%d] = %x\n",
harq_process->b[offset],
harq_process->F>>3,
harq_process->c[r]);
#endif
}
ulsch->last_iteration_cnt = ret;
return(ret);
}
@@ -52,9 +52,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
ncoef = 32767 - coef;
//#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d.%d: rx_offset (before) = %d\n",ue->proc.proc_rxtx[0].frame_rx%1024,subframe,ue->rx_offset);
//#endif //DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset);
// we only use channel estimates from tx antenna 0 here
@@ -122,8 +120,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d.%d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n",
ue->proc.proc_rxtx[ue->current_thread_id[subframe]].frame_rx,
LOG_D(PHY,"AbsSubframe %d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n",
subframe,
ue->current_thread_id[subframe],
diff,
@@ -29,47 +29,37 @@
#include "filt16a_32.h"
#include "T.h"
//#define DEBUG_PDSCH
//#define DEBUG_PDCCH
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id,
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
uint8_t eNB_offset,
unsigned char Ns,
unsigned char l,
unsigned char symbol)
unsigned char symbol,
int dmrss,
NR_UE_SSB *current_ssb)
{
int pilot[200] __attribute__((aligned(16)));
unsigned char aarx;
unsigned short k;
unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
int ch_offset,symbol_offset;
int dmrss;
int16_t ch[2],*pil,*rxF;
int symbol_offset;
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
uint8_t nushift, ssb_index=0, n_hf=0;
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
uint8_t nushift;
uint8_t ssb_index=current_ssb->i_ssb;
uint8_t n_hf=current_ssb->n_hf;
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
nushift = ue->frame_parms.Nid_cell%4;
ue->frame_parms.nushift = nushift;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
if (ue->is_synchronized ==0 ) dmrss = symbol-1;
else dmrss = symbol-5;
if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
ch_offset = ue->frame_parms.ofdm_symbol_size ;
else
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
AssertFatal((symbol > 0 && symbol < 4 && ue->is_synchronized == 0) ||
(symbol > 4 && symbol < 8 && ue->is_synchronized == 1),
"symbol %d is illegal for PBCH DM-RS (is_synchronized %d)\n",
symbol,ue->is_synchronized);
AssertFatal(dmrss >= 0 && dmrss < 3,
"symbol %d is illegal for PBCH DM-RS \n",
dmrss);
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
@@ -77,8 +67,175 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
k = nushift;
#ifdef DEBUG_CH
printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,l,Ns,k, symbol);
printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,Ns,k, symbol);
#endif
// generate pilot
nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
int re_offset = ssb_offset;
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
#ifdef DEBUG_CH
printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
printf("rxF addr %p\n", rxF);
#endif
//if ((ue->frame_parms.N_RB_DL&1)==0) {
// Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re +=ch[0];
current_ssb->c_im +=ch[1];
#ifdef DEBUG_CH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
pil+=2;
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re +=ch[0];
current_ssb->c_im +=ch[1];
#ifdef DEBUG_CH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
pil+=2;
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
current_ssb->c_re +=ch[0];
current_ssb->c_im +=ch[1];
#ifdef DEBUG_CH
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
pil+=2;
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) {
// if (pilot_cnt == 30)
// rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)];
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
if (dmrss == 1 && pilot_cnt == 12) {
pilot_cnt=48;
re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re +=ch[0];
current_ssb->c_im +=ch[1];
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
pil+=2;
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re +=ch[0];
current_ssb->c_im +=ch[1];
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
pil+=2;
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re +=ch[0];
current_ssb->c_im +=ch[1];
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
pil+=2;
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
}
//}
}
return(0);
}
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_offset,
unsigned char Ns,
unsigned char symbol,
int dmrss,
uint8_t ssb_index,
uint8_t n_hf)
{
int pilot[200] __attribute__((aligned(16)));
unsigned char aarx;
unsigned short k;
unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
int ch_offset,symbol_offset;
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
uint8_t nushift;
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
nushift = ue->frame_parms.Nid_cell%4;
ue->frame_parms.nushift = nushift;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
ch_offset = ue->frame_parms.ofdm_symbol_size ;
else
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
AssertFatal(dmrss >= 0 && dmrss < 3,
"symbol %d is illegal for PBCH DM-RS \n",
dmrss);
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
k = nushift;
#ifdef DEBUG_CH
printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,Ns,k, symbol);
#endif
switch (k) {
@@ -121,7 +278,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
@@ -138,6 +295,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
// Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
@@ -155,6 +313,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
@@ -166,9 +326,6 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
@@ -196,6 +353,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
@@ -214,6 +372,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
@@ -248,12 +407,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
//}
}
return(0);
}
int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id,
uint8_t eNB_offset,
unsigned char Ns,
unsigned char l,
@@ -271,8 +428,8 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
uint8_t nushift;
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
nushift = 1;
ue->frame_parms.nushift = nushift;
@@ -287,7 +444,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
k = coreset_start_subcarrier;
#ifdef DEBUG_PDCCH
printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,l,Ns,k, symbol);
#endif
@@ -459,16 +616,16 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
break;
}
if( (Ns== 2) && (l == 0))
if( (Ns== 1) && (l == 0))
{
// do ifft of channel estimate
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
{
LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns>>1], l);
idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][0],
(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], l);
idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][0],
(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
}
}
}
@@ -477,7 +634,6 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
}
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id,
uint8_t eNB_offset,
unsigned char Ns,
unsigned short p,
@@ -496,8 +652,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
uint8_t nushift;
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset];
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
nushift = (p>>1)&1;
ue->frame_parms.nushift = nushift;
+16 -9
View File
@@ -43,7 +43,6 @@
\param symbol symbol within frame
*/
int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id,
uint8_t eNB_offset,
unsigned char Ns,
unsigned char l,
@@ -51,22 +50,30 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned short coreset_start_subcarrier,
unsigned short nb_rb_coreset);
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
uint8_t eNB_offset,
unsigned char Ns,
unsigned char symbol,
int dmrss,
NR_UE_SSB *current_ssb);
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id,
uint8_t eNB_offset,
unsigned char Ns,
unsigned char l,
unsigned char symbol);
uint8_t eNB_offset,
unsigned char Ns,
unsigned char symbol,
int dmrss,
uint8_t ssb_index,
uint8_t n_hf);
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t eNB_id,
uint8_t eNB_offset,
unsigned char Ns,
unsigned short p,
unsigned char l,
unsigned char symbol,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch);
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch);
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
+865 -775
View File
File diff suppressed because it is too large Load Diff
+14 -33
View File
@@ -52,7 +52,7 @@
//#define DEBUG_DCI
#define NR_PDCCH_DCI_TOOLS
#define NR_PDCCH_DCI_TOOLS_DEBUG
//#define NR_PDCCH_DCI_TOOLS_DEBUG
typedef unsigned __int128 uint128_t;
@@ -64,17 +64,10 @@ int8_t *nr_delta_PUCCH_lut = nr_delta_PUSCH_acc;
#ifdef NR_PDCCH_DCI_TOOLS
uint16_t nr_dci_field(uint32_t dci_pdu[4],
uint16_t nr_dci_field(uint64_t dci_pdu[2],
uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS],
uint8_t dci_field)
{
// uint16_t field_value = 0 ;
// first_bit_position contains the position of the first bit of the corresponding field within the dci pdu payload
// last_bit_position contains the position of the last bit of the corresponding field within the dci pdu payload
// uint16_t last_bit_position = 0;
// uint8_t bit=0;
//printf("\tdci_field=%d, \tsize=%d \t|",dci_field,dci_fields_sizes[dci_field]);
int dci_size=0;
for (int i=0;i<NBR_NR_DCI_FIELDS;i++) dci_size+=dci_fields_sizes[i];
@@ -87,25 +80,13 @@ uint16_t nr_dci_field(uint32_t dci_pdu[4],
for (int i=0; i<=dci_field ; i++){
first_bit_position = first_bit_position - dci_fields_sizes[i];
}
// last_bit_position = first_bit_position + dci_fields_sizes[dci_field];
//printf("\tfirst_bit=%d,\tlast_bit=%d",first_bit_position,last_bit_position);
/*
for (int i=0; i<4; i++)
for (int j=0; j<32; j++){
if ((((i*32)+j) >= first_bit_position) && (((i*32)+j) < last_bit_position)){
bit = (dci_pdu[i]<<(31-j))>>31;
field_value = (field_value<<1) + bit;
//printf(" bit(%d)=%d[%d] ",(i*32)+j,bit,field_value);
}
}
*/
uint64_t *dci_pdu64=(uint64_t*)&dci_pdu[0];
/*
printf("pdu %llx, field %d, pos %d, size %d => %u\n",(long long unsigned int)*dci_pdu64,dci_field,first_bit_position,dci_fields_sizes[dci_field],
(unsigned int)((*dci_pdu64>>first_bit_position)&((1<<dci_fields_sizes[dci_field])-1)));*/
/*uint16_t tmp1 = ((*dci_pdu>>first_bit_position)&((1<<dci_fields_sizes[dci_field])-1));
uint16_t tmp2 = 0;
for (int i=0; i<dci_fields_sizes[dci_field]; i++)
tmp2 |= ((tmp1>>i)&1)<<(dci_fields_sizes[dci_field]-i-1);*/
return (uint16_t)((*dci_pdu64>>first_bit_position)&((1<<dci_fields_sizes[dci_field])-1));
return ((uint16_t)(*dci_pdu>>first_bit_position)&((1<<dci_fields_sizes[dci_field])-1));
}
int nr_extract_dci_info(PHY_VARS_NR_UE *ue,
@@ -113,7 +94,7 @@ int nr_extract_dci_info(PHY_VARS_NR_UE *ue,
lte_frame_type_t frame_type,
uint8_t dci_length,
uint16_t rnti,
uint32_t dci_pdu[4],
uint64_t dci_pdu[2],
NR_DCI_INFO_EXTRACTED_t *nr_pdci_info_extracted,
uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS],
NR_DL_UE_HARQ_t *pdlsch0_harq,
@@ -125,7 +106,7 @@ int nr_extract_dci_info(PHY_VARS_NR_UE *ue,
uint16_t n_RB_DLBWP,
uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES])
{
/*
* This function will extract the different elements of the dci pdu and interpret the values extracted to update correctly the parameters in:
* NR_DL_UE_HARQ_t *pdlsch0_harq,
@@ -312,8 +293,8 @@ int nr_extract_dci_info(PHY_VARS_NR_UE *ue,
// uint8_t sizes_count=0;
// uint8_t left_shift=0;
#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> Entering function nr_extract_dci_info() with dci_pdu=%x %x %x %x dci_length=%d\n",
dci_pdu[0],dci_pdu[1],dci_pdu[2],dci_pdu[3], dci_length);
printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> Entering function nr_extract_dci_info() with dci_pdu=%lx %lx dci_length=%d\n",
dci_pdu[0],dci_pdu[1], dci_length);
printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> for format %d, dci_fields_sizes {",dci_format);
for (int i=0; i<NBR_NR_DCI_FIELDS; i++) printf("%d ",dci_fields_sizes[i][dci_format]);
printf("}\n");
@@ -1040,7 +1021,7 @@ int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue,
uint8_t eNB_id,
int frame,
uint8_t nr_tti_rx,
uint32_t dci_pdu[4],
uint64_t dci_pdu[2],
uint16_t rnti,
uint8_t dci_length,
NR_DCI_format_t dci_format,
@@ -1074,8 +1055,8 @@ int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue,
uint8_t status=0;
#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> dci_format=%d, rnti=%d, dci_length=%d, dci_pdu[0]=%x, dci_pdu[2]=%x, dci_pdu[2]=%x, dci_pdu[3]=%x\n",
dci_format,rnti,dci_length,dci_pdu[0],dci_pdu[1],dci_pdu[2],dci_pdu[3]);
printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> dci_format=%d, rnti=%d, dci_length=%d, dci_pdu[0]=0x%lx, dci_pdu[1]=0x%lx\n",
dci_format,rnti,dci_length,dci_pdu[0],dci_pdu[1]);
#endif
File diff suppressed because it is too large Load Diff
@@ -203,14 +203,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#endif
}
else {
LOG_E(PHY,"[UE][FATAL] Frame %d nr_tti_rx %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,nr_tti_rx);
LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n",nr_tti_rx);
return(-1);
}
beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id];
break;
default:
LOG_E(PHY,"[UE][FATAL] Frame %d nr_tti_rx %d: Unknown PDSCH format %d\n",ue->proc.proc_rxtx[0].frame_rx,nr_tti_rx,type);
LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n",nr_tti_rx,type);
return(-1);
break;
}
@@ -1350,7 +1350,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
unsigned char aatx,aarx,pilots=0;
__m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128;
__m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
QAM_amp128b = _mm_setzero_si128();
if (symbol == 2){
pilots=1;
+174 -102
View File
@@ -35,10 +35,12 @@
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "nr_transport_proto_ue.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
//#include "SCHED/defs.h"
//#include "SCHED/extern.h"
#include "common_lib.h"
#include <math.h>
#include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/sss_nr.h"
@@ -51,59 +53,126 @@ int cnt=0;
#define DEBUG_INITIAL_SYNCH
int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode)
// create a new node of SSB structure
NR_UE_SSB* create_ssb_node(uint8_t i, uint8_t h) {
NR_UE_SSB *new_node = (NR_UE_SSB*)malloc(sizeof(NR_UE_SSB));
new_node->i_ssb = i;
new_node->n_hf = h;
new_node->c_re = 0;
new_node->c_im = 0;
new_node->metric = 0;
new_node->next_ssb = NULL;
return new_node;
}
// insertion of the structure in the ordered list (highest metric first)
NR_UE_SSB* insert_into_list(NR_UE_SSB *head, NR_UE_SSB *node) {
if (node->metric > head->metric) {
node->next_ssb = head;
head = node;
return head;
}
NR_UE_SSB *current = head;
while (current->next_ssb !=NULL) {
NR_UE_SSB *temp=current->next_ssb;
if(node->metric > temp->metric) {
node->next_ssb = temp;
current->next_ssb = node;
return head;
}
else
current = temp;
}
current->next_ssb = node;
return head;
}
void free_list(NR_UE_SSB *node) {
if (node->next_ssb != NULL)
free_list(node->next_ssb);
free(node);
}
int nr_pbch_detection(PHY_VARS_NR_UE *ue, int pbch_initial_symbol, runmode_t mode)
{
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
int ret =-1;
NR_UE_SSB *best_ssb = NULL;
NR_UE_SSB *current_ssb;
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
ue->rx_offset);
#endif
// save the nb_prefix_samples0 since we are not synchronized to subframes yet and the SSB has all symbols with nb_prefix_samples
int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples;
uint8_t N_L = (frame_parms->Lmax == 4)? 4:8;
uint8_t N_hf = (frame_parms->Lmax == 4)? 2:1;
//symbol 1
nr_slot_fep(ue,
1,
0,
ue->ssb_offset,
0,
1,
NR_PBCH_EST);
//symbol 2
nr_slot_fep(ue,
2,
0,
ue->ssb_offset,
0,
1,
NR_PBCH_EST);
// loops over possible pbch dmrs cases to retrive best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection
for (int hf = 0; hf < N_hf; hf++) {
for (int l = 0; l < N_L ; l++) {
//symbol 3
nr_slot_fep(ue,
3,
0,
ue->ssb_offset,
0,
1,
NR_PBCH_EST);
// initialization of structure
current_ssb = create_ssb_node(l,hf);
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats);
#endif
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
nr_pbch_dmrs_correlation(ue,0,0,i,i-pbch_initial_symbol,current_ssb);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats);
#endif
current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im+current_ssb->c_re;
// generate a list of SSB structures
if (best_ssb == NULL)
best_ssb = current_ssb;
else
best_ssb = insert_into_list(best_ssb,current_ssb);
}
}
NR_UE_SSB *temp_ptr=best_ssb;
while (ret!=0 && temp_ptr != NULL) {
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats);
#endif
// computing channel estimation for selected best ssb
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
nr_pbch_channel_estimation(ue,0,0,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats);
#endif
ret = nr_rx_pbch(ue,
0,
ue->pbch_vars[0],
frame_parms,
0,
temp_ptr->i_ssb,
SISO,
ue->high_speed_flag);
temp_ptr=temp_ptr->next_ssb;
}
free_list(best_ssb);
//put back nb_prefix_samples0
frame_parms->nb_prefix_samples0 = nb_prefix_samples0;
ret = nr_rx_pbch(ue,
&ue->proc.proc_rxtx[0],
ue->pbch_vars[0],
frame_parms,
0,
SISO,
ue->high_speed_flag);
if (ret==0) {
@@ -119,11 +188,6 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode)
// ue->pbch_vars[0]->decoded_output[0] = ue->pbch_vars[0]->decoded_output[2];
// ue->pbch_vars[0]->decoded_output[2] = dummy;
for(int i=0; i<RX_NB_TH;i++)
{
ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx;
}
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id);
#endif
@@ -140,9 +204,10 @@ char prefix_string[2][9] = {"NORMAL","EXTENDED"};
int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
{
int32_t sync_pos, sync_pos_slot; // k_ssb, N_ssb_crb, sync_pos2,
int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2,
int32_t metric_tdd_ncp=0;
uint8_t phase_tdd_ncp;
double im, re;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
int ret=-1;
@@ -182,25 +247,58 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
/* process pss search on received buffer */
sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE);
sync_pos_slot = (fp->samples_per_subframe/fp->slots_per_subframe) - 10*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
if (sync_pos >= fp->nb_prefix_samples){
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;}
else{
ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples;}
ue->rx_offset = ue->ssb_offset - sync_pos_slot;
if (sync_pos >= fp->nb_prefix_samples)
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
else
ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples;
//write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos,ue->common_vars.eNb_id);
LOG_I(PHY,"sync_pos %d ssb_offset %d sync_pos_slot %d \n",sync_pos,ue->ssb_offset,sync_pos_slot);
LOG_I(PHY,"sync_pos %d ssb_offset %d \n",sync_pos,ue->ssb_offset);
#endif
// digital compensation of FFO for SSB symbols
if (ue->UE_fo_compensation){
double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample
int start = ue->ssb_offset; // start for offset correction is at ssb_offset (pss time position)
int end = start + 4*(fp->ofdm_symbol_size + fp->nb_prefix_samples); // loop over samples in 4 symbols (ssb size), including prefix
for(int n=start; n<end; n++){
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]);
im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]);
((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle)));
((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
}
}
}
/* check that SSS/PBCH block is continuous inside the received buffer */
if (sync_pos < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe - (NB_SYMBOLS_PBCH * fp->ofdm_symbol_size))) {
/* slop_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
/* for NR this is not the case but slot_fep is still used for computing FFT of samples */
/* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
/* symbol number are from beginning of SS/PBCH blocks as below: */
/* Signal PSS PBCH SSS PBCH */
/* symbol number 0 1 2 3 */
/* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
for(int i=0; i<4;i++)
nr_slot_fep(ue,
i,
0,
ue->ssb_offset,
0,
NR_PBCH_EST);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"Calling sss detection (normal CP)\n");
#endif
@@ -211,15 +309,22 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
//nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0);
nr_gold_pbch(ue);
ret = nr_pbch_detection(ue,mode);
ret = nr_pbch_detection(ue,1,mode); // start pbch detection at first symbol after pss
if (ret == 0) {
// sync at symbol ue->symbol_offset
// computing the offset wrt the beginning of the frame
sync_pos_frame = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)+((ue->symbol_offset)-1)*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
ue->rx_offset = ue->ssb_offset - sync_pos_frame;
}
nr_gold_pdcch(ue,0, 2);
/*
int nb_prefix_samples0 = fp->nb_prefix_samples0;
fp->nb_prefix_samples0 = fp->nb_prefix_samples;
nr_slot_fep(ue,0, 0, ue->ssb_offset, 0, 1, NR_PDCCH_EST);
nr_slot_fep(ue,1, 0, ue->ssb_offset, 0, 1, NR_PDCCH_EST);
nr_slot_fep(ue,0, 0, ue->ssb_offset, 0, NR_PDCCH_EST);
nr_slot_fep(ue,1, 0, ue->ssb_offset, 0, NR_PDCCH_EST);
fp->nb_prefix_samples0 = nb_prefix_samples0;
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
@@ -236,7 +341,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
}
else {
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot);
LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos);
#endif
}
}
@@ -244,7 +349,8 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
ret = -1;
}
/* Consider this is a false detection if the offset is > 1000 Hz */
/* Consider this is a false detection if the offset is > 1000 Hz
Not to be used now that offest estimation is in place
if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) )
{
ret=-1;
@@ -253,7 +359,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
#else
LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
#endif
}
}*/
if (ret==0) { // PBCH found so indicate sync to higher layers and configure frame parameters
@@ -268,9 +374,8 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
if (ue->UE_scan_carrier == 0) {
#if UE_AUTOTEST_TRACE
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : rx_offset %d, freq_offset %d \n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
ue->rx_offset,
ue->common_vars.freq_offset );
#endif
@@ -281,30 +386,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
}
#if DISABLE_LOG_X
printf("[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
10*log10(ue->measurements.rssi),
ue->rx_total_gain_dB,
ue->measurements.n0_power_tot_dBm,
10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB,
(10*log10(ue->measurements.rsrq[0])));
printf("[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
duplex_string[fp->frame_type],
prefix_string[fp->Ncp],
fp->Nid_cell,
fp->N_RB_DL,
fp->phich_config_common.phich_duration,
phich_string[fp->phich_config_common.phich_resource],
fp->nb_antenna_ports_eNB);
#else
LOG_I(PHY, "[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
LOG_I(PHY, "[UE %d] RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
10*log10(ue->measurements.rssi),
ue->rx_total_gain_dB,
@@ -322,22 +404,12 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
fp->phich_config_common.phich_duration,
phich_string[fp->phich_config_common.phich_resource],
fp->nb_antenna_ports_eNB);*/
#endif
#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
# if DISABLE_LOG_X
printf("[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
LOG_I(PHY, "[UE %d] Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset,
openair0_cfg[0].rx_freq[0]+ue->common_vars.freq_offset,
ue->common_vars.freq_offset);
# else
LOG_I(PHY, "[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset,
ue->common_vars.freq_offset);
# endif
#endif
} else {
#ifdef DEBUG_INITIAL_SYNC
+256 -380
View File
@@ -34,12 +34,13 @@
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/sse_intrin.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "PHY/INIT/phy_init.h"
//#define DEBUG_PBCH 1
//#define DEBUG_PBCH_ENCODING
#ifdef OPENAIR2
//#include "PHY_INTERFACE/defs.h"
//#include "PHY_INTERFACE/defs.h"
#endif
#define PBCH_A 24
@@ -47,42 +48,39 @@
#define print_shorts(s,x) printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,((int16_t*)x)[0],((int16_t*)x)[1],((int16_t*)x)[2],((int16_t*)x)[3],((int16_t*)x)[4],((int16_t*)x)[5],((int16_t*)x)[6],((int16_t*)x)[7])
uint16_t nr_pbch_extract(int **rxdataF,
int **dl_ch_estimates,
int **rxdataF_ext,
int **dl_ch_estimates_ext,
uint32_t symbol,
uint32_t s_offset,
uint32_t high_speed_flag,
NR_DL_FRAME_PARMS *frame_parms)
{
int **dl_ch_estimates,
int **rxdataF_ext,
int **dl_ch_estimates_ext,
uint32_t symbol,
uint32_t s_offset,
uint32_t high_speed_flag,
NR_DL_FRAME_PARMS *frame_parms) {
uint16_t rb;
uint8_t i,j,aarx;
int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
int nushiftmod4 = frame_parms->nushift;
unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; //and
if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size;
AssertFatal(symbol>=1 && symbol<5,
"symbol %d illegal for PBCH extraction\n",
symbol);
AssertFatal(symbol>=1 && symbol<5,
"symbol %d illegal for PBCH extraction\n",
symbol);
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size];
rxF_ext = &rxdataF_ext[aarx][symbol*20*12];
#ifdef DEBUG_PBCH
printf("extract_rbs (nushift %d): rx_offset=%d, symbol %d\n",frame_parms->nushift,
(rx_offset + ((symbol+s_offset)*(frame_parms->ofdm_symbol_size))),symbol);
int16_t *p = (int16_t *)rxF;
for (int i =0; i<8;i++){
printf("rxF [%d]= %d\n",i,rxF[i]);
printf("pbch extract rxF %d %d addr %p\n", p[2*i], p[2*i+1], &p[2*i]);
printf("rxF ext addr %p\n", &rxF_ext[i]);
}
printf("extract_rbs (nushift %d): rx_offset=%d, symbol %d\n",frame_parms->nushift,
(rx_offset + ((symbol+s_offset)*(frame_parms->ofdm_symbol_size))),symbol);
int16_t *p = (int16_t *)rxF;
for (int i =0; i<8; i++) {
printf("rxF [%d]= %d\n",i,rxF[i]);
printf("pbch extract rxF %d %d addr %p\n", p[2*i], p[2*i+1], &p[2*i]);
printf("rxF ext addr %p\n", &rxF_ext[i]);
}
#endif
for (rb=0; rb<20; rb++) {
@@ -95,41 +93,43 @@ uint16_t nr_pbch_extract(int **rxdataF,
(i!=(nushiftmod4+8))) {
rxF_ext[j]=rxF[rx_offset];
#ifdef DEBUG_PBCH
printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(9*rb) + j,
((int16_t*)&rxF_ext[j])[0],
((int16_t*)&rxF_ext[j])[1],
rx_offset,
((int16_t*)&rxF[rx_offset])[0],
((int16_t*)&rxF[rx_offset])[1]);
printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(9*rb) + j,
((int16_t *)&rxF_ext[j])[0],
((int16_t *)&rxF_ext[j])[1],
rx_offset,
((int16_t *)&rxF[rx_offset])[0],
((int16_t *)&rxF[rx_offset])[1]);
#endif
j++;
j++;
}
rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
}
rxF_ext+=9;
} else { //symbol 2
if ((rb < 4) || (rb >15)){
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) {
rxF_ext[j]=rxF[rx_offset];
if ((rb < 4) || (rb >15)) {
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) {
rxF_ext[j]=rxF[rx_offset];
#ifdef DEBUG_PBCH
printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(rb<4) ? (9*rb) + j : (9*(rb-12))+j,
((int16_t*)&rxF_ext[j])[0],
((int16_t*)&rxF_ext[j])[1],
rx_offset,
((int16_t*)&rxF[rx_offset])[0],
((int16_t*)&rxF[rx_offset])[1]);
#endif
j++;
}
rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
}
rxF_ext+=9;
}
else rx_offset = (rx_offset+12)&(frame_parms->ofdm_symbol_size-1);
printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(rb<4) ? (9*rb) + j : (9*(rb-12))+j,
((int16_t *)&rxF_ext[j])[0],
((int16_t *)&rxF_ext[j])[1],
rx_offset,
((int16_t *)&rxF[rx_offset])[0],
((int16_t *)&rxF[rx_offset])[1]);
#endif
j++;
}
rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
}
rxF_ext+=9;
} else rx_offset = (rx_offset+12)&(frame_parms->ofdm_symbol_size-1);
}
}
@@ -137,56 +137,59 @@ uint16_t nr_pbch_extract(int **rxdataF,
dl_ch0 = &dl_ch_estimates[aarx][((symbol+s_offset)*(frame_parms->ofdm_symbol_size))];
else
dl_ch0 = &dl_ch_estimates[aarx][0];
//printf("dl_ch0 addr %p\n",dl_ch0);
dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*20*12];
for (rb=0; rb<20; rb++) {
j=0;
if (symbol==1 || symbol==3) {
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) {
dl_ch0_ext[j]=dl_ch0[i];
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) {
dl_ch0_ext[j]=dl_ch0[i];
#ifdef DEBUG_PBCH
if ((rb==0) && (i<2))
printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j,
((int16_t*)&dl_ch0_ext[j])[0],
((int16_t*)&dl_ch0_ext[j])[1],
i,
((int16_t*)&dl_ch0[i])[0],
((int16_t*)&dl_ch0[i])[1]);
if ((rb==0) && (i<2))
printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j,
((int16_t *)&dl_ch0_ext[j])[0],
((int16_t *)&dl_ch0_ext[j])[1],
i,
((int16_t *)&dl_ch0[i])[0],
((int16_t *)&dl_ch0[i])[1]);
#endif
j++;
}
}
dl_ch0+=12;
dl_ch0_ext+=9;
}
else {
if ((rb < 4) || (rb >15)){
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) {
dl_ch0_ext[j]=dl_ch0[i];
j++;
}
}
dl_ch0+=12;
dl_ch0_ext+=9;
} else {
if ((rb < 4) || (rb >15)) {
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) {
dl_ch0_ext[j]=dl_ch0[i];
#ifdef DEBUG_PBCH
printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j,
((int16_t*)&dl_ch0_ext[j])[0],
((int16_t*)&dl_ch0_ext[j])[1],
i,
((int16_t*)&dl_ch0[i])[0],
((int16_t*)&dl_ch0[i])[1]);
printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j,
((int16_t *)&dl_ch0_ext[j])[0],
((int16_t *)&dl_ch0_ext[j])[1],
i,
((int16_t *)&dl_ch0[i])[0],
((int16_t *)&dl_ch0[i])[1]);
#endif
j++;
}
}
dl_ch0_ext+=9;
}
dl_ch0+=12;
j++;
}
}
dl_ch0_ext+=9;
}
dl_ch0+=12;
}
}
}
@@ -198,13 +201,10 @@ uint16_t nr_pbch_extract(int **rxdataF,
//compute average channel_level on each (TX,RX) antenna pair
int nr_pbch_channel_level(int **dl_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t symbol)
{
NR_DL_FRAME_PARMS *frame_parms,
uint32_t symbol) {
int16_t rb, nb_rb=20;
uint8_t aarx;
#if defined(__x86_64__) || defined(__i386__)
__m128i avg128;
__m128i *dl_ch128;
@@ -216,180 +216,83 @@ int nr_pbch_channel_level(int **dl_ch_estimates_ext,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
//clear average level
#if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_setzero_si128();
dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][symbol*20*12];
#elif defined(__arm__)
avg128 = vdupq_n_s32(0);
dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[aarx][symbol*20*12];
#endif
for (rb=0; rb<nb_rb; rb++) {
#if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
#elif defined(__arm__)
// to be filled in
// to be filled in
#endif
dl_ch128+=3;
/*
if (rb==0) {
print_shorts("dl_ch128",&dl_ch128[0]);
print_shorts("dl_ch128",&dl_ch128[1]);
print_shorts("dl_ch128",&dl_ch128[2]);
}*/
print_shorts("dl_ch128",&dl_ch128[0]);
print_shorts("dl_ch128",&dl_ch128[1]);
print_shorts("dl_ch128",&dl_ch128[2]);
}*/
}
avg1 = (((int*)&avg128)[0] +
((int*)&avg128)[1] +
((int*)&avg128)[2] +
((int*)&avg128)[3])/(nb_rb*12);
avg1 = (((int *)&avg128)[0] +
((int *)&avg128)[1] +
((int *)&avg128)[2] +
((int *)&avg128)[3])/(nb_rb*12);
if (avg1>avg2)
avg2 = avg1;
//LOG_I(PHY,"Channel level : %d, %d\n",avg1, avg2);
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
return(avg2);
}
void nr_pbch_channel_compensation(int **rxdataF_ext,
int **dl_ch_estimates_ext,
int **rxdataF_comp,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t symbol,
uint8_t output_shift)
{
short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
//short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
#if defined(__x86_64__) || defined(__i386__)
__m128i mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#elif defined(__arm__)
int16x8_t mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#endif
uint16_t nb_re=180;
uint8_t aarx;
#if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
#elif defined(__arm__)
#endif
int **dl_ch_estimates_ext,
int **rxdataF_comp,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t symbol,
uint8_t output_shift) {
const uint16_t nb_re=symbol == 2 ? 72 : 180;
AssertFatal((symbol > 0 && symbol < 4),
"symbol %d is illegal for PBCH DM-RS\n",
symbol);
if (symbol == 2) nb_re = 72;
"symbol %d is illegal for PBCH DM-RS\n",
symbol);
// printf("comp: symbol %d : nb_re %d\n",symbol,nb_re);
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
#if defined(__x86_64__) || defined(__i386__)
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*20*12];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*20*12];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[aarx][symbol*20*12];
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
vect128 *dl_ch128 = (vect128 *)&dl_ch_estimates_ext[aarx][symbol*20*12];
vect128 *rxdataF128 = (vect128 *)&rxdataF_ext[aarx][symbol*20*12];
vect128 *rxdataF_comp128 = (vect128 *)&rxdataF_comp[aarx][symbol*20*12];
/*
printf("ch compensation dl_ch ext addr %p \n", &dl_ch_estimates_ext[aarx][symbol*20*12]);
printf("rxdataf ext addr %p symbol %d\n", &rxdataF_ext[aarx][symbol*20*12], symbol);
printf("rxdataf_comp addr %p\n",&rxdataF_comp[aarx][symbol*20*12]);
printf("rxdataf_comp addr %p\n",&rxdataF_comp[aarx][symbol*20*12]);
*/
#elif defined(__arm__)
// to be filled in
#endif
for (int re=0; re<nb_re; re+=12) {
// printf("******re %d\n",re);
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
mmtmpP0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
// print_ints("re",&mmtmpP0);
// mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]);
// print_ints("im",&mmtmpP1);
mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[0]);
// mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
// print_ints("re(shift)",&mmtmpP0);
mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
// print_ints("im(shift)",&mmtmpP1);
mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
// print_ints("c0",&mmtmpP2);
// print_ints("c1",&mmtmpP3);
rxdataF_comp128[0] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
/*
print_shorts("rx:",rxdataF128);
print_shorts("ch:",dl_ch128);
print_shorts("pack:",rxdataF_comp128);
*/
// multiply by conjugated channel
mmtmpP0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
// mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]);
mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[1]);
// mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
rxdataF_comp128[1] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
// print_shorts("rx:",rxdataF128+1);
// print_shorts("ch:",dl_ch128+1);
// print_shorts("pack:",rxdataF_comp128+1);
// multiply by conjugated channel
mmtmpP0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
// mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]);
mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[2]);
// mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
rxdataF_comp128[2] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
// print_shorts("rx:",rxdataF128+2);
// print_shorts("ch:",dl_ch128+2);
// print_shorts("pack:",rxdataF_comp128+2);
dl_ch128+=3;
rxdataF128+=3;
rxdataF_comp128+=3;
#elif defined(__arm__)
// to be filled in
#endif
*rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift);
*rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift);
*rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift);
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
int **rxdataF_comp,
uint8_t symbol)
{
int **rxdataF_comp,
uint8_t symbol) {
uint8_t symbol_mod;
int i, nb_rb=6;
#if defined(__x86_64__) || defined(__i386__)
@@ -401,23 +304,22 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
if (frame_parms->nb_antennas_rx>1) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol_mod*6*12];
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[1][symbol_mod*6*12];
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol_mod*6*12];
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[1][symbol_mod*6*12];
#elif defined(__arm__)
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol_mod*6*12];
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol_mod*6*12];
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol_mod*6*12];
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol_mod*6*12];
#endif
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
for (i=0; i<nb_rb*3; i++) {
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
for (i=0; i<nb_rb*3; i++) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
#elif defined(__arm__)
rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
#endif
}
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
@@ -426,19 +328,16 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
}
void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
uint16_t Nid,
uint8_t nushift,
uint16_t M,
uint16_t length,
uint8_t bitwise,
uint32_t unscrambling_mask)
{
uint16_t Nid,
uint8_t nushift,
uint16_t M,
uint16_t length,
uint8_t bitwise,
uint32_t unscrambling_mask) {
uint8_t reset, offset;
uint32_t x1, x2, s=0;
uint8_t k=0;
int16_t *demod_pbch_e = pbch->llr;
reset = 1;
// x1 is set in first call to lte_gold_generic
x2 = Nid; //this is c_init
@@ -448,48 +347,49 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
// Scrambling is now done with offset (nushift*M)%32
offset = (nushift*M)&0x1f;
for (int i=0; i<length; i++) {
/*if (((i+offset)&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}*/
if (bitwise) {
/*if (((i+offset)&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}*/
if (bitwise) {
if (((k+offset)&0x1f)==0 && (!((unscrambling_mask>>i)&1))) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
(pbch->pbch_a_interleaved) ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_prime>>i)&1)<<i : (((pbch->pbch_a_prime>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
k += (!((unscrambling_mask>>i)&1));
#ifdef DEBUG_PBCH_ENCODING
printf("i %d k %d offset %d (unscrambling_mask>>i)&1) %d s: %08x\t pbch_a_interleaved 0x%08x (!((unscrambling_mask>>i)&1)) %d\n", i, k, offset, (unscrambling_mask>>i)&1, s, pbch->pbch_a_interleaved, (!((unscrambling_mask>>i)&1)));
#endif
}
else {
(pbch->pbch_a_interleaved) ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_prime>>i)&1)<<i : (((pbch->pbch_a_prime>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
k += (!((unscrambling_mask>>i)&1));
#ifdef DEBUG_PBCH_ENCODING
printf("i %d k %d offset %d (unscrambling_mask>>i)&1) %d s: %08x\t pbch_a_interleaved 0x%08x (!((unscrambling_mask>>i)&1)) %d\n", i, k, offset, (unscrambling_mask>>i)&1, s, pbch->pbch_a_interleaved,
(!((unscrambling_mask>>i)&1)));
#endif
} else {
if (((i+offset)&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
if (((s>>((i+offset)&0x1f))&1)==1)
demod_pbch_e[i] = -demod_pbch_e[i];
#ifdef DEBUG_PBCH_ENCODING
if (i<8)
printf("s %d demod_pbch_e[i] %d\n", ((s>>((i+offset)&0x1f))&1), demod_pbch_e[i]);
#endif
}
}
if (((s>>((i+offset)&0x1f))&1)==1)
demod_pbch_e[i] = -demod_pbch_e[i];
#ifdef DEBUG_PBCH_ENCODING
if (i<8)
printf("s %d demod_pbch_e[i] %d\n", ((s>>((i+offset)&0x1f))&1), demod_pbch_e[i]);
#endif
}
}
}
void nr_pbch_quantize(int16_t *pbch_llr8,
int16_t *pbch_llr,
uint16_t len)
{
uint16_t len) {
uint16_t i;
for (i=0; i<len; i++) {
@@ -499,7 +399,6 @@ void nr_pbch_quantize(int16_t *pbch_llr8,
pbch_llr8[i]=-32;
else
pbch_llr8[i] = (char)(pbch_llr[i]);
}
}
/*
@@ -509,72 +408,61 @@ unsigned char sign(int8_t x) {
*/
uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,7,29,25,27,5,8,24,9,10,11,12,13,1,4,3,14,15,16,17,2,26,18,19,20,21,22,6,23};
int nr_rx_pbch( PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_UE_PBCH *nr_ue_pbch_vars,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
MIMO_mode_t mimo_mode,
uint32_t high_speed_flag)
{
int subframe_rx,
NR_UE_PBCH *nr_ue_pbch_vars,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
uint8_t i_ssb,
MIMO_mode_t mimo_mode,
uint32_t high_speed_flag) {
NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
int max_h=0;
int symbol;
//uint8_t pbch_a[64];
uint8_t *pbch_a = malloc(sizeof(uint8_t) * 32);
//uint32_t pbch_a_prime;
int16_t *pbch_e_rx;
uint8_t *decoded_output = nr_ue_pbch_vars->decoded_output;
uint8_t nushift;
uint8_t nushift,n_hf,ssb_index;
uint16_t M;
uint8_t Lmax=8; //to update
uint8_t ssb_index=0;
uint8_t Lmax=frame_parms->Lmax;
//uint16_t crc;
//unsigned short idx_demod =0;
uint32_t decoderState=0;
//uint8_t decoderListSize = 8, pathMetricAppr = 0;
//time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving;
//time_stats_t path_metric,sorting,update_LLR;
memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS);
//printf("nr_pbch_ue nid_cell %d\n",frame_parms->Nid_cell);
int subframe_rx = proc->subframe_rx;
pbch_e_rx = &nr_ue_pbch_vars->llr[0];
// clear LLR buffer
memset(nr_ue_pbch_vars->llr,0,NR_POLAR_PBCH_E);
int symbol_offset=1;
if (ue->is_synchronized > 0)
symbol_offset=4;
symbol_offset=ue->symbol_offset;
else
symbol_offset=0;
#ifdef DEBUG_PBCH
//printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF);
write_output("rxdataF0_pbch.m","rxF0pbch",
&nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1);
//printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF);
write_output("rxdataF0_pbch.m","rxF0pbch",
&nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1);
#endif
// symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot
// symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot
for (symbol=1; symbol<4; symbol++) {
nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF,
nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[eNB_id],
nr_ue_pbch_vars->rxdataF_ext,
nr_ue_pbch_vars->dl_ch_estimates_ext,
symbol,
symbol_offset,
high_speed_flag,
frame_parms);
nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[eNB_id],
nr_ue_pbch_vars->rxdataF_ext,
nr_ue_pbch_vars->dl_ch_estimates_ext,
symbol,
symbol_offset,
high_speed_flag,
frame_parms);
#ifdef DEBUG_PBCH
LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size );
LOG_I(PHY,"[PHY] PBCH starting channel_level\n");
@@ -582,113 +470,90 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
if (symbol == 1) {
max_h = nr_pbch_channel_level(nr_ue_pbch_vars->dl_ch_estimates_ext,
frame_parms,
symbol);
frame_parms,
symbol);
nr_ue_pbch_vars->log2_maxh = 3+(log2_approx(max_h)/2);
}
#ifdef DEBUG_PBCH
LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",nr_ue_pbch_vars->log2_maxh,max_h);
#endif
nr_pbch_channel_compensation(nr_ue_pbch_vars->rxdataF_ext,
nr_ue_pbch_vars->dl_ch_estimates_ext,
nr_ue_pbch_vars->rxdataF_comp,
frame_parms,
symbol,
nr_ue_pbch_vars->log2_maxh); // log2_maxh+I0_shift
nr_ue_pbch_vars->dl_ch_estimates_ext,
nr_ue_pbch_vars->rxdataF_comp,
frame_parms,
symbol,
nr_ue_pbch_vars->log2_maxh); // log2_maxh+I0_shift
/*if (frame_parms->nb_antennas_rx > 1)
pbch_detection_mrc(frame_parms,
nr_ue_pbch_vars->rxdataF_comp,
symbol);*/
/*
if (mimo_mode == ALAMOUTI) {
nr_pbch_alamouti(frame_parms,nr_ue_pbch_vars->rxdataF_comp,symbol);
} else if (mimo_mode != SISO) {
LOG_I(PHY,"[PBCH][RX] Unsupported MIMO mode\n");
return(-1);
}
*/
/*
if (mimo_mode == ALAMOUTI) {
nr_pbch_alamouti(frame_parms,nr_ue_pbch_vars->rxdataF_comp,symbol);
} else if (mimo_mode != SISO) {
LOG_I(PHY,"[PBCH][RX] Unsupported MIMO mode\n");
return(-1);
}
*/
if (symbol==1) {
nr_pbch_quantize(pbch_e_rx,
(short*)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]),
144);
(short *)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]),
144);
pbch_e_rx+=144;
} else {
nr_pbch_quantize(pbch_e_rx,
(short*)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]),
360);
(short *)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]),
360);
pbch_e_rx+=360;
}
}
#ifdef DEBUG_PBCH
write_output("rxdataF_comp.m","rxFcomp",&nr_ue_pbch_vars->rxdataF_comp[0][240],240*3,1,1);
#endif
pbch_e_rx = nr_ue_pbch_vars->llr;
//demod_pbch_e = nr_ue_pbch_vars->demod_pbch_e;
pbch_a = nr_ue_pbch_vars->pbch_a;
#ifdef DEBUG_PBCH
//pbch_e_rx = &nr_ue_pbch_vars->llr[0];
short *p = (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][20*12]);
for (int cnt = 0; cnt < 864 ; cnt++)
printf("pbch rx llr %d\n",*(pbch_e_rx+cnt));
#endif
//un-scrambling
M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
nushift = (Lmax==4)? i_ssb&3 : i_ssb&7;
uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041;
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0,0);
//polar decoding de-rate matching
const t_nrPolar_params *currentPtr = nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&nr_ue_pbch_vars->pbch_a_prime,currentPtr);
nr_polar_init(&nr_ue_pbch_vars->nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE,
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL);
AssertFatal(nr_ue_pbch_vars->nrPolar_params != NULL,"nr_ue_pbch_vars->nrPolar_params is null\n");
t_nrPolar_params *currentPtr = nr_polar_params(nr_ue_pbch_vars->nrPolar_params, NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t*)&nr_ue_pbch_vars->pbch_a_prime,currentPtr);
if(decoderState) return(decoderState);
// printf("polar decoder output 0x%08x\n",nr_ue_pbch_vars->pbch_a_prime);
// printf("polar decoder output 0x%08x\n",nr_ue_pbch_vars->pbch_a_prime);
// Decoder reversal
uint32_t a_reversed=0;
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
a_reversed |= (((uint64_t)nr_ue_pbch_vars->pbch_a_prime>>i)&1)<<(31-i);
nr_ue_pbch_vars->pbch_a_prime = a_reversed;
//payload un-scrambling
memset(&nr_ue_pbch_vars->pbch_a_interleaved, 0, sizeof(uint32_t) );
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) ^ (((nr_ue_pbch_vars->pbch_a_prime>>6)&1)<<1);
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_PAYLOAD_BITS,1,unscrambling_mask);
//printf("nushift %d sfn 3rd %d 2nd %d", nushift,((nr_ue_pbch_vars->pbch_a_prime>>6)&1), ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) );
//payload deinterleaving
//uint32_t in=0;
uint32_t out=0;
for (int i=0; i<32; i++) {
out |= ((nr_ue_pbch_vars->pbch_a_interleaved>>i)&1)<<(pbch_deinterleaving_pattern[i]);
#ifdef DEBUG_PBCH
@@ -696,36 +561,47 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
#endif
}
uint32_t payload = 0;
uint8_t xtra_byte = 0;
xtra_byte = (out>>24)&0xff;
uint32_t payload = 0;
uint8_t xtra_byte = 0;
xtra_byte = (out>>24)&0xff;
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
payload |= ((out>>i)&1)<<(NR_POLAR_PBCH_PAYLOAD_BITS-i-1);
payload |= ((out>>i)&1)<<(NR_POLAR_PBCH_PAYLOAD_BITS-i-1);
for (int i=0; i<3; i++)
decoded_output[i] = (uint8_t)((payload>>((3-i)<<3))&0xff);
for (int i=0; i<3; i++)
decoded_output[i] = (uint8_t)((payload>>((3-i)<<3))&0xff);
n_hf = ((xtra_byte>>4)&0x01); // computing the half frame index from the extra byte
ssb_index = i_ssb; // ssb index corresponds to i_ssb for Lmax = 4,8
if (Lmax == 64) { // for Lmax = 64 ssb index 4th,5th and 6th bits are in extra byte
for (int i=0; i<3; i++)
ssb_index += (((xtra_byte>>(7-i))&0x01)<<(3+i));
}
ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index, n_hf);
#ifdef DEBUG_PBCH
printf("xtra_byte %x payload %x\n", xtra_byte, payload);
for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++){
// printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]);
printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]);
printf("xtra_byte %x payload %x\n", xtra_byte, payload);
for (int i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++) {
// printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]);
printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]);
}
#endif
ue->dl_indication.rx_ind = &ue->rx_ind; // hang on rx_ind instance
//ue->rx_ind.sfn_slot = 0; //should be set by higher-1-layer, i.e. clean_and_set_if_instance()
ue->rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_MIB;
ue->rx_ind.rx_indication_body[0].mib_pdu.pdu = &decoded_output[0];
ue->rx_ind.rx_indication_body[0].mib_pdu.additional_bits = xtra_byte;
ue->rx_ind.rx_indication_body[0].mib_pdu.ssb_index = ssb_index; // confirm with TCL
ue->rx_ind.rx_indication_body[0].mib_pdu.ssb_length = Lmax; // confirm with TCL
ue->rx_ind.rx_indication_body[0].mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL
ue->rx_ind.number_pdus = 1;
ue->dl_indication.rx_ind = &ue->rx_ind; // hang on rx_ind instance
//ue->rx_ind.sfn_slot = 0; //should be set by higher-1-layer, i.e. clean_and_set_if_instance()
ue->rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_MIB;
ue->rx_ind.rx_indication_body[0].mib_pdu.pdu = &decoded_output[0];
ue->rx_ind.rx_indication_body[0].mib_pdu.additional_bits = xtra_byte;
ue->rx_ind.rx_indication_body[0].mib_pdu.ssb_index = i_ssb; // confirm with TCL
ue->rx_ind.rx_indication_body[0].mib_pdu.ssb_length = Lmax; // confirm with TCL
ue->rx_ind.rx_indication_body[0].mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL
ue->rx_ind.number_pdus = 1;
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&ue->dl_indication);
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&ue->dl_indication);
return 0;
return 0;
}
+1 -1
View File
@@ -577,7 +577,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
uint8_t preamble_index = ue->prach_resources[eNB_id]->ra_PreambleIndex;
//uint8_t tdd_mapindex = ue->prach_resources[eNB_id]->ra_TDD_map_index;
int16_t *prachF = ue->prach_vars[eNB_id]->prachF;
static int16_t prach_tmp[45600*2] __attribute__((aligned(32)));
static int16_t prach_tmp[45600*4] __attribute__((aligned(32)));
int16_t *prach = prach_tmp;
int16_t *prach2;
int16_t amp = ue->prach_vars[eNB_id]->amp;
@@ -61,10 +61,10 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch);
NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag);
void free_ue_ulsch(NR_UE_ULSCH_t *ulsch);
void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch);
NR_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag);
NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag);
void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
@@ -1006,6 +1006,25 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t is_crnti,
uint8_t llr8_flag);
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid);
/*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
@param[in] in Pointer to input bits
@param[in] size of input bits
@param[in] Nid cell id
@param[in] n_RNTI CRNTI
@param[out] out the scrambled bits
*/
void nr_pusch_codeword_scrambling(uint8_t *in,
uint16_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out);
uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
UE_nr_rxtx_proc_t *proc,
int eNB_id,
@@ -1118,13 +1137,18 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin
\returns number of tx antennas or -1 if error
*/
int nr_rx_pbch( PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int subframe_rx,
NR_UE_PBCH *nr_ue_pbch_vars,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
uint8_t i_ssb,
MIMO_mode_t mimo_mode,
uint32_t high_speed_flag);
int nr_pbch_detection(PHY_VARS_NR_UE *ue,
int pbch_initial_symbol,
runmode_t mode);
uint16_t rx_pbch_emul(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t eNB_id,
uint8_t pbch_phase);
@@ -1675,7 +1699,7 @@ int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue,
uint8_t eNB_id,
int frame,
uint8_t nr_tti_rx,
uint32_t dci_pdu[4],
uint64_t dci_pdu[2],
uint16_t rnti,
uint8_t dci_length,
NR_DCI_format_t dci_format,
+29 -16
View File
@@ -102,6 +102,8 @@ typedef struct {
uint16_t first_rb;
/// Current Number of RBs
uint16_t nb_rb;
/// number of layers
uint8_t Nl;
/// Last TPC command
uint8_t TPC;
/// Transport block size
@@ -110,20 +112,24 @@ typedef struct {
uint32_t B;
/// Length of ACK information (bits)
uint8_t O_ACK;
/// Pointer to the payload
uint8_t *b;
/// Pointers to transport block segments
uint8_t *c[MAX_NUM_ULSCH_SEGMENTS];
/// Index of current HARQ round for this ULSCH
uint8_t round;
/// MCS format of this ULSCH
uint8_t mcs;
/// Redundancy-version of the current sub-frame
uint8_t rvidx;
/// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8)
unsigned char *a;
/// Pointer to the payload + CRC
uint8_t *b;
/// Pointers to transport block segments
uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS];
/// LDPC-code outputs
uint8_t d[MAX_NUM_ULSCH_SEGMENTS][3*8448];
/// Interleaver outputs
uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*8448];
uint8_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
/// LDPC-code outputs (TS 36.212 V15.4.0, Sec 5.3.2 p. 17)
uint8_t e[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32)));
/// Rate matching (Interleaving) outputs (TS 36.212 V15.4.0, Sec 5.4.2.2 p. 30)
uint8_t f[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32)));
/// Number of code segments
uint32_t C;
/// Number of bits in code segments
@@ -158,6 +164,8 @@ typedef struct {
typedef struct {
/// Current Number of Symbols
uint8_t Nsymb_pusch;
/// number of DMRS resource elements
uint8_t nb_re_dmrs;
/// SRS active flag
uint8_t srs_active;
//#if defined(UPGRADE_RAT_NR)
@@ -168,6 +176,7 @@ typedef struct {
// UL number of harq processes
uint8_t number_harq_processes_for_pusch;
#endif
/*
/// Pointer to CQI data (+1 for 8 bits crc)
uint8_t o[1+MAX_CQI_BYTES];
/// Length of CQI data (bits)
@@ -180,22 +189,25 @@ typedef struct {
uint8_t O_RI;
/// Pointer to ACK
uint8_t o_ACK[4];
*/
/// Minimum number of CQI bits for PUSCH (36-212 r8.6, Sec 5.2.4.1 p. 37)
uint8_t O_CQI_MIN;
/// ACK/NAK Bundling flag
uint8_t bundling;
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
uint8_t e[MAX_NUM_CHANNEL_BITS];
/// Concatenated "g"-sequences (for definition see 36-212 V15.4.0 2018-12, p.31)
uint8_t g[MAX_NUM_NR_CHANNEL_BITS];
/// Interleaved "h"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
uint8_t h[MAX_NUM_CHANNEL_BITS];
uint8_t h[MAX_NUM_NR_CHANNEL_BITS];
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
uint8_t b_tilde[MAX_NUM_CHANNEL_BITS];
uint8_t b_tilde[MAX_NUM_NR_CHANNEL_BITS];
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
int32_t d[MAX_NUM_RE];
int32_t d[MAX_NUM_NR_RE];
/// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15)
int32_t z[MAX_NUM_RE];
int32_t z[MAX_NUM_NR_RE];
/*
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
uint8_t q[MAX_CQI_PAYLOAD];
/// coded and interleaved CQI bits
uint8_t o_w[(MAX_CQI_BITS+8)*3];
/// coded CQI bits
@@ -204,6 +216,7 @@ typedef struct {
uint8_t q_ACK[MAX_ACK_PAYLOAD];
/// coded RI bits
uint8_t q_RI[MAX_RI_PAYLOAD];
*/
/// beta_offset_cqi times 8
uint16_t beta_offset_cqi_times8;
/// beta_offset_ri times 8
@@ -229,9 +242,9 @@ typedef struct {
/// num active cba group
uint8_t num_active_cba_groups;
/// num dci found for cba
uint8_t num_cba_dci[10];
//uint8_t num_cba_dci[10];
/// allocated CBA RNTI
uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
//uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
/// UL max-harq-retransmission
uint8_t Mlimit;
} NR_UE_ULSCH_t;
@@ -394,7 +407,7 @@ typedef struct {
/// search space
dci_space_t search_space;
/// DCI pdu
uint32_t dci_pdu[4];
uint64_t dci_pdu[2];
//#if defined(UPGRADE_RAT_NR)
#if 1
/// harq information
@@ -0,0 +1,453 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
* \brief Top-level routines for coding the ULSCH transport channel as described in 38.212 V15.4 2018-12
* \author Khalid Ahmed
* \date 2019
* \version 0.1
* \company Fraunhofer IIS
* \email: khalid.ahmed@iis.fraunhofer.de
* \note
* \warning
*/
#include "PHY/defs_UE.h"
#include "PHY/phy_extern_ue.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/CODING/coding_defs.h"
#include "PHY/CODING/coding_extern.h"
#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/CODING/nrLDPC_encoder/defs.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch)
{
int i;
int r;
if (ulsch) {
#ifdef DEBUG_ULSCH_FREE
printf("Freeing ulsch %p\n",ulsch);
#endif
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
if (ulsch->harq_processes[i]) {
if (ulsch->harq_processes[i]->a) {
free16(ulsch->harq_processes[i]->a,MAX_NR_ULSCH_PAYLOAD_BYTES);
ulsch->harq_processes[i]->a = NULL;
}
if (ulsch->harq_processes[i]->b) {
free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES);
ulsch->harq_processes[i]->b = NULL;
}
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS; r++) {
if (ulsch->harq_processes[i]->c[r]) {
free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
ulsch->harq_processes[i]->c[r] = NULL;
}
if (ulsch->harq_processes[i]->d[r]) {
free16(ulsch->harq_processes[i]->d[r],68*384);
ulsch->harq_processes[i]->d[r] = NULL;
}
}
free16(ulsch->harq_processes[i],sizeof(NR_UL_UE_HARQ_t));
ulsch->harq_processes[i] = NULL;
}
}
free16(ulsch,sizeof(NR_UE_ULSCH_t));
ulsch = NULL;
}
}
NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag)
{
NR_UE_ULSCH_t *ulsch;
unsigned char exit_flag = 0,i,j,r;
unsigned char bw_scaling =1;
switch (N_RB_UL) {
case 106:
bw_scaling =2;
break;
default:
bw_scaling =1;
break;
}
ulsch = (NR_UE_ULSCH_t *)malloc16(sizeof(NR_UE_ULSCH_t));
if (ulsch) {
memset(ulsch,0,sizeof(NR_UE_ULSCH_t));
ulsch->number_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES;
ulsch->Mlimit = 4; // maximum harq retransmissions
//for (i=0; i<10; i++)
//ulsch->harq_ids[i] = 0;
for (i=0; i<number_of_harq_pids; i++) {
ulsch->harq_processes[i] = (NR_UL_UE_HARQ_t *)malloc16(sizeof(NR_UL_UE_HARQ_t));
// printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]);
if (ulsch->harq_processes[i]) {
memset(ulsch->harq_processes[i], 0, sizeof(NR_UL_UE_HARQ_t));
ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
ulsch->harq_processes[i]->a = (unsigned char*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
if (ulsch->harq_processes[i]->a) {
bzero(ulsch->harq_processes[i]->a,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
} else {
printf("Can't allocate PDU\n");
exit_flag=1;
}
if (ulsch->harq_processes[i]->b)
bzero(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
else {
LOG_E(PHY,"Can't get b\n");
exit_flag=1;
}
if (abstraction_flag==0) {
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling; r++) {
// account for filler in first segment and CRCs for multiple segment case
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448);
ulsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output
if (ulsch->harq_processes[i]->c[r]) {
bzero(ulsch->harq_processes[i]->c[r],8448);
} else {
printf("Can't get c\n");
exit_flag=2;
}
if (ulsch->harq_processes[i]->d[r]) {
bzero(ulsch->harq_processes[i]->d[r],(68*384));
} else {
printf("Can't get d\n");
exit_flag=2;
}
}
}
ulsch->harq_processes[i]->subframe_scheduling_flag = 0;
ulsch->harq_processes[i]->first_tx = 1;
} else {
LOG_E(PHY,"Can't get harq_p %d\n",i);
exit_flag=3;
}
}
if (exit_flag==0) {
for (i=0; i<number_of_harq_pids; i++) {
ulsch->harq_processes[i]->round=0;
}
return(ulsch);
}
}
LOG_E(PHY,"new_ue_ulsch exit flag, size of %d , %zu\n",exit_flag, sizeof(LTE_UE_ULSCH_t));
free_nr_ue_ulsch(ulsch);
return(NULL);
}
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid)
{
/////////////////////////parameters and variables declaration/////////////////////////
///////////
unsigned int G,crc;
NR_UL_UE_HARQ_t *harq_process;
uint16_t nb_rb ;
uint8_t nb_symb_sch ;
uint32_t A, Z, F;
uint32_t *pz;
uint8_t mod_order;
uint16_t Kr,r,r_offset,Kr_bytes;
uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
uint8_t BG;
uint32_t E;
uint8_t Ilbrm;
uint32_t Tbslbrm;
uint8_t nb_re_dmrs;
uint16_t length_dmrs;
int i;
float Coderate;
///////////
///////////////////////////////////////////////////////////////////////////////////////
/////////////////////////parameters and variables initialization/////////////////////////
///////////
crc = 1;
harq_process = ulsch->harq_processes[harq_pid];
nb_rb = harq_process->nb_rb;
nb_symb_sch = harq_process->nb_symbols;
A = harq_process->TBS;
pz = &Z;
mod_order = nr_get_Qm(harq_process->mcs,1);
Kr=0;
r_offset=0;
BG = 1;
F=0;
Ilbrm = 0;
Tbslbrm = 950984; //max tbs
nb_re_dmrs = ulsch->nb_re_dmrs;
length_dmrs = 1;
Coderate = 0.0;
///////////
/////////////////////////////////////////////////////////////////////////////////////////
/*
uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char
for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
channel_input[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
}
*/
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
printf("ulsch coding nb_rb %d nb_symb_sch %d nb_re_dmrs %d, length_dmrs %d\n", nb_rb,nb_symb_sch, nb_re_dmrs,length_dmrs);
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,harq_process->Nl);
LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
printf("ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
// if (harq_process->Ndi == 1) { // this is a new packet
if (harq_process->round == 0) { // this is a new packet
#ifdef DEBUG_DLSCH_CODING
printf("encoding thinks this is a new packet \n");
#endif
///////////////////////// a---->| add CRC |---->b /////////////////////////
///////////
/*
int i;
printf("ulsch (tx): \n");
for (i=0;i<(A>>3);i++)
printf("%02x.",a[i]);
printf("\n");
*/
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(harq_process->a,A)>>8;
harq_process->a[A>>3] = ((uint8_t*)&crc)[2];
harq_process->a[1+(A>>3)] = ((uint8_t*)&crc)[1];
harq_process->a[2+(A>>3)] = ((uint8_t*)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
harq_process->B = A+24;
memcpy(harq_process->b,harq_process->a,(A/8)+4);
///////////
///////////////////////////////////////////////////////////////////////////
///////////////////////// b---->| block segmentation |---->c /////////////////////////
///////////
nr_segmentation(harq_process->b,
harq_process->c,
harq_process->B,
&harq_process->C,
&harq_process->K,
pz,
&harq_process->F);
F = harq_process->F;
Coderate = (float) A /(float) G;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
BG = 2;
}
else{
BG = 1;
}
Kr = harq_process->K;
Kr_bytes = Kr>>3;
///////////
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////// c---->| LDCP coding |---->d /////////////////////////
///////////
//printf("segment Z %d k %d Kr %d BG %d\n", *pz,harq_process->K,Kr,BG);
//start_meas(te_stats);
for (r=0; r<harq_process->C; r++) {
d_tmp[r] = &harq_process->d[r][0];
//channel_input[r] = &harq_process->d[r][0];
#ifdef DEBUG_DLSCH_CODING
printf("Encoder: B %d F %d \n",harq_process->B, harq_process->F);
printf("start ldpc encoder segment %d/%d\n",r,harq_process->C);
printf("input %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){
printf("%d ", harq_process->c[r][cnt]);
}
printf("\n");
#endif
//ldpc_encoder_orig((unsigned char*)harq_process->c[r],harq_process->d[r],Kr,BG,0);
//ldpc_encoder_optim((unsigned char*)harq_process->c[r],(unsigned char*)&harq_process->d[r][0],Kr,BG,NULL,NULL,NULL,NULL);
}
//for (int i=0;i<68*384;i++)
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
/*printf("output %d %d %d %d %d \n", harq_process->d[0][0], harq_process->d[0][1], harq_process->d[r][2],harq_process->d[0][3], harq_process->d[0][4]);
for (int cnt =0 ; cnt < 66*(*pz); cnt ++){
printf("%d \n", harq_process->d[0][cnt]);
}
printf("\n");*/
//ldpc_encoder_optim_8seg(harq_process->c,d_tmp,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL);
ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL);
//stop_meas(te_stats);
//printf("end ldpc encoder -- output\n");
//write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4);
#ifdef DEBUG_DLSCH_CODING
write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4);
write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
#endif
///////////
///////////////////////////////////////////////////////////////////////////////
}
for (r=0; r<harq_process->C; r++) { // looping over C segments
if (harq_process->F>0) {
for (int k=(Kr-F-2*(*pz)); k<Kr-2*(*pz); k++) {
harq_process->d[r][k] = NR_NULL;
//if (k<(Kr-F+8))
//printf("r %d filler bits [%d] = %d \n", r,k, harq_process->d[r][k]);
}
}
#ifdef DEBUG_DLSCH_CODING
printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
r,
G,
Kr*3,
mod_order,nb_rb);
#endif
//start_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING
printf("rvidx in encoding = %d\n", harq_process->rvidx);
#endif
///////////////////////// d---->| Rate matching bit selection |---->e /////////////////////////
///////////
E = nr_get_E(G, harq_process->C, mod_order, harq_process->Nl, r);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
BG,
*pz,
harq_process->d[r],
harq_process->e+r_offset,
harq_process->C,
harq_process->rvidx,
E);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output ratematching e[%d]= %d r_offset %d\n", i,harq_process->e[i+r_offset], r_offset);
#endif
///////////
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////// e---->| Rate matching bit interleaving |---->f /////////////////////////
///////////
//stop_meas(rm_stats);
//start_meas(i_stats);
nr_interleaving_ldpc(E,
mod_order,
harq_process->e+r_offset,
harq_process->f+r_offset);
//stop_meas(i_stats);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output interleaving f[%d]= %d r_offset %d\n", i,harq_process->f[i+r_offset], r_offset);
if (r==harq_process->C-1)
write_output("enc_output.m","enc",harq_process->f,G,1,4);
#endif
r_offset += E;
///////////
///////////////////////////////////////////////////////////////////////////////////////////////
}
memcpy(ulsch->g,harq_process->f,G>>3); // g is the concatenated code block
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0);
}
+56 -6
View File
@@ -33,6 +33,7 @@
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <math.h>
#include "PHY/defs_nr_UE.h"
@@ -662,6 +663,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
int synchro_position;
int **rxdata = NULL;
int fo_flag = PHY_vars_UE->UE_fo_compensation; // flag to enable freq offset estimation and compensation
#ifdef DBG_PSS_NR
@@ -705,7 +707,10 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
synchro_position = pss_search_time_nr(rxdata,
frame_parms,
(int *)&PHY_vars_UE->common_vars.eNb_id);
fo_flag,
(int *)&PHY_vars_UE->common_vars.eNb_id,
(int *)&PHY_vars_UE->common_vars.freq_offset);
#if TEST_SYNCHRO_TIMING_PSS
@@ -751,6 +756,15 @@ static inline int64_t abs64(int64_t x)
return (((int64_t)((int32_t*)&x)[0])*((int64_t)((int32_t*)&x)[0]) + ((int64_t)((int32_t*)&x)[1])*((int64_t)((int32_t*)&x)[1]));
}
static inline double angle64(int64_t x)
{
double re=((int32_t*)&x)[0];
double im=((int32_t*)&x)[1];
return (atan2(im,re));
}
/*******************************************************************
*
* NAME : pss_search_time_nr
@@ -805,12 +819,15 @@ static inline int64_t abs64(int64_t x)
int pss_search_time_nr(int **rxdata, ///rx data in time domain
NR_DL_FRAME_PARMS *frame_parms,
int *eNB_id)
int fo_flag,
int *eNB_id,
int *f_off)
{
unsigned int n, ar, peak_position, pss_source;
int64_t peak_value;
int64_t result;
int64_t avg[NUMBER_PSS_SEQUENCE];
double ffo_est=0;
unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); /* 1 frame for now, it should be 2 TODO_NR */
@@ -831,7 +848,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
maxval = max(maxval,-primary_synchro_time_nr[1][i]);
maxval = max(maxval,primary_synchro_time_nr[2][i]);
maxval = max(maxval,-primary_synchro_time_nr[2][i]);
}
int shift = log2_approx(maxval);//*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*2);
@@ -859,7 +875,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
frame_parms->ofdm_symbol_size,
shift);
pss_corr_ue[pss_index][n] += abs64(result);
//((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */
//((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
//((short*)&synchro_out)[0] += ((int*) &result)[0]; /* real part */
@@ -867,7 +882,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
}
}
/* calculate the absolute value of sync_corr[n] */
avg[pss_index]+=pss_corr_ue[pss_index][n];
if (pss_corr_ue[pss_index][n] > peak_value) {
@@ -882,11 +897,46 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
}
}
if (fo_flag){
// fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS
// Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th International Conference on Communications and Networking in China, 2012.
int64_t result1,result2;
// Computing cross-correlation at peak on half the symbol size for first half of data
result1 = dot_product64((short*)primary_synchro_time_nr[pss_source],
(short*) &(rxdata[0][peak_position]),
frame_parms->ofdm_symbol_size>>1,
shift);
// Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size
// as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift
result2 = dot_product64((short*)primary_synchro_time_nr[pss_source]+(frame_parms->ofdm_symbol_size),
(short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size),
frame_parms->ofdm_symbol_size>>1,
shift);
int64_t re1,re2,im1,im2;
re1=((int*) &result1)[0];
re2=((int*) &result2)[0];
im1=((int*) &result1)[1];
im2=((int*) &result2)[1];
// estimation of fractional frequency offset: angle[(result1)'*(result2)]/pi
ffo_est=atan2(re1*im2-re2*im1,re1*re2+im1*im2)/M_PI;
#ifdef DBG_PSS_NR
printf("ffo %lf\n",ffo_est);
#endif
}
// computing absolute value of frequency offset
*f_off = ffo_est*frame_parms->subcarrier_spacing;
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) avg[pss_index]/=(length/4);
*eNB_id = pss_source;
LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB\n", pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]));
LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf\n", pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]),ffo_est);
if (peak_value < 5*avg[pss_source])
return(-1);

Some files were not shown because too many files have changed in this diff Show More