Resolved merge conflict
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
cmake_targets/log/
|
cmake_targets/log/
|
||||||
cmake_targets/ran_build/
|
cmake_targets/*/build/
|
||||||
targets/bin/
|
targets/bin/
|
||||||
|
|
||||||
|
|||||||
@@ -131,10 +131,10 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage ("Start VM -- nu-ue-usrp") {
|
stage ("Start VM -- nr-ue-usrp") {
|
||||||
steps {
|
steps {
|
||||||
timeout (time: 5, unit: 'MINUTES') {
|
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 {
|
steps {
|
||||||
gitlabCommitStatus(name: "Build nr-UE-usrp") {
|
gitlabCommitStatus(name: "Build nr-UE-usrp") {
|
||||||
timeout (time: 20, unit: 'MINUTES') {
|
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}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,380 @@
|
|||||||
|
#!/bin/groovy
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Abstraction function to send social media messages:
|
||||||
|
// like on Slack or Mattermost
|
||||||
|
def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) {
|
||||||
|
if (params.pipelineUsesSlack != null) {
|
||||||
|
if (params.pipelineUsesSlack) {
|
||||||
|
slackSend channel: pipeChannel, color: pipeColor, message: pipeMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Location of the test XML file to be run
|
||||||
|
def testXMLFile = params.pythonTestXmlFile
|
||||||
|
def mainPythonAllXmlFiles = ""
|
||||||
|
def buildStageStatus = true
|
||||||
|
|
||||||
|
// Name of the phone resource
|
||||||
|
def ciUSRPsResource = params.USRPsResource
|
||||||
|
|
||||||
|
// Terminate Status
|
||||||
|
def termUE = 0
|
||||||
|
def termENB = 1
|
||||||
|
def termStatusArray = new Boolean[2]
|
||||||
|
termStatusArray[termUE] = false
|
||||||
|
termStatusArray[termENB] = false
|
||||||
|
|
||||||
|
// Global Parameters.
|
||||||
|
def eNB_Repository
|
||||||
|
def eNB_Branch
|
||||||
|
def eNB_CommitID
|
||||||
|
def eNB_AllowMergeRequestProcess = false
|
||||||
|
def eNB_TargetBranch
|
||||||
|
def PROJECT_NAME = "test-boris"
|
||||||
|
def GIT_COMMIT_AUTHORi
|
||||||
|
def GIT_COMMIT_EMAIL
|
||||||
|
def testStageName
|
||||||
|
// Reversing list because pop() will take the last (right-most) element
|
||||||
|
//def modeList = ['TesteNB', 'TestUE', 'TesteNB'].reverse()
|
||||||
|
|
||||||
|
// Global Parameters not to break the main.py command line and code.
|
||||||
|
def ADB_IPAddress = "none"
|
||||||
|
def ADB_Username = "none"
|
||||||
|
def ADB_Password = "none"
|
||||||
|
def EPC_IPAddress = "none"
|
||||||
|
def EPC_Username = "none"
|
||||||
|
def EPC_Password = "none"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pipeline {
|
||||||
|
agent {
|
||||||
|
label pythonExecutor
|
||||||
|
}
|
||||||
|
options {
|
||||||
|
disableConcurrentBuilds()
|
||||||
|
gitLabConnection('OAI GitLab')
|
||||||
|
ansiColor('xterm')
|
||||||
|
lock (ciUSRPsResource)
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage ('Retrieve latest from branch') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
checkout([$class: 'GitSCM', branches: [[name: "${params.Branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'https://gitlab.eurecom.fr/oai/openairinterface5g.git']]])
|
||||||
|
sh "git clean -x -d -ff"
|
||||||
|
sh "git log -n1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage ("print latest commit info") {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
echo "Building on: "
|
||||||
|
echo " Repository -- ${GIT_URL}"
|
||||||
|
echo " Branch -- ${GIT_BRANCH}"
|
||||||
|
echo " Commit -- ${GIT_COMMIT}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage ("Verify Parameters") {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"'
|
||||||
|
JOB_TIMESTAMP = JOB_TIMESTAMP.trim()
|
||||||
|
|
||||||
|
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
|
||||||
|
def allParametersPresent = true
|
||||||
|
|
||||||
|
// It is already too late to check it
|
||||||
|
if (params.pythonExecutor != null) {
|
||||||
|
echo "eNB CI executor node : ${pythonExecutor}"
|
||||||
|
}
|
||||||
|
if (params.eNB_Repository == null) {
|
||||||
|
eNB_Repository = GIT_URL
|
||||||
|
} else {
|
||||||
|
eNB_Repository = params.eNB_Repository
|
||||||
|
}
|
||||||
|
echo "eNB_Repository = ${eNB_Repository}"
|
||||||
|
if (params.eNB_Branch== null) {
|
||||||
|
eNB_Branch = GIT_BRANCH
|
||||||
|
} else {
|
||||||
|
eNB_Branch = params.eNB_Branch
|
||||||
|
}
|
||||||
|
echo "eNB_Branch = ${eNB_Branch}"
|
||||||
|
if (params.eNB_CommitID == null) {
|
||||||
|
eNB_CommitID = GIT_COMMIT
|
||||||
|
} else {
|
||||||
|
eNB_CommitID = params.eNB_CommitID
|
||||||
|
}
|
||||||
|
echo "eNB_CommitID = ${eNB_CommitID}"
|
||||||
|
// If not present picking a default Stage Name
|
||||||
|
if (params.pipelineTestStageName == null) {
|
||||||
|
// picking default
|
||||||
|
testStageName = 'Template Test Stage'
|
||||||
|
} else {
|
||||||
|
testStageName = params.pipelineTestStageName
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.USRPsResource == null) {
|
||||||
|
allParametersPresent = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.eNB_IPAddress == null) {
|
||||||
|
allParametersPresent = false
|
||||||
|
}
|
||||||
|
if (params.UE_IPAddress == null) {
|
||||||
|
allParametersPresent = false
|
||||||
|
}
|
||||||
|
if (params.eNB_SourceCodePath == null) {
|
||||||
|
allParametersPresent = false
|
||||||
|
}
|
||||||
|
if (params.eNB_Credentials == null) {
|
||||||
|
allParametersPresent = false
|
||||||
|
}
|
||||||
|
if (params.UE_Credentials == null) {
|
||||||
|
allParametersPresent = false
|
||||||
|
}
|
||||||
|
GIT_COMMIT_AUTHOR = sh (
|
||||||
|
script: 'git show -s --pretty=%an',
|
||||||
|
returnStdout: true
|
||||||
|
).trim()
|
||||||
|
echo "The author of the commit is: ${GIT_COMMIT_AUTHOR}"
|
||||||
|
GIT_COMMIT_EMAIL = sh (
|
||||||
|
script: 'git show -s --pretty=%ae',
|
||||||
|
returnStdout: true
|
||||||
|
).trim()
|
||||||
|
echo "The email of the author is: ${GIT_COMMIT_EMAIL}"
|
||||||
|
if (allParametersPresent) {
|
||||||
|
echo "All parameters are present"
|
||||||
|
} else {
|
||||||
|
echo "Some parameters are missing"
|
||||||
|
sh "./ci-scripts/fail.sh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage ("Build and Test") {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
dir ('ci-scripts') {
|
||||||
|
// If not present picking a default XML file
|
||||||
|
if (params.pythonTestXmlFile == null) {
|
||||||
|
// picking default
|
||||||
|
testXMLFile = 'xml_files/gnb_usrp_build.xml'
|
||||||
|
echo "Test XML file(default): ${testXMLFile}"
|
||||||
|
mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " "
|
||||||
|
} else {
|
||||||
|
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
|
||||||
|
for (xmlFile in myXmlTestSuite) {
|
||||||
|
if (fileExists(xmlFile)) {
|
||||||
|
mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " "
|
||||||
|
echo "Test XML file : ${xmlFile}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password']
|
||||||
|
]) {
|
||||||
|
sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --ADBIPAddress=${ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_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} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --UEIPAddress=${params.eNB_IPAddress} --UEUserName=${eNB_Username} --UEPassword=${eNB_Password} --eNBBranch=${eNB_Branch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --UESourceCodePath=${params.eNB_SourceCodePath} --eNBRepository=${eNB_Repository} --eNBCommitID=${eNB_CommitID} --ADBIPAddress=${ADB_IPAddress} --EPCIPAddress=${EPC_IPAddress} --XMLTestFile=${xmlFile}"
|
||||||
|
} catch (Exception e) {
|
||||||
|
currentBuild.result = 'FAILURE'
|
||||||
|
buildStageStatus = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage ("Terminate") {
|
||||||
|
parallel {
|
||||||
|
stage('Terminate NR UE') {
|
||||||
|
steps {
|
||||||
|
echo '\u2705 \u001B[32mTerminate NR UE\u001B[0m'
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password']
|
||||||
|
]) {
|
||||||
|
sh "python3 ci-scripts/main.py --mode=TerminateOAIUE --UEIPAddress=${params.eNB_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
success {
|
||||||
|
script {
|
||||||
|
termStatusArray[termUE] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Terminate NR eNB') {
|
||||||
|
steps {
|
||||||
|
echo '\u2705 \u001B[32mTerminate NR eNB\u001B[0m'
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
|
||||||
|
]) {
|
||||||
|
sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
success {
|
||||||
|
script {
|
||||||
|
termStatusArray[termENB] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Log Collection') {
|
||||||
|
parallel {
|
||||||
|
stage('Log Collection (gNB and NR UE - Build)') {
|
||||||
|
steps {
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
|
||||||
|
]) {
|
||||||
|
echo '\u2705 \u001B[32mLog Collection (gNB and NR UE - Build)\u001B[0m'
|
||||||
|
sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
|
||||||
|
|
||||||
|
echo '\u2705 \u001B[32mLog Transfer (gNB and NR UE - Build)\u001B[0m'
|
||||||
|
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
if(fileExists("build.log.${env.BUILD_ID}.zip")) {
|
||||||
|
archiveArtifacts "build.log.${env.BUILD_ID}.zip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Log Collection (gNB - Run)') {
|
||||||
|
steps {
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
|
||||||
|
]) {
|
||||||
|
echo '\u2705 \u001B[32mLog Collection (gNB - Run)\u001B[0m'
|
||||||
|
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
|
||||||
|
|
||||||
|
echo '\u2705 \u001B[32mLog Transfer (gNB - Run)\u001B[0m'
|
||||||
|
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
|
||||||
|
archiveArtifacts "enb.log.${env.BUILD_ID}.zip"
|
||||||
|
}
|
||||||
|
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>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
|
||||||
|
archiveArtifacts "test_results-${JOB_NAME}.html"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Log Collection (NR UE - Run)') {
|
||||||
|
steps {
|
||||||
|
withCredentials([
|
||||||
|
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
|
||||||
|
]) {
|
||||||
|
echo '\u2705 \u001B[32mLog Collection (gNB - Run)\u001B[0m'
|
||||||
|
sh "python3 ci-scripts/main.py --mode=LogCollectOAIUE --UEIPAddress=${params.eNB_IPAddress} --UEUserName=${eNB_Username} --UEPassword=${eNB_Password} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --UESourceCodePath=${params.eNB_SourceCodePath}"
|
||||||
|
|
||||||
|
echo '\u2705 \u001B[32mLog Transfer (gNB - Run)\u001B[0m'
|
||||||
|
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/ue.log.zip ./ue.log.${env.BUILD_ID}.zip || true"
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
if(fileExists("ue.log.${env.BUILD_ID}.zip")) {
|
||||||
|
archiveArtifacts "ue.log.${env.BUILD_ID}.zip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
script {
|
||||||
|
if ("MERGE".equals(env.gitlabActionType)) {
|
||||||
|
echo "This is a MERGE event"
|
||||||
|
} else {
|
||||||
|
gitlabCommitStatus(name: "Test-gNB-nrUE") {
|
||||||
|
if ((currentBuild.result == null) || (currentBuild.result == 'SUCCESS')) {
|
||||||
|
echo "Setting the gitlab commit status to pass"
|
||||||
|
} else {
|
||||||
|
sh "./ci-scripts/fail.sh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emailext attachmentsPattern: '*results*.html',
|
||||||
|
body: '''Hi,
|
||||||
|
Here are attached HTML report files for $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!
|
||||||
|
|
||||||
|
Regards,
|
||||||
|
OAI CI Team''',
|
||||||
|
replyTo: 'no-reply@openairinterface.org',
|
||||||
|
subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!',
|
||||||
|
to: GIT_COMMIT_EMAIL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
success {
|
||||||
|
script {
|
||||||
|
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")"
|
||||||
|
if ("MERGE".equals(env.gitlabActionType)) {
|
||||||
|
echo "This is a MERGE event"
|
||||||
|
//addGitLabMRComment comment: message
|
||||||
|
def message2 = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ") -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")"
|
||||||
|
sendSocialMediaMessage('ci-test', 'good', message2)
|
||||||
|
} else {
|
||||||
|
sendSocialMediaMessage('ci-test', 'good', message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
script {
|
||||||
|
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ")"
|
||||||
|
if ("MERGE".equals(env.gitlabActionType)) {
|
||||||
|
echo "This is a MERGE event"
|
||||||
|
//addGitLabMRComment comment: message
|
||||||
|
def message2 = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ") -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")"
|
||||||
|
sendSocialMediaMessage('ci-test', 'danger', message2)
|
||||||
|
} else {
|
||||||
|
sendSocialMediaMessage('ci-test', 'danger', message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
Active_gNBs = ( "gNB-Eurecom-5GNRBox");
|
||||||
|
# Asn1_verbosity, choice in: none, info, annoying
|
||||||
|
Asn1_verbosity = "none";
|
||||||
|
|
||||||
|
gNBs =
|
||||||
|
(
|
||||||
|
{
|
||||||
|
////////// Identification parameters:
|
||||||
|
gNB_ID = 0xe00;
|
||||||
|
|
||||||
|
cell_type = "CELL_MACRO_GNB";
|
||||||
|
|
||||||
|
gNB_name = "gNB-Eurecom-5GNRBox";
|
||||||
|
|
||||||
|
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||||
|
tracking_area_code = 1;
|
||||||
|
|
||||||
|
plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
|
||||||
|
|
||||||
|
tr_s_preference = "local_mac"
|
||||||
|
|
||||||
|
////////// Physical parameters:
|
||||||
|
|
||||||
|
component_carriers = (
|
||||||
|
{
|
||||||
|
node_function = "3GPP_gNODEB";
|
||||||
|
node_timing = "synch_to_ext_device";
|
||||||
|
node_synch_ref = 0;
|
||||||
|
frame_type = "TDD";
|
||||||
|
DL_prefix_type = "NORMAL";
|
||||||
|
UL_prefix_type = "NORMAL";
|
||||||
|
eutra_band = 78;
|
||||||
|
downlink_frequency = 3510000000L;
|
||||||
|
uplink_frequency_offset = -120000000;
|
||||||
|
Nid_cell = 0;
|
||||||
|
N_RB_DL = 106;
|
||||||
|
nb_antenna_ports = 1;
|
||||||
|
nb_antennas_tx = 1;
|
||||||
|
nb_antennas_rx = 1;
|
||||||
|
tx_gain = 90;
|
||||||
|
rx_gain = 125;
|
||||||
|
MIB_subCarrierSpacingCommon = 30;
|
||||||
|
MIB_ssb_SubcarrierOffset = 0;
|
||||||
|
MIB_dmrs_TypeA_Position = 2;
|
||||||
|
pdcch_ConfigSIB1 = 0;
|
||||||
|
SIB1_frequencyOffsetSSB = "khz5";
|
||||||
|
SIB1_ssb_PeriodicityServingCell = 5;
|
||||||
|
SIB1_ss_PBCH_BlockPower = -60;
|
||||||
|
absoluteFrequencySSB = 0;
|
||||||
|
DL_FreqBandIndicatorNR = 15;
|
||||||
|
DL_absoluteFrequencyPointA = 15;
|
||||||
|
DL_offsetToCarrier = 15;
|
||||||
|
DL_SCS_SubcarrierSpacing = "kHz30";
|
||||||
|
DL_SCS_SpecificCarrier_k0 = 0;
|
||||||
|
DL_carrierBandwidth = 15;
|
||||||
|
DL_locationAndBandwidth = 15;
|
||||||
|
DL_BWP_SubcarrierSpacing = "kHz30";
|
||||||
|
DL_BWP_prefix_type = "NORMAL";
|
||||||
|
UL_FreqBandIndicatorNR = 15;
|
||||||
|
UL_absoluteFrequencyPointA = 13;
|
||||||
|
UL_additionalSpectrumEmission = 3;
|
||||||
|
UL_p_Max = -1;
|
||||||
|
UL_frequencyShift7p5khz = "TRUE";
|
||||||
|
UL_offsetToCarrier = 10;
|
||||||
|
UL_SCS_SubcarrierSpacing = "kHz30";
|
||||||
|
UL_SCS_SpecificCarrier_k0 = 0;
|
||||||
|
UL_carrierBandwidth = 15;
|
||||||
|
UL_locationAndBandwidth = 15;
|
||||||
|
UL_BWP_SubcarrierSpacing = "kHz30";
|
||||||
|
UL_BWP_prefix_type = "NORMAL";
|
||||||
|
UL_timeAlignmentTimerCommon = "infinity";
|
||||||
|
ServingCellConfigCommon_n_TimingAdvanceOffset = "n0"
|
||||||
|
ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01;
|
||||||
|
ServingCellConfigCommon_ssb_periodicityServingCell = 10;
|
||||||
|
ServingCellConfigCommon_dmrs_TypeA_Position = 2;
|
||||||
|
NIA_SubcarrierSpacing = "kHz15";
|
||||||
|
ServingCellConfigCommon_ss_PBCH_BlockPower = -60;
|
||||||
|
referenceSubcarrierSpacing = "kHz15";
|
||||||
|
dl_UL_TransmissionPeriodicity = "ms0p5";
|
||||||
|
nrofDownlinkSlots = 10;
|
||||||
|
nrofDownlinkSymbols = 10;
|
||||||
|
nrofUplinkSlots = 10;
|
||||||
|
nrofUplinkSymbols = 10;
|
||||||
|
rach_totalNumberOfRA_Preambles = 63;
|
||||||
|
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice = "oneEighth";
|
||||||
|
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth = 4;
|
||||||
|
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth = 8;
|
||||||
|
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf = 16;
|
||||||
|
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one = 24;
|
||||||
|
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two = 32;
|
||||||
|
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four = 8;
|
||||||
|
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight = 4;
|
||||||
|
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen = 2;
|
||||||
|
rach_groupBconfigured = "ENABLE";
|
||||||
|
rach_ra_Msg3SizeGroupA = 56;
|
||||||
|
rach_messagePowerOffsetGroupB = "dB0";
|
||||||
|
rach_numberOfRA_PreamblesGroupA = 32;
|
||||||
|
rach_ra_ContentionResolutionTimer = 8;
|
||||||
|
rsrp_ThresholdSSB = 64;
|
||||||
|
rsrp_ThresholdSSB_SUL = 64;
|
||||||
|
prach_RootSequenceIndex_choice = "l839";
|
||||||
|
prach_RootSequenceIndex_l839 = 0;
|
||||||
|
prach_RootSequenceIndex_l139 = 0;
|
||||||
|
prach_msg1_SubcarrierSpacing = "kHz30";
|
||||||
|
restrictedSetConfig = "unrestrictedSet";
|
||||||
|
msg3_transformPrecoding = "ENABLE";
|
||||||
|
prach_ConfigurationIndex = 10;
|
||||||
|
prach_msg1_FDM = "one";
|
||||||
|
prach_msg1_FrequencyStart = 10;
|
||||||
|
zeroCorrelationZoneConfig = 10;
|
||||||
|
preambleReceivedTargetPower = -150;
|
||||||
|
preambleTransMax = 6;
|
||||||
|
powerRampingStep = "dB0";
|
||||||
|
ra_ResponseWindow = 8;
|
||||||
|
groupHoppingEnabledTransformPrecoding = "ENABLE";
|
||||||
|
msg3_DeltaPreamble = 0;
|
||||||
|
p0_NominalWithGrant = 0;
|
||||||
|
PUSCH_TimeDomainResourceAllocation_k2 = 0;
|
||||||
|
PUSCH_TimeDomainResourceAllocation_mappingType = "typeA";
|
||||||
|
PUSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0;
|
||||||
|
pucch_ResourceCommon = 0;
|
||||||
|
pucch_GroupHopping = "neither";
|
||||||
|
hoppingId = 0;
|
||||||
|
p0_nominal = -30;
|
||||||
|
PDSCH_TimeDomainResourceAllocation_k0 = 2;
|
||||||
|
PDSCH_TimeDomainResourceAllocation_mappingType = "typeA";
|
||||||
|
PDSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0;
|
||||||
|
rateMatchPatternId = 0;
|
||||||
|
RateMatchPattern_patternType = "bitmaps";
|
||||||
|
symbolsInResourceBlock = "oneSlot";
|
||||||
|
periodicityAndPattern = 2;
|
||||||
|
RateMatchPattern_controlResourceSet = 5;
|
||||||
|
RateMatchPattern_subcarrierSpacing = "kHz30";
|
||||||
|
RateMatchPattern_mode = "dynamic";
|
||||||
|
controlResourceSetZero = 0;
|
||||||
|
searchSpaceZero = 0;
|
||||||
|
searchSpaceSIB1 = 10;
|
||||||
|
searchSpaceOtherSystemInformation = 10;
|
||||||
|
pagingSearchSpace = 10;
|
||||||
|
ra_SearchSpace = 10;
|
||||||
|
PDCCH_common_controlResourceSetId = 5;
|
||||||
|
PDCCH_common_ControlResourceSet_duration = 2;
|
||||||
|
PDCCH_cce_REG_MappingType = "nonInterleaved";
|
||||||
|
PDCCH_reg_BundleSize = 3;
|
||||||
|
PDCCH_interleaverSize = 3;
|
||||||
|
PDCCH_shiftIndex = 10;
|
||||||
|
PDCCH_precoderGranularity = "sameAsREG-bundle";
|
||||||
|
PDCCH_TCI_StateId = 32;
|
||||||
|
tci_PresentInDCI = "ENABLE";
|
||||||
|
PDCCH_DMRS_ScramblingID = 0;
|
||||||
|
SearchSpaceId = 10;
|
||||||
|
commonSearchSpaces_controlResourceSetId = 5;
|
||||||
|
SearchSpace_monitoringSlotPeriodicityAndOffset_choice = "sl1";
|
||||||
|
SearchSpace_monitoringSlotPeriodicityAndOffset_value = 0;
|
||||||
|
SearchSpace_duration = 2;
|
||||||
|
SearchSpace_nrofCandidates_aggregationLevel1 = 0;
|
||||||
|
SearchSpace_nrofCandidates_aggregationLevel2 = 0;
|
||||||
|
SearchSpace_nrofCandidates_aggregationLevel4 = 0;
|
||||||
|
SearchSpace_nrofCandidates_aggregationLevel8 = 0;
|
||||||
|
SearchSpace_nrofCandidates_aggregationLevel16 = 0;
|
||||||
|
SearchSpace_searchSpaceType = "common";
|
||||||
|
Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1 = 1;
|
||||||
|
Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2 = 1;
|
||||||
|
Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4 = 1;
|
||||||
|
Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8 = 1;
|
||||||
|
Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16 = 1;
|
||||||
|
Common_dci_Format2_3_monitoringPeriodicity = 1;
|
||||||
|
Common_dci_Format2_3_nrofPDCCH_Candidates = 1;
|
||||||
|
ue_Specific__dci_Formats = "formats0-0-And-1-0";
|
||||||
|
RateMatchPatternLTE_CRS_carrierFreqDL = 6;
|
||||||
|
RateMatchPatternLTE_CRS_carrierBandwidthDL = 6;
|
||||||
|
RateMatchPatternLTE_CRS_nrofCRS_Ports = 1;
|
||||||
|
RateMatchPatternLTE_CRS_v_Shift = 0;
|
||||||
|
RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 1;
|
||||||
|
RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0;
|
||||||
|
RateMatchPatternLTE_CRS_subframeAllocation_choice = "oneFrame";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
srb1_parameters :
|
||||||
|
{
|
||||||
|
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
|
||||||
|
timer_poll_retransmit = 80;
|
||||||
|
|
||||||
|
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
|
||||||
|
timer_reordering = 35;
|
||||||
|
|
||||||
|
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
|
||||||
|
timer_status_prohibit = 0;
|
||||||
|
|
||||||
|
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
|
||||||
|
poll_pdu = 4;
|
||||||
|
|
||||||
|
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
|
||||||
|
poll_byte = 99999;
|
||||||
|
|
||||||
|
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
|
||||||
|
max_retx_threshold = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------- SCTP definitions
|
||||||
|
SCTP :
|
||||||
|
{
|
||||||
|
# Number of streams to use in input/output
|
||||||
|
SCTP_INSTREAMS = 2;
|
||||||
|
SCTP_OUTSTREAMS = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////// MME parameters:
|
||||||
|
mme_ip_address = ( { ipv4 = "192.168.12.26";
|
||||||
|
ipv6 = "192:168:30::17";
|
||||||
|
active = "yes";
|
||||||
|
preference = "ipv4";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
NETWORK_INTERFACES :
|
||||||
|
{
|
||||||
|
|
||||||
|
GNB_INTERFACE_NAME_FOR_S1_MME = "eth0";
|
||||||
|
GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
|
||||||
|
GNB_INTERFACE_NAME_FOR_S1U = "eth0";
|
||||||
|
GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
|
||||||
|
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
MACRLCs = (
|
||||||
|
{
|
||||||
|
num_cc = 1;
|
||||||
|
tr_s_preference = "local_L1";
|
||||||
|
tr_n_preference = "local_RRC";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
L1s = (
|
||||||
|
{
|
||||||
|
num_cc = 1;
|
||||||
|
tr_n_preference = "local_mac";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
RUs = (
|
||||||
|
{
|
||||||
|
local_rf = "yes"
|
||||||
|
nb_tx = 1
|
||||||
|
nb_rx = 1
|
||||||
|
att_tx = 0
|
||||||
|
att_rx = 0;
|
||||||
|
bands = [7];
|
||||||
|
max_pdschReferenceSignalPower = -27;
|
||||||
|
max_rxgain = 114;
|
||||||
|
eNB_instances = [0];
|
||||||
|
sdr_addrs = "addr=192.168.20.2,second_addr=192.168.10.2,mgmt_addr=192.168.20.2,clock_source=external,time_source=external";
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
THREAD_STRUCT = (
|
||||||
|
{
|
||||||
|
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||||
|
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
|
||||||
|
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||||
|
worker_config = "WORKER_ENABLE";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
NETWORK_CONTROLLER :
|
||||||
|
{
|
||||||
|
FLEXRAN_ENABLED = "no";
|
||||||
|
FLEXRAN_INTERFACE_NAME = "lo";
|
||||||
|
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
|
||||||
|
FLEXRAN_PORT = 2210;
|
||||||
|
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
|
||||||
|
FLEXRAN_AWAIT_RECONF = "no";
|
||||||
|
};
|
||||||
|
|
||||||
|
log_config :
|
||||||
|
{
|
||||||
|
global_log_level ="info";
|
||||||
|
global_log_verbosity ="medium";
|
||||||
|
hw_log_level ="info";
|
||||||
|
hw_log_verbosity ="medium";
|
||||||
|
phy_log_level ="info";
|
||||||
|
phy_log_verbosity ="medium";
|
||||||
|
mac_log_level ="info";
|
||||||
|
mac_log_verbosity ="high";
|
||||||
|
rlc_log_level ="info";
|
||||||
|
rlc_log_verbosity ="medium";
|
||||||
|
pdcp_log_level ="info";
|
||||||
|
pdcp_log_verbosity ="medium";
|
||||||
|
rrc_log_level ="info";
|
||||||
|
rrc_log_verbosity ="medium";
|
||||||
|
};
|
||||||
|
|
||||||
+862
-87
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,7 @@ function variant_usage {
|
|||||||
echo " --variant phy-sim OR -v3"
|
echo " --variant phy-sim OR -v3"
|
||||||
echo " --variant cppcheck OR -v4"
|
echo " --variant cppcheck OR -v4"
|
||||||
echo " --variant gnb-usrp OR -v5"
|
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 enb-ethernet OR -v7"
|
||||||
echo " --variant ue-ethernet OR -v8"
|
echo " --variant ue-ethernet OR -v8"
|
||||||
}
|
}
|
||||||
@@ -252,9 +252,9 @@ case $key in
|
|||||||
VM_NAME=ci-phy-sim
|
VM_NAME=ci-phy-sim
|
||||||
ARCHIVES_LOC=phy_sim
|
ARCHIVES_LOC=phy_sim
|
||||||
LOG_PATTERN=.Rel15.txt
|
LOG_PATTERN=.Rel15.txt
|
||||||
NB_PATTERN_FILES=8
|
NB_PATTERN_FILES=10
|
||||||
BUILD_OPTIONS="--phy_simulators"
|
BUILD_OPTIONS="--phy_simulators"
|
||||||
VM_MEMORY=4096
|
VM_MEMORY=8192
|
||||||
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
|
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
|
||||||
NBARGS=$[$NBARGS+256]
|
NBARGS=$[$NBARGS+256]
|
||||||
shift
|
shift
|
||||||
@@ -331,9 +331,9 @@ case $key in
|
|||||||
VM_NAME=ci-phy-sim
|
VM_NAME=ci-phy-sim
|
||||||
ARCHIVES_LOC=phy_sim
|
ARCHIVES_LOC=phy_sim
|
||||||
LOG_PATTERN=.Rel15.txt
|
LOG_PATTERN=.Rel15.txt
|
||||||
NB_PATTERN_FILES=8
|
NB_PATTERN_FILES=10
|
||||||
BUILD_OPTIONS="--phy_simulators"
|
BUILD_OPTIONS="--phy_simulators"
|
||||||
VM_MEMORY=4096
|
VM_MEMORY=8192
|
||||||
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
|
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
|
||||||
NBARGS=$[$NBARGS+256]
|
NBARGS=$[$NBARGS+256]
|
||||||
;;
|
;;
|
||||||
@@ -354,7 +354,7 @@ case $key in
|
|||||||
BUILD_OPTIONS="--gNB -w USRP"
|
BUILD_OPTIONS="--gNB -w USRP"
|
||||||
NBARGS=$[$NBARGS+256]
|
NBARGS=$[$NBARGS+256]
|
||||||
;;
|
;;
|
||||||
nu-ue-usrp)
|
nr-ue-usrp)
|
||||||
VM_NAME=ci-ue-nr-usrp
|
VM_NAME=ci-ue-nr-usrp
|
||||||
ARCHIVES_LOC=nrue_usrp
|
ARCHIVES_LOC=nrue_usrp
|
||||||
LOG_PATTERN=.Rel15.txt
|
LOG_PATTERN=.Rel15.txt
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
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>run-OAI-gNB-NR-UE-USRP</htmlTabRef>
|
||||||
|
<htmlTabName>run OAI gNB and OAI NR UE USRP</htmlTabName>
|
||||||
|
<htmlTabIcon>tasks</htmlTabIcon>
|
||||||
|
<TestCaseRequestedList>
|
||||||
|
090101 000001 090102 000001 090108 090109
|
||||||
|
</TestCaseRequestedList>
|
||||||
|
<TestCaseExclusionList></TestCaseExclusionList>
|
||||||
|
|
||||||
|
<testCase id="090101">
|
||||||
|
<class>Initialize_OAI_eNB</class>
|
||||||
|
<desc>Initialize gNB USRP</desc>
|
||||||
|
<Initialize_OAI_eNB_args>-O ../../../ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf</Initialize_OAI_eNB_args>
|
||||||
|
<air_interface>NR</air_interface>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="000001">
|
||||||
|
<class>IdleSleep</class>
|
||||||
|
<desc>Sleep</desc>
|
||||||
|
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="090102">
|
||||||
|
<class>Initialize_OAI_UE</class>
|
||||||
|
<desc>Initialize NR UE USRP</desc>
|
||||||
|
<Initialize_OAI_UE_args>-C 3510000000 --numerology 1 -r 106 --phy-test --usrp-args "addr=192.168.30.2,clock_source=external,time_source=external" --threadoffset 16</Initialize_OAI_UE_args>
|
||||||
|
<air_interface>NR</air_interface>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="090108">
|
||||||
|
<class>Terminate_OAI_UE</class>
|
||||||
|
<desc>Terminate NR UE</desc>
|
||||||
|
<air_interface>NR</air_interface>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="090109">
|
||||||
|
<class>Terminate_eNB</class>
|
||||||
|
<desc>Terminate gNB</desc>
|
||||||
|
<air_interface>NR</air_interface>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
</testCaseList>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
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>gnb-build-tab</htmlTabRef>
|
||||||
|
<htmlTabName>Build-gNB</htmlTabName>
|
||||||
|
<htmlTabIcon>wrench</htmlTabIcon>
|
||||||
|
<TestCaseRequestedList>
|
||||||
|
010101
|
||||||
|
</TestCaseRequestedList>
|
||||||
|
<TestCaseExclusionList></TestCaseExclusionList>
|
||||||
|
|
||||||
|
<testCase id="010101">
|
||||||
|
<mode>TesteNB</mode>
|
||||||
|
<class>Build_eNB</class>
|
||||||
|
<desc>Build gNB (USRP)</desc>
|
||||||
|
<Build_eNB_args>--gNB -w USRP</Build_eNB_args>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
</testCaseList>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
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>nr-ue-build-tab</htmlTabRef>
|
||||||
|
<htmlTabName>Build-NR-UE</htmlTabName>
|
||||||
|
<htmlTabIcon>wrench</htmlTabIcon>
|
||||||
|
<TestCaseRequestedList>
|
||||||
|
010102
|
||||||
|
</TestCaseRequestedList>
|
||||||
|
<TestCaseExclusionList></TestCaseExclusionList>
|
||||||
|
|
||||||
|
<testCase id="010102">
|
||||||
|
<mode>TestUE</mode>
|
||||||
|
<class>Build_OAI_UE</class>
|
||||||
|
<desc>Build NR UE (USRP)</desc>
|
||||||
|
<Build_OAI_UE_args>--nrUE -w USRP</Build_OAI_UE_args>
|
||||||
|
<clean_repository>false</clean_repository>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
</testCaseList>
|
||||||
@@ -167,7 +167,7 @@ endif()
|
|||||||
|
|
||||||
#
|
#
|
||||||
set(CMAKE_C_FLAGS
|
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!
|
# add autotools definitions that were maybe used!
|
||||||
set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
|
set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
|
||||||
set(CMAKE_C_FLAGS
|
set(CMAKE_C_FLAGS
|
||||||
@@ -671,7 +671,7 @@ add_boolean_option(EXMIMO_IOT True "????")
|
|||||||
add_boolean_option(LOCALIZATION False "???")
|
add_boolean_option(LOCALIZATION False "???")
|
||||||
add_integer_option(MAX_NUM_CCs 1 "????")
|
add_integer_option(MAX_NUM_CCs 1 "????")
|
||||||
add_boolean_option(MU_RECEIVER False "????")
|
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_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(PHY_EMUL False "not clear: must remain False for dlsim")
|
||||||
add_boolean_option(SMBV False "Rohde&Schwarz SMBV100A vector signal generator")
|
add_boolean_option(SMBV False "Rohde&Schwarz SMBV100A vector signal generator")
|
||||||
@@ -754,6 +754,7 @@ include_directories("${OPENAIR_BIN_DIR}")
|
|||||||
|
|
||||||
# Legacy exact order
|
# Legacy exact order
|
||||||
|
|
||||||
|
include_directories("${OPENAIR_DIR}/executables")
|
||||||
include_directories("${OPENAIR2_DIR}/COMMON")
|
include_directories("${OPENAIR2_DIR}/COMMON")
|
||||||
include_directories("${OPENAIR2_DIR}/UTIL")
|
include_directories("${OPENAIR2_DIR}/UTIL")
|
||||||
include_directories("${OPENAIR2_DIR}/UTIL/LOG")
|
include_directories("${OPENAIR2_DIR}/UTIL/LOG")
|
||||||
@@ -1118,15 +1119,19 @@ set(PHY_POLARSRC
|
|||||||
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_procedures.c
|
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_procedures.c
|
||||||
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c
|
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c
|
||||||
)
|
)
|
||||||
|
set(PHY_SMALLBLOCKSRC
|
||||||
|
${OPENAIR1_DIR}/PHY/CODING/nrSmallBlock/encodeSmallBlock.c
|
||||||
|
${OPENAIR1_DIR}/PHY/CODING/nrSmallBlock/decodeSmallBlock.c
|
||||||
|
)
|
||||||
set(PHY_TURBOIF
|
set(PHY_TURBOIF
|
||||||
${OPENAIR1_DIR}/PHY/CODING/coding_load.c
|
${OPENAIR1_DIR}/PHY/CODING/coding_load.c
|
||||||
)
|
)
|
||||||
set(PHY_LDPCSRC
|
set(PHY_LDPCSRC
|
||||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
|
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
|
||||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
|
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
|
||||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c
|
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c
|
||||||
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
|
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(coding MODULE ${PHY_TURBOSRC} )
|
add_library(coding MODULE ${PHY_TURBOSRC} )
|
||||||
set(PHY_SRC_COMMON
|
set(PHY_SRC_COMMON
|
||||||
@@ -1275,6 +1280,7 @@ set(PHY_SRC_UE
|
|||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.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_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_tbs_tools.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
||||||
@@ -1291,6 +1297,7 @@ set(PHY_SRC_UE
|
|||||||
${OPENAIR1_DIR}/PHY/TOOLS/time_meas.c
|
${OPENAIR1_DIR}/PHY/TOOLS/time_meas.c
|
||||||
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
|
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
|
||||||
${PHY_POLARSRC}
|
${PHY_POLARSRC}
|
||||||
|
${PHY_SMALLBLOCKSRC}
|
||||||
${PHY_LDPCSRC}
|
${PHY_LDPCSRC}
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c # added by prasanth
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c # added by prasanth
|
||||||
)
|
)
|
||||||
@@ -1305,6 +1312,7 @@ set(PHY_SRC_UE
|
|||||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
|
${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_pbch.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.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_decoding.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
|
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
||||||
@@ -1335,6 +1343,7 @@ set(PHY_SRC_UE
|
|||||||
${OPENAIR1_DIR}/PHY/INIT/nr_init_ue.c
|
${OPENAIR1_DIR}/PHY/INIT/nr_init_ue.c
|
||||||
# ${OPENAIR1_DIR}/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
|
# ${OPENAIR1_DIR}/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
|
||||||
${PHY_POLARSRC}
|
${PHY_POLARSRC}
|
||||||
|
${PHY_SMALLBLOCKSRC}
|
||||||
${PHY_LDPCSRC}
|
${PHY_LDPCSRC}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1576,6 +1585,7 @@ add_library(L2
|
|||||||
${ENB_APP_SRC}
|
${ENB_APP_SRC}
|
||||||
)
|
)
|
||||||
add_dependencies(L2 rrc_flag s1ap_flag x2_flag)
|
add_dependencies(L2 rrc_flag s1ap_flag x2_flag)
|
||||||
|
|
||||||
add_library(MAC_NR
|
add_library(MAC_NR
|
||||||
${MAC_NR_SRC}
|
${MAC_NR_SRC}
|
||||||
)
|
)
|
||||||
@@ -1594,7 +1604,6 @@ add_dependencies(S1AP_LIB nr_rrc_flag s1ap_flag)
|
|||||||
add_library(L2_UE
|
add_library(L2_UE
|
||||||
${L2_SRC_UE}
|
${L2_SRC_UE}
|
||||||
${MAC_SRC_UE}
|
${MAC_SRC_UE}
|
||||||
#${MAC_NR_SRC_UE}
|
|
||||||
)
|
)
|
||||||
if (NOT ${NOS1})
|
if (NOT ${NOS1})
|
||||||
target_compile_definitions(L2_UE PUBLIC -DPDCP_USE_NETLINK)
|
target_compile_definitions(L2_UE PUBLIC -DPDCP_USE_NETLINK)
|
||||||
@@ -1603,44 +1612,13 @@ endif()
|
|||||||
add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag)
|
add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag)
|
||||||
|
|
||||||
add_library( NR_L2_UE
|
add_library( NR_L2_UE
|
||||||
#${L2_SRC_UE}
|
|
||||||
${NR_L2_SRC_UE}
|
${NR_L2_SRC_UE}
|
||||||
${MAC_NR_SRC_UE}
|
${MAC_NR_SRC_UE}
|
||||||
#${MAC_SRC_UE}
|
)
|
||||||
)
|
|
||||||
|
|
||||||
set ( NR_LTE_UE_REUSE_SRC
|
add_library( MAC_NR_COMMON
|
||||||
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_timefreq.c
|
${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.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}
|
|
||||||
)
|
|
||||||
|
|
||||||
include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE")
|
include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE")
|
||||||
include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE")
|
include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE")
|
||||||
@@ -2137,11 +2115,18 @@ if (${XFORMS})
|
|||||||
${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_scope.c
|
${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_scope.c
|
||||||
)
|
)
|
||||||
set(XFORMS_SOURCE_SOFTMODEM
|
set(XFORMS_SOURCE_SOFTMODEM
|
||||||
${OPENAIR_TARGETS}/RT/USER/stats.c
|
${OPENAIR_DIR}/targets/RT/USER/stats.c
|
||||||
)
|
)
|
||||||
set(XFORMS_LIBRARIES "forms")
|
set(XFORMS_LIBRARIES "forms")
|
||||||
endif (${XFORMS})
|
endif (${XFORMS})
|
||||||
|
|
||||||
|
include_directories ("/usr/include/X11")
|
||||||
|
|
||||||
|
add_library(gnbScope MODULE
|
||||||
|
${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_scope.c
|
||||||
|
)
|
||||||
|
target_link_libraries(gnbScope forms)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
|
set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
|
||||||
|
|
||||||
#include T directory even if the T is off because T macros are in the code
|
#include T directory even if the T is off because T macros are in the code
|
||||||
@@ -2185,6 +2170,24 @@ add_definitions(-DASN1_MINIMUM_VERSION=924)
|
|||||||
#################################
|
#################################
|
||||||
# add executables for operation
|
# add executables for operation
|
||||||
#################################
|
#################################
|
||||||
|
add_library(minimal_lib
|
||||||
|
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||||
|
${OPENAIR_DIR}/common/utils/LOG/log.c
|
||||||
|
${OPENAIR_DIR}/common/config/config_userapi.c
|
||||||
|
${OPENAIR_DIR}/common/config/config_load_configmodule.c
|
||||||
|
${OPENAIR_DIR}/common/config/config_cmdline.c
|
||||||
|
${OPENAIR_DIR}/common/utils/minimal_stub.c
|
||||||
|
)
|
||||||
|
target_link_libraries(minimal_lib pthread dl)
|
||||||
|
|
||||||
|
add_executable(replay_node
|
||||||
|
${OPENAIR_TARGETS}/ARCH/rfsimulator/stored_node.c
|
||||||
|
)
|
||||||
|
target_link_libraries (replay_node minimal_lib)
|
||||||
|
|
||||||
|
add_executable(measurement_display
|
||||||
|
${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c)
|
||||||
|
target_link_libraries (measurement_display minimal_lib)
|
||||||
|
|
||||||
# lte-softmodem is both eNB and UE implementation
|
# lte-softmodem is both eNB and UE implementation
|
||||||
###################################################
|
###################################################
|
||||||
@@ -2347,19 +2350,16 @@ add_executable(nr-softmodem
|
|||||||
${nr_rrc_h}
|
${nr_rrc_h}
|
||||||
${s1ap_h}
|
${s1ap_h}
|
||||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
${OPENAIR_DIR}/executables/nr-gnb.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/nr-gnb.c
|
${OPENAIR_DIR}/executables/nr-ru.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/nr-ru.c
|
${OPENAIR_DIR}/executables/nr-softmodem.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/nr-softmodem.c
|
|
||||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||||
${OPENAIR_TARGETS}/COMMON/create_nr_tasks.c
|
|
||||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||||
${OPENAIR_DIR}/common/utils/utils.c
|
${OPENAIR_DIR}/common/utils/utils.c
|
||||||
${OPENAIR_DIR}/common/utils/system.c
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
${GTPU_need_ITTI}
|
${GTPU_need_ITTI}
|
||||||
${XFORMS_SOURCE}
|
${XFORMS_SOURCE_NR}
|
||||||
${XFORMS_SOURCE_SOFTMODEM}
|
|
||||||
${T_SOURCE}
|
${T_SOURCE}
|
||||||
${CONFIG_SOURCES}
|
${CONFIG_SOURCES}
|
||||||
${SHLIB_LOADER_SOURCES}
|
${SHLIB_LOADER_SOURCES}
|
||||||
@@ -2369,7 +2369,7 @@ target_link_libraries (nr-softmodem
|
|||||||
-Wl,--start-group
|
-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
|
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}
|
${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
|
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
|
||||||
-Wl,--end-group z dl)
|
-Wl,--end-group z dl)
|
||||||
|
|
||||||
@@ -2385,13 +2385,10 @@ add_executable(nr-softmodem-nos1
|
|||||||
${rrc_h}
|
${rrc_h}
|
||||||
${s1ap_h}
|
${s1ap_h}
|
||||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
${OPENAIR_DIR}/executables/nr-gnb.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/nr-gnb.c
|
${OPENAIR_DIR}/executables/nr-ru.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/nr-ru.c
|
${OPENAIR_DIR}/executables/nr-softmodem.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/nr-softmodem.c
|
|
||||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||||
${OPENAIR_TARGETS}/COMMON/create_tasks.c
|
|
||||||
${OPENAIR_TARGETS}/COMMON/create_nr_tasks.c
|
|
||||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||||
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||||
@@ -2399,8 +2396,7 @@ add_executable(nr-softmodem-nos1
|
|||||||
${OPENAIR_DIR}/common/utils/utils.c
|
${OPENAIR_DIR}/common/utils/utils.c
|
||||||
${OPENAIR_DIR}/common/utils/system.c
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
${GTPU_need_ITTI}
|
${GTPU_need_ITTI}
|
||||||
${XFORMS_SOURCE}
|
${XFORMS_SOURCE_NR}
|
||||||
${XFORMS_SOURCE_SOFTMODEM}
|
|
||||||
${T_SOURCE}
|
${T_SOURCE}
|
||||||
${CONFIG_SOURCES}
|
${CONFIG_SOURCES}
|
||||||
${SHLIB_LOADER_SOURCES}
|
${SHLIB_LOADER_SOURCES}
|
||||||
@@ -2410,7 +2406,7 @@ target_link_libraries (nr-softmodem-nos1
|
|||||||
-Wl,--start-group
|
-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
|
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}
|
${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
|
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
|
||||||
-Wl,--end-group z dl)
|
-Wl,--end-group z dl)
|
||||||
|
|
||||||
@@ -2426,18 +2422,16 @@ add_executable(nr-uesoftmodem
|
|||||||
${rrc_h}
|
${rrc_h}
|
||||||
${s1ap_h}
|
${s1ap_h}
|
||||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/nr-ue.c
|
${OPENAIR_DIR}/executables/nr-uesoftmodem.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/nr-uesoftmodem.c
|
${OPENAIR_DIR}/executables/nr-ue.c
|
||||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||||
# ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
|
|
||||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||||
${OPENAIR_DIR}/common/utils/utils.c
|
${OPENAIR_DIR}/common/utils/utils.c
|
||||||
${OPENAIR_DIR}/common/utils/system.c
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
${XFORMS_SOURCE_NR}
|
${XFORMS_SOURCE_NR}
|
||||||
${XFORMS_SOURCE_SOFTMODEM}
|
|
||||||
${T_SOURCE}
|
${T_SOURCE}
|
||||||
${CONFIG_SOURCES}
|
${CONFIG_SOURCES}
|
||||||
${SHLIB_LOADER_SOURCES}
|
${SHLIB_LOADER_SOURCES}
|
||||||
@@ -2445,7 +2439,7 @@ add_executable(nr-uesoftmodem
|
|||||||
|
|
||||||
target_link_libraries (nr-uesoftmodem
|
target_link_libraries (nr-uesoftmodem
|
||||||
-Wl,--start-group
|
-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}
|
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
|
||||||
-Wl,--end-group z dl)
|
-Wl,--end-group z dl)
|
||||||
|
|
||||||
@@ -2461,17 +2455,14 @@ add_executable(nr-uesoftmodem-nos1
|
|||||||
${rrc_h}
|
${rrc_h}
|
||||||
${s1ap_h}
|
${s1ap_h}
|
||||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
${OPENAIR_DIR}/executables/nr-ue.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/nr-ue.c
|
${OPENAIR_DIR}/executables/nr-uesoftmodem.c
|
||||||
${OPENAIR_TARGETS}/RT/USER/nr-uesoftmodem.c
|
|
||||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||||
#${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
|
|
||||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||||
${OPENAIR_DIR}/common/utils/utils.c
|
${OPENAIR_DIR}/common/utils/utils.c
|
||||||
${OPENAIR_DIR}/common/utils/system.c
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
${XFORMS_SOURCE_NR}
|
${XFORMS_SOURCE_NR}
|
||||||
${XFORMS_SOURCE_SOFTMODEM}
|
|
||||||
${T_SOURCE}
|
${T_SOURCE}
|
||||||
${CONFIG_SOURCES}
|
${CONFIG_SOURCES}
|
||||||
${SHLIB_LOADER_SOURCES}
|
${SHLIB_LOADER_SOURCES}
|
||||||
@@ -2479,7 +2470,7 @@ add_executable(nr-uesoftmodem-nos1
|
|||||||
|
|
||||||
target_link_libraries (nr-uesoftmodem-nos1
|
target_link_libraries (nr-uesoftmodem-nos1
|
||||||
-Wl,--start-group
|
-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}
|
${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
|
||||||
-Wl,--end-group z dl)
|
-Wl,--end-group z dl)
|
||||||
|
|
||||||
@@ -2523,6 +2514,7 @@ target_link_libraries (nr-uesoftmodem-nos1 ${T_LIB})
|
|||||||
add_executable(dlsim_tm4
|
add_executable(dlsim_tm4
|
||||||
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/dlsim_tm4.c
|
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/dlsim_tm4.c
|
||||||
${OPENAIR1_DIR}/PHY/TOOLS/lte_phy_scope_tm4.c
|
${OPENAIR1_DIR}/PHY/TOOLS/lte_phy_scope_tm4.c
|
||||||
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
${T_SOURCE}
|
${T_SOURCE}
|
||||||
)
|
)
|
||||||
target_link_libraries (dlsim_tm4
|
target_link_libraries (dlsim_tm4
|
||||||
@@ -2535,6 +2527,12 @@ add_executable(polartest
|
|||||||
${OPENAIR_DIR}/common/utils/backtrace.c)
|
${OPENAIR_DIR}/common/utils/backtrace.c)
|
||||||
target_link_libraries(polartest SIMU PHY PHY_NR PHY_COMMON m ${ATLAS_LIBRARIES})
|
target_link_libraries(polartest SIMU PHY PHY_NR PHY_COMMON m ${ATLAS_LIBRARIES})
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(smallblocktest
|
||||||
|
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c
|
||||||
|
${OPENAIR_DIR}/common/utils/backtrace.c)
|
||||||
|
target_link_libraries(smallblocktest SIMU PHY PHY_NR PHY_COMMON m ${ATLAS_LIBRARIES})
|
||||||
|
|
||||||
add_executable(ldpctest
|
add_executable(ldpctest
|
||||||
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
|
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
|
||||||
${OPENAIR_DIR}/common/utils/backtrace.c)
|
${OPENAIR_DIR}/common/utils/backtrace.c)
|
||||||
@@ -2543,12 +2541,14 @@ target_link_libraries(ldpctest SIMU PHY PHY_NR m ${ATLAS_LIBRARIES})
|
|||||||
add_executable(nr_dlschsim
|
add_executable(nr_dlschsim
|
||||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c
|
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c
|
||||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||||
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
${T_SOURCE})
|
${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)
|
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
|
add_executable(nr_pbchsim
|
||||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c
|
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c
|
||||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||||
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
${T_SOURCE})
|
${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)
|
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)
|
||||||
|
|
||||||
@@ -2563,8 +2563,15 @@ target_link_libraries(nr_pucchsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR
|
|||||||
add_executable(nr_dlsim
|
add_executable(nr_dlsim
|
||||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c
|
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c
|
||||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||||
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
${T_SOURCE})
|
${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)
|
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)
|
foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
|
||||||
@@ -2572,6 +2579,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
|
|||||||
add_executable(${myExe}
|
add_executable(${myExe}
|
||||||
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
|
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
|
||||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||||
|
${OPENAIR_DIR}/common/utils/system.c
|
||||||
${XFORMS_SOURCE}
|
${XFORMS_SOURCE}
|
||||||
${T_SOURCE}
|
${T_SOURCE}
|
||||||
${CONFIG_SOURCES}
|
${CONFIG_SOURCES}
|
||||||
@@ -2697,7 +2705,9 @@ L2
|
|||||||
L2_NR
|
L2_NR
|
||||||
L2_UE
|
L2_UE
|
||||||
NR_L2_UE
|
NR_L2_UE
|
||||||
NR_LTE_UE_REUSE_LIB
|
MAC_NR_COMMON
|
||||||
|
MAC_NR
|
||||||
|
MAC_UE_NR
|
||||||
CN_UTILS
|
CN_UTILS
|
||||||
GTPV1U
|
GTPV1U
|
||||||
SCTP_CLIENT
|
SCTP_CLIENT
|
||||||
|
|||||||
@@ -1117,6 +1117,49 @@
|
|||||||
<nruns>3</nruns>
|
<nruns>3</nruns>
|
||||||
</testCase>
|
</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 -s -4 -d 1 -i 10000
|
||||||
|
-l 6 -s -4 -d 1 -i 10000
|
||||||
|
-l 7 -s -4 -d 1 -i 10000
|
||||||
|
-l 11 -s -4 -d 1 -i 10000</main_exec_args>
|
||||||
|
<tags>smallblocktest.test1 smallblocktest.test2 smallblocktest.test3 smallblocktest.test4</tags>
|
||||||
|
<search_expr_true>BLER= 0.000000</search_expr_true>
|
||||||
|
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
|
||||||
|
<nruns>3</nruns>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
|
|
||||||
|
<testCase id="015108">
|
||||||
|
<class>execution</class>
|
||||||
|
<desc>nr_ulschsim 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_ulschsim.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_ulschsim.test1 nr_ulschsim.test2 nr_ulschsim.test3</tags>
|
||||||
|
<search_expr_true>PUSCH test OK</search_expr_true>
|
||||||
|
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
|
||||||
|
<nruns>3</nruns>
|
||||||
|
</testCase>
|
||||||
|
|
||||||
<testCase id="015110">
|
<testCase id="015110">
|
||||||
<class>execution</class>
|
<class>execution</class>
|
||||||
<desc>dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB),
|
<desc>dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB),
|
||||||
|
|||||||
@@ -80,8 +80,6 @@ function print_help() {
|
|||||||
This program installs OpenAirInterface Software
|
This program installs OpenAirInterface Software
|
||||||
You should have ubuntu 16.xx or 18.04 updated
|
You should have ubuntu 16.xx or 18.04 updated
|
||||||
Options
|
Options
|
||||||
-h
|
|
||||||
This help
|
|
||||||
-c | --clean
|
-c | --clean
|
||||||
Erase all files to make a rebuild from start
|
Erase all files to make a rebuild from start
|
||||||
-C | --clean-all
|
-C | --clean-all
|
||||||
@@ -422,11 +420,6 @@ function main() {
|
|||||||
|
|
||||||
CMAKE_CMD="$CMAKE_CMD .."
|
CMAKE_CMD="$CMAKE_CMD .."
|
||||||
echo_info "CMAKE_CMD=$CMAKE_CMD"
|
echo_info "CMAKE_CMD=$CMAKE_CMD"
|
||||||
if [ "$eNB" = "1" -o "$gNB" = "1" ] && [ "$UE" = "1" -o "$nrUE" = "1" ]; then
|
|
||||||
echo_error "Cannot build UE/nrUE and eNB/gNB on one build_oai execution"
|
|
||||||
echo_error "use 2 build_oai invocations"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# check validity of HW and TP parameters for eNB / gNB
|
# check validity of HW and TP parameters for eNB / gNB
|
||||||
@@ -691,7 +684,7 @@ function main() {
|
|||||||
echo_info "Compiling unitary tests simulators"
|
echo_info "Compiling unitary tests simulators"
|
||||||
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
|
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
|
||||||
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
|
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
|
||||||
simlist="nr_pucchsim dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim nr_dlsim"
|
simlist="nr_pucchsim dlsim ulsim polartest ldpctest smallblocktest nr_pbchsim nr_dlschsim nr_dlsim nr_ulschsim"
|
||||||
for f in $simlist ; do
|
for f in $simlist ; do
|
||||||
compilations \
|
compilations \
|
||||||
phy_simulators $f \
|
phy_simulators $f \
|
||||||
|
|||||||
@@ -683,7 +683,7 @@ install_asn1c_from_source(){
|
|||||||
# better to use a given commit than a branch in case the branch
|
# better to use a given commit than a branch in case the branch
|
||||||
# is updated and requires modifications in the source of OAI
|
# is updated and requires modifications in the source of OAI
|
||||||
#git checkout velichkov_s1ap_plus_option_group
|
#git checkout velichkov_s1ap_plus_option_group
|
||||||
git checkout d3aed06bb2bec7df1b5c6d0333f8c7dfc5993372
|
git checkout f12568d617dbf48497588f8e227d70388fa217c9
|
||||||
autoreconf -iv
|
autoreconf -iv
|
||||||
./configure
|
./configure
|
||||||
make -j`nproc`
|
make -j`nproc`
|
||||||
|
|||||||
+262
-322
@@ -40,7 +40,7 @@
|
|||||||
#include "assertions.h"
|
#include "assertions.h"
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
#if defined(ENABLE_ITTI)
|
||||||
# include "intertask_interface.h"
|
#include "intertask_interface.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
@@ -75,16 +75,14 @@ char *log_level_highlight_start[] = {LOG_RED, LOG_ORANGE, "", LOG_BLUE, LOG_CYBL
|
|||||||
char *log_level_highlight_end[] = {LOG_RESET,LOG_RESET,LOG_RESET, LOG_RESET,LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
|
char *log_level_highlight_end[] = {LOG_RESET,LOG_RESET,LOG_RESET, LOG_RESET,LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
|
||||||
|
|
||||||
|
|
||||||
int write_file_matlab(const char *fname,const char *vname,void *data,int length,int dec,char format)
|
int write_file_matlab(const char *fname,const char *vname,void *data,int length,int dec,char format) {
|
||||||
{
|
|
||||||
|
|
||||||
FILE *fp=NULL;
|
FILE *fp=NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
//printf("Writing %d elements of type %d to %s\n",length,format,fname);
|
|
||||||
|
|
||||||
|
//printf("Writing %d elements of type %d to %s\n",length,format,fname);
|
||||||
|
|
||||||
if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) {
|
if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) {
|
||||||
fp = fopen(fname,"a+");
|
fp = fopen(fname,"a+");
|
||||||
@@ -92,8 +90,6 @@ int write_file_matlab(const char *fname,const char *vname,void *data,int length,
|
|||||||
fp = fopen(fname,"w+");
|
fp = fopen(fname,"w+");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (fp== NULL) {
|
if (fp== NULL) {
|
||||||
printf("[OPENAIR][FILE OUTPUT] Cannot open file %s\n",fname);
|
printf("[OPENAIR][FILE OUTPUT] Cannot open file %s\n",fname);
|
||||||
return(-1);
|
return(-1);
|
||||||
@@ -102,121 +98,108 @@ int write_file_matlab(const char *fname,const char *vname,void *data,int length,
|
|||||||
if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14)
|
if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14)
|
||||||
fprintf(fp,"%s = [",vname);
|
fprintf(fp,"%s = [",vname);
|
||||||
|
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 0: // real 16-bit
|
case 0: // real 16-bit
|
||||||
|
for (i=0; i<length; i+=dec) {
|
||||||
|
fprintf(fp,"%d\n",((short *)data)[i]);
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i<length; i+=dec) {
|
break;
|
||||||
fprintf(fp,"%d\n",((short *)data)[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
case 1: // complex 16-bit
|
||||||
|
case 13:
|
||||||
|
case 14:
|
||||||
|
case 15:
|
||||||
|
for (i=0; i<length<<1; i+=(2*dec)) {
|
||||||
|
fprintf(fp,"%d + j*(%d)\n",((short *)data)[i],((short *)data)[i+1]);
|
||||||
|
}
|
||||||
|
|
||||||
case 1: // complex 16-bit
|
break;
|
||||||
case 13:
|
|
||||||
case 14:
|
|
||||||
case 15:
|
|
||||||
|
|
||||||
for (i=0; i<length<<1; i+=(2*dec)) {
|
case 2: // real 32-bit
|
||||||
fprintf(fp,"%d + j*(%d)\n",((short *)data)[i],((short *)data)[i+1]);
|
for (i=0; i<length; i+=dec) {
|
||||||
|
fprintf(fp,"%d\n",((int *)data)[i]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
case 3: // complex 32-bit
|
||||||
|
for (i=0; i<length<<1; i+=(2*dec)) {
|
||||||
|
fprintf(fp,"%d + j*(%d)\n",((int *)data)[i],((int *)data)[i+1]);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // real 32-bit
|
case 4: // real 8-bit
|
||||||
for (i=0; i<length; i+=dec) {
|
for (i=0; i<length; i+=dec) {
|
||||||
fprintf(fp,"%d\n",((int *)data)[i]);
|
fprintf(fp,"%d\n",((char *)data)[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // complex 32-bit
|
case 5: // complex 8-bit
|
||||||
for (i=0; i<length<<1; i+=(2*dec)) {
|
for (i=0; i<length<<1; i+=(2*dec)) {
|
||||||
fprintf(fp,"%d + j*(%d)\n",((int *)data)[i],((int *)data)[i+1]);
|
fprintf(fp,"%d + j*(%d)\n",((char *)data)[i],((char *)data)[i+1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // real 8-bit
|
case 6: // real 64-bit
|
||||||
for (i=0; i<length; i+=dec) {
|
for (i=0; i<length; i+=dec) {
|
||||||
fprintf(fp,"%d\n",((char *)data)[i]);
|
fprintf(fp,"%lld\n",((long long *)data)[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: // complex 8-bit
|
case 7: // real double
|
||||||
for (i=0; i<length<<1; i+=(2*dec)) {
|
for (i=0; i<length; i+=dec) {
|
||||||
fprintf(fp,"%d + j*(%d)\n",((char *)data)[i],((char *)data)[i+1]);
|
fprintf(fp,"%g\n",((double *)data)[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6: // real 64-bit
|
case 8: // complex double
|
||||||
for (i=0; i<length; i+=dec) {
|
for (i=0; i<length<<1; i+=2*dec) {
|
||||||
fprintf(fp,"%lld\n",((long long*)data)[i]);
|
fprintf(fp,"%g + j*(%g)\n",((double *)data)[i], ((double *)data)[i+1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: // real double
|
case 9: // real unsigned 8-bit
|
||||||
for (i=0; i<length; i+=dec) {
|
for (i=0; i<length; i+=dec) {
|
||||||
fprintf(fp,"%g\n",((double *)data)[i]);
|
fprintf(fp,"%d\n",((unsigned char *)data)[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8: // complex double
|
case 10 : // case eren 16 bit complex :
|
||||||
for (i=0; i<length<<1; i+=2*dec) {
|
for (i=0; i<length<<1; i+=(2*dec)) {
|
||||||
fprintf(fp,"%g + j*(%g)\n",((double *)data)[i], ((double *)data)[i+1]);
|
if((i < 2*(length-1)) && (i > 0))
|
||||||
}
|
fprintf(fp,"%d + j*(%d),",((short *)data)[i],((short *)data)[i+1]);
|
||||||
|
else if (i == 2*(length-1))
|
||||||
|
fprintf(fp,"%d + j*(%d);",((short *)data)[i],((short *)data)[i+1]);
|
||||||
|
else if (i == 0)
|
||||||
|
fprintf(fp,"\n%d + j*(%d),",((short *)data)[i],((short *)data)[i+1]);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9: // real unsigned 8-bit
|
case 11 : //case eren 16 bit real for channel magnitudes:
|
||||||
for (i=0; i<length; i+=dec) {
|
for (i=0; i<length; i+=dec) {
|
||||||
fprintf(fp,"%d\n",((unsigned char *)data)[i]);
|
if((i <(length-1))&& (i > 0))
|
||||||
}
|
fprintf(fp,"%d,",((short *)data)[i]);
|
||||||
|
else if (i == (length-1))
|
||||||
|
fprintf(fp,"%d;",((short *)data)[i]);
|
||||||
|
else if (i == 0)
|
||||||
|
fprintf(fp,"\n%d,",((short *)data)[i]);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
printf("\n eren: length :%d",length);
|
||||||
|
break;
|
||||||
|
|
||||||
case 10 : // case eren 16 bit complex :
|
|
||||||
|
|
||||||
for (i=0; i<length<<1; i+=(2*dec)) {
|
|
||||||
|
|
||||||
if((i < 2*(length-1)) && (i > 0))
|
|
||||||
fprintf(fp,"%d + j*(%d),",((short *)data)[i],((short *)data)[i+1]);
|
|
||||||
else if (i == 2*(length-1))
|
|
||||||
fprintf(fp,"%d + j*(%d);",((short *)data)[i],((short *)data)[i+1]);
|
|
||||||
else if (i == 0)
|
|
||||||
fprintf(fp,"\n%d + j*(%d),",((short *)data)[i],((short *)data)[i+1]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 11 : //case eren 16 bit real for channel magnitudes:
|
|
||||||
for (i=0; i<length; i+=dec) {
|
|
||||||
|
|
||||||
if((i <(length-1))&& (i > 0))
|
|
||||||
fprintf(fp,"%d,",((short *)data)[i]);
|
|
||||||
else if (i == (length-1))
|
|
||||||
fprintf(fp,"%d;",((short *)data)[i]);
|
|
||||||
else if (i == 0)
|
|
||||||
fprintf(fp,"\n%d,",((short *)data)[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n eren: length :%d",length);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 12 : // case eren for log2_maxh real unsigned 8 bit
|
|
||||||
fprintf(fp,"%d \n",((unsigned char *)&data)[0]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
case 12 : // case eren for log2_maxh real unsigned 8 bit
|
||||||
|
fprintf(fp,"%d \n",((unsigned char *)&data)[0]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format != 10 && format !=11 && format !=12 && format != 13 && format != 15) {
|
if (format != 10 && format !=11 && format !=12 && format != 13 && format != 15) {
|
||||||
@@ -235,131 +218,141 @@ int write_file_matlab(const char *fname,const char *vname,void *data,int length,
|
|||||||
void log_getconfig(log_t *g_log) {
|
void log_getconfig(log_t *g_log) {
|
||||||
char *gloglevel = NULL;
|
char *gloglevel = NULL;
|
||||||
int consolelog ;
|
int consolelog ;
|
||||||
|
|
||||||
|
|
||||||
paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC;
|
paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC;
|
||||||
paramdef_t logparams_level[MAX_LOG_PREDEF_COMPONENTS];
|
paramdef_t logparams_level[MAX_LOG_PREDEF_COMPONENTS];
|
||||||
paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS];
|
paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS];
|
||||||
paramdef_t logparams_debug[sizeof(log_maskmap)/sizeof(mapping)];
|
paramdef_t logparams_debug[sizeof(log_maskmap)/sizeof(mapping)];
|
||||||
paramdef_t logparams_dump[sizeof(log_maskmap)/sizeof(mapping)];
|
paramdef_t logparams_dump[sizeof(log_maskmap)/sizeof(mapping)];
|
||||||
|
|
||||||
int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX);
|
int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX);
|
||||||
|
|
||||||
if (ret <0) {
|
if (ret <0) {
|
||||||
fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed");
|
fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set LOG display options (enable/disable color, thread name, level ) */
|
/* set LOG display options (enable/disable color, thread name, level ) */
|
||||||
for(int i=0; i<logparams_defaults[LOG_OPTIONS_IDX].numelt ; i++) {
|
for(int i=0; i<logparams_defaults[LOG_OPTIONS_IDX].numelt ; i++) {
|
||||||
for(int j=0; log_options[j].name != NULL ; j++) {
|
for(int j=0; log_options[j].name != NULL ; j++) {
|
||||||
if (strcmp(logparams_defaults[LOG_OPTIONS_IDX].strlistptr[i],log_options[j].name) == 0) {
|
if (strcmp(logparams_defaults[LOG_OPTIONS_IDX].strlistptr[i],log_options[j].name) == 0) {
|
||||||
g_log->flag = g_log->flag | log_options[j].value;
|
g_log->flag = g_log->flag | log_options[j].value;
|
||||||
break;
|
break;
|
||||||
} else if (log_options[j+1].name == NULL){
|
} else if (log_options[j+1].name == NULL) {
|
||||||
fprintf(stderr,"Unknown log option: %s\n",logparams_defaults[LOG_OPTIONS_IDX].strlistptr[i]);
|
fprintf(stderr,"Unknown log option: %s\n",logparams_defaults[LOG_OPTIONS_IDX].strlistptr[i]);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build the parameter array for setting per component log level and infile options */
|
/* build the parameter array for setting per component log level and infile options */
|
||||||
memset(logparams_level, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS);
|
memset(logparams_level, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS);
|
||||||
memset(logparams_logfile, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS);
|
memset(logparams_logfile, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS);
|
||||||
|
|
||||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
|
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
|
||||||
if(g_log->log_component[i].name == NULL) {
|
if(g_log->log_component[i].name == NULL) {
|
||||||
g_log->log_component[i].name = malloc(16);
|
g_log->log_component[i].name = malloc(16);
|
||||||
sprintf((char *)g_log->log_component[i].name,"comp%i?",i);
|
sprintf((char *)g_log->log_component[i].name,"comp%i?",i);
|
||||||
logparams_logfile[i].paramflags = PARAMFLAG_DONOTREAD;
|
logparams_logfile[i].paramflags = PARAMFLAG_DONOTREAD;
|
||||||
logparams_level[i].paramflags = PARAMFLAG_DONOTREAD;
|
logparams_level[i].paramflags = PARAMFLAG_DONOTREAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(logparams_level[i].optname, LOG_CONFIG_LEVEL_FORMAT, g_log->log_component[i].name);
|
sprintf(logparams_level[i].optname, LOG_CONFIG_LEVEL_FORMAT, g_log->log_component[i].name);
|
||||||
sprintf(logparams_logfile[i].optname, LOG_CONFIG_LOGFILE_FORMAT, g_log->log_component[i].name);
|
sprintf(logparams_logfile[i].optname, LOG_CONFIG_LOGFILE_FORMAT, g_log->log_component[i].name);
|
||||||
/* workaround: all log options in existing configuration files use lower case component names
|
|
||||||
where component names include uppercase char in log.h.... */
|
/* workaround: all log options in existing configuration files use lower case component names
|
||||||
|
where component names include uppercase char in log.h.... */
|
||||||
for (int j=0 ; j<strlen(logparams_level[i].optname); j++)
|
for (int j=0 ; j<strlen(logparams_level[i].optname); j++)
|
||||||
logparams_level[i].optname[j] = tolower(logparams_level[i].optname[j]);
|
logparams_level[i].optname[j] = tolower(logparams_level[i].optname[j]);
|
||||||
|
|
||||||
for (int j=0 ; j<strlen(logparams_level[i].optname); j++)
|
for (int j=0 ; j<strlen(logparams_level[i].optname); j++)
|
||||||
logparams_logfile[i].optname[j] = tolower(logparams_logfile[i].optname[j]);
|
logparams_logfile[i].optname[j] = tolower(logparams_logfile[i].optname[j]);
|
||||||
/* */
|
|
||||||
|
/* */
|
||||||
logparams_level[i].defstrval = gloglevel;
|
logparams_level[i].defstrval = gloglevel;
|
||||||
logparams_logfile[i].defuintval = 0;
|
logparams_logfile[i].defuintval = 0;
|
||||||
logparams_logfile[i].numelt = 0;
|
logparams_logfile[i].numelt = 0;
|
||||||
logparams_level[i].numelt = 0;
|
logparams_level[i].numelt = 0;
|
||||||
logparams_level[i].type = TYPE_STRING;
|
logparams_level[i].type = TYPE_STRING;
|
||||||
logparams_logfile[i].type = TYPE_UINT;
|
logparams_logfile[i].type = TYPE_UINT;
|
||||||
|
|
||||||
logparams_logfile[i].paramflags = logparams_logfile[i].paramflags|PARAMFLAG_BOOL;
|
logparams_logfile[i].paramflags = logparams_logfile[i].paramflags|PARAMFLAG_BOOL;
|
||||||
}
|
}
|
||||||
/* read the per component parameters */
|
|
||||||
|
/* read the per component parameters */
|
||||||
config_get( logparams_level, MAX_LOG_PREDEF_COMPONENTS,CONFIG_STRING_LOG_PREFIX);
|
config_get( logparams_level, MAX_LOG_PREDEF_COMPONENTS,CONFIG_STRING_LOG_PREFIX);
|
||||||
config_get( logparams_logfile, MAX_LOG_PREDEF_COMPONENTS,CONFIG_STRING_LOG_PREFIX);
|
config_get( logparams_logfile, MAX_LOG_PREDEF_COMPONENTS,CONFIG_STRING_LOG_PREFIX);
|
||||||
/* now set the log levels and infile option, according to what we read */
|
|
||||||
|
/* now set the log levels and infile option, according to what we read */
|
||||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
|
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
|
||||||
g_log->log_component[i].level = map_str_to_int(log_level_names, *(logparams_level[i].strptr));
|
g_log->log_component[i].level = map_str_to_int(log_level_names, *(logparams_level[i].strptr));
|
||||||
set_log(i, g_log->log_component[i].level);
|
set_log(i, g_log->log_component[i].level);
|
||||||
|
|
||||||
if (*(logparams_logfile[i].uptr) == 1)
|
if (*(logparams_logfile[i].uptr) == 1)
|
||||||
set_component_filelog(i);
|
set_component_filelog(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build then read the debug and dump parameter array */
|
/* build then read the debug and dump parameter array */
|
||||||
for (int i=0;log_maskmap[i].name != NULL ; i++) {
|
for (int i=0; log_maskmap[i].name != NULL ; i++) {
|
||||||
sprintf(logparams_debug[i].optname, LOG_CONFIG_DEBUG_FORMAT, log_maskmap[i].name);
|
sprintf(logparams_debug[i].optname, LOG_CONFIG_DEBUG_FORMAT, log_maskmap[i].name);
|
||||||
sprintf(logparams_dump[i].optname, LOG_CONFIG_DUMP_FORMAT, log_maskmap[i].name);
|
sprintf(logparams_dump[i].optname, LOG_CONFIG_DUMP_FORMAT, log_maskmap[i].name);
|
||||||
logparams_debug[i].defuintval = 0;
|
logparams_debug[i].defuintval = 0;
|
||||||
logparams_debug[i].type = TYPE_UINT;
|
logparams_debug[i].type = TYPE_UINT;
|
||||||
logparams_debug[i].paramflags = PARAMFLAG_BOOL;
|
logparams_debug[i].paramflags = PARAMFLAG_BOOL;
|
||||||
logparams_debug[i].uptr = NULL;
|
logparams_debug[i].uptr = NULL;
|
||||||
logparams_debug[i].chkPptr = NULL;
|
logparams_debug[i].chkPptr = NULL;
|
||||||
logparams_debug[i].numelt = 0;
|
logparams_debug[i].numelt = 0;
|
||||||
logparams_dump[i].defuintval = 0;
|
logparams_dump[i].defuintval = 0;
|
||||||
logparams_dump[i].type = TYPE_UINT;
|
logparams_dump[i].type = TYPE_UINT;
|
||||||
logparams_dump[i].paramflags = PARAMFLAG_BOOL;
|
logparams_dump[i].paramflags = PARAMFLAG_BOOL;
|
||||||
logparams_dump[i].uptr = NULL;
|
logparams_dump[i].uptr = NULL;
|
||||||
logparams_dump[i].chkPptr = NULL;
|
logparams_dump[i].chkPptr = NULL;
|
||||||
logparams_dump[i].numelt = 0;
|
logparams_dump[i].numelt = 0;
|
||||||
}
|
}
|
||||||
config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX);
|
|
||||||
config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX);
|
config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX);
|
||||||
/* set the debug mask according to the debug parameters values */
|
config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX);
|
||||||
|
|
||||||
|
/* set the debug mask according to the debug parameters values */
|
||||||
for (int i=0; log_maskmap[i].name != NULL ; i++) {
|
for (int i=0; log_maskmap[i].name != NULL ; i++) {
|
||||||
if (*(logparams_debug[i].uptr) )
|
if (*(logparams_debug[i].uptr) )
|
||||||
g_log->debug_mask = g_log->debug_mask | log_maskmap[i].value;
|
g_log->debug_mask = g_log->debug_mask | log_maskmap[i].value;
|
||||||
|
|
||||||
if (*(logparams_dump[i].uptr) )
|
if (*(logparams_dump[i].uptr) )
|
||||||
g_log->dump_mask = g_log->dump_mask | log_maskmap[i].value;
|
g_log->dump_mask = g_log->dump_mask | log_maskmap[i].value;
|
||||||
}
|
}
|
||||||
/* log globally enabled/disabled */
|
|
||||||
|
/* log globally enabled/disabled */
|
||||||
set_glog_onlinelog(consolelog);
|
set_glog_onlinelog(consolelog);
|
||||||
}
|
}
|
||||||
|
|
||||||
int register_log_component(char *name, char *fext, int compidx)
|
int register_log_component(char *name, char *fext, int compidx) {
|
||||||
{
|
int computed_compidx=compidx;
|
||||||
int computed_compidx=compidx;
|
|
||||||
|
|
||||||
if (strlen(fext) > 3) {
|
if (strlen(fext) > 3) {
|
||||||
fext[3]=0; /* limit log file extension to 3 chars */
|
fext[3]=0; /* limit log file extension to 3 chars */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compidx < 0) { /* this is not a pre-defined component */
|
if (compidx < 0) { /* this is not a pre-defined component */
|
||||||
for (int i = MAX_LOG_PREDEF_COMPONENTS; i< MAX_LOG_COMPONENTS; i++) {
|
for (int i = MAX_LOG_PREDEF_COMPONENTS; i< MAX_LOG_COMPONENTS; i++) {
|
||||||
if (g_log->log_component[i].name == NULL) {
|
if (g_log->log_component[i].name == NULL) {
|
||||||
computed_compidx=i;
|
computed_compidx=i;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (computed_compidx >= 0 && computed_compidx <MAX_LOG_COMPONENTS) {
|
if (computed_compidx >= 0 && computed_compidx <MAX_LOG_COMPONENTS) {
|
||||||
g_log->log_component[computed_compidx].name = strdup(name);
|
g_log->log_component[computed_compidx].name = strdup(name);
|
||||||
g_log->log_component[computed_compidx].stream = stdout;
|
g_log->log_component[computed_compidx].stream = stdout;
|
||||||
g_log->log_component[computed_compidx].filelog = 0;
|
g_log->log_component[computed_compidx].filelog = 0;
|
||||||
g_log->log_component[computed_compidx].filelog_name = malloc(strlen(name)+16);/* /tmp/<name>.%s */
|
g_log->log_component[computed_compidx].filelog_name = malloc(strlen(name)+16);/* /tmp/<name>.%s */
|
||||||
sprintf(g_log->log_component[computed_compidx].filelog_name,"/tmp/%s.%s",name,fext);
|
sprintf(g_log->log_component[computed_compidx].filelog_name,"/tmp/%s.%s",name,fext);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"{LOG} %s %d Couldn't register componemt %s\n",__FILE__,__LINE__,name);
|
fprintf(stderr,"{LOG} %s %d Couldn't register componemt %s\n",__FILE__,__LINE__,name);
|
||||||
}
|
}
|
||||||
return computed_compidx;
|
|
||||||
|
return computed_compidx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int logInit (void)
|
int logInit (void) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
g_log = calloc(1, sizeof(log_t));
|
g_log = calloc(1, sizeof(log_t));
|
||||||
|
|
||||||
@@ -367,10 +360,8 @@ int logInit (void)
|
|||||||
perror ("cannot allocated memory for log generation module \n");
|
perror ("cannot allocated memory for log generation module \n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(g_log,0,sizeof(log_t));
|
memset(g_log,0,sizeof(log_t));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
register_log_component("PHY","log",PHY);
|
register_log_component("PHY","log",PHY);
|
||||||
register_log_component("MAC","log",MAC);
|
register_log_component("MAC","log",MAC);
|
||||||
register_log_component("OPT","log",OPT);
|
register_log_component("OPT","log",OPT);
|
||||||
@@ -399,130 +390,108 @@ int logInit (void)
|
|||||||
register_log_component("TMR","",TMR);
|
register_log_component("TMR","",TMR);
|
||||||
register_log_component("USIM","txt",USIM);
|
register_log_component("USIM","txt",USIM);
|
||||||
register_log_component("SIM","txt",SIM);
|
register_log_component("SIM","txt",SIM);
|
||||||
|
|
||||||
/* following log component are used for the localization*/
|
/* following log component are used for the localization*/
|
||||||
register_log_component("LOCALIZE","log",LOCALIZE);
|
register_log_component("LOCALIZE","log",LOCALIZE);
|
||||||
register_log_component("NAS","log",NAS);
|
register_log_component("NAS","log",NAS);
|
||||||
register_log_component("UDP","",UDP_);
|
register_log_component("UDP","",UDP_);
|
||||||
|
|
||||||
|
|
||||||
register_log_component("GTPV1U","",GTPU);
|
register_log_component("GTPV1U","",GTPU);
|
||||||
|
|
||||||
|
|
||||||
register_log_component("S1AP","",S1AP);
|
register_log_component("S1AP","",S1AP);
|
||||||
register_log_component("X2AP","",X2AP);
|
register_log_component("X2AP","",X2AP);
|
||||||
|
|
||||||
|
|
||||||
register_log_component("SCTP","",SCTP);
|
register_log_component("SCTP","",SCTP);
|
||||||
register_log_component("X2AP","",X2AP);
|
register_log_component("X2AP","",X2AP);
|
||||||
register_log_component("LOADER","log",LOADER);
|
register_log_component("LOADER","log",LOADER);
|
||||||
register_log_component("ASN","log",ASN);
|
register_log_component("ASN","log",ASN);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (int i=0 ; log_level_names[i].name != NULL ; i++)
|
for (int i=0 ; log_level_names[i].name != NULL ; i++)
|
||||||
g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name
|
g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
g_log->filelog_name = "/tmp/openair.log";
|
g_log->filelog_name = "/tmp/openair.log";
|
||||||
|
|
||||||
log_getconfig(g_log);
|
log_getconfig(g_log);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// set all unused component items to 0, they are for non predefined components
|
// set all unused component items to 0, they are for non predefined components
|
||||||
for (i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
for (i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||||
memset(&(g_log->log_component[i]),0,sizeof(log_component_t));
|
memset(&(g_log->log_component[i]),0,sizeof(log_component_t));
|
||||||
}
|
}
|
||||||
printf("log init done\n");
|
|
||||||
|
|
||||||
|
printf("log init done\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *log_getthreadname(char *threadname, int bufsize) {
|
char *log_getthreadname(char *threadname, int bufsize) {
|
||||||
|
int rt = pthread_getname_np(pthread_self(), threadname,bufsize) ;
|
||||||
|
|
||||||
int rt = pthread_getname_np(pthread_self(), threadname,bufsize) ;
|
if (rt == 0) {
|
||||||
if (rt == 0)
|
return threadname;
|
||||||
{
|
} else {
|
||||||
return threadname;
|
return "thread?";
|
||||||
} else {
|
}
|
||||||
return "thread?";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int log_header(char *log_buffer, int buffsize, int comp, int level,const char *format) {
|
static int log_header(char *log_buffer, int buffsize, int comp, int level,const char *format) {
|
||||||
char threadname[PR_SET_NAME];
|
char threadname[PR_SET_NAME];
|
||||||
return snprintf(log_buffer, buffsize , "%s%s[%s]%c %s %s%s",
|
return snprintf(log_buffer, buffsize, "%s%s[%s]%c %s %s%s",
|
||||||
log_level_highlight_end[level],
|
log_level_highlight_end[level],
|
||||||
( (g_log->flag & FLAG_NOCOLOR)?"":log_level_highlight_start[level]),
|
( (g_log->flag & FLAG_NOCOLOR)?"":log_level_highlight_start[level]),
|
||||||
g_log->log_component[comp].name,
|
g_log->log_component[comp].name,
|
||||||
( (g_log->flag & FLAG_LEVEL)?g_log->level2string[level]:' '),
|
( (g_log->flag & FLAG_LEVEL)?g_log->level2string[level]:' '),
|
||||||
( (g_log->flag & FLAG_THREAD)?log_getthreadname(threadname,PR_SET_NAME+1):""),
|
( (g_log->flag & FLAG_THREAD)?log_getthreadname(threadname,PR_SET_NAME+1):""),
|
||||||
format,
|
format,
|
||||||
log_level_highlight_end[level]);
|
log_level_highlight_end[level]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logRecord_mt(const char *file, const char *func, int line, int comp, int level, const char* format, ... )
|
void logRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, ... ) {
|
||||||
{
|
char log_buffer[MAX_LOG_TOTAL]= {0};
|
||||||
char log_buffer[MAX_LOG_TOTAL]={0};
|
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
|
log_header(log_buffer,MAX_LOG_TOTAL,comp, level,format);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
log_header(log_buffer,MAX_LOG_TOTAL ,comp, level,format);
|
|
||||||
g_log->log_component[comp].vprint(g_log->log_component[comp].stream,log_buffer, args);
|
g_log->log_component[comp].vprint(g_log->log_component[comp].stream,log_buffer, args);
|
||||||
|
fflush(g_log->log_component[comp].stream);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_dump(int component, void *buffer, int buffsize,int datatype, const char* format, ... ) {
|
void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... ) {
|
||||||
va_list args;
|
va_list args;
|
||||||
char *wbuf;
|
char *wbuf;
|
||||||
|
|
||||||
|
switch(datatype) {
|
||||||
|
case LOG_DUMP_DOUBLE:
|
||||||
|
wbuf=malloc((buffsize * 10) + 64 + MAX_LOG_TOTAL);
|
||||||
|
break;
|
||||||
|
|
||||||
switch(datatype) {
|
case LOG_DUMP_CHAR:
|
||||||
case LOG_DUMP_DOUBLE:
|
default:
|
||||||
wbuf=malloc((buffsize * 10) + 64 + MAX_LOG_TOTAL);
|
wbuf=malloc((buffsize * 3 ) + 64 + MAX_LOG_TOTAL);
|
||||||
break;
|
break;
|
||||||
case LOG_DUMP_CHAR:
|
}
|
||||||
default:
|
|
||||||
wbuf=malloc((buffsize * 3 ) + 64 + MAX_LOG_TOTAL);
|
if (wbuf != NULL) {
|
||||||
break;
|
va_start(args, format);
|
||||||
|
int pos=log_header(wbuf,MAX_LOG_TOTAL,component, OAILOG_INFO,"");
|
||||||
|
int pos2=vsprintf(wbuf+pos,format, args);
|
||||||
|
pos=pos+pos2;
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
for (int i=0; i<buffsize; i++) {
|
||||||
|
switch(datatype) {
|
||||||
|
case LOG_DUMP_DOUBLE:
|
||||||
|
pos = pos + sprintf(wbuf+pos,"%04.4lf ", (double)((double *)buffer)[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOG_DUMP_CHAR:
|
||||||
|
default:
|
||||||
|
pos = pos + sprintf(wbuf+pos,"%02x ", (unsigned char)((unsigned char *)buffer)[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (wbuf != NULL) {
|
|
||||||
va_start(args, format);
|
|
||||||
int pos=log_header(wbuf,MAX_LOG_TOTAL ,component, OAILOG_INFO,"");
|
|
||||||
int pos2=vsprintf(wbuf+pos,format, args);
|
|
||||||
pos=pos+pos2;
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
for (int i=0; i<buffsize; i++) {
|
|
||||||
switch(datatype) {
|
|
||||||
case LOG_DUMP_DOUBLE:
|
|
||||||
pos = pos + sprintf(wbuf+pos,"%04.4lf ", (double)((double *)buffer)[i]);
|
|
||||||
break;
|
|
||||||
case LOG_DUMP_CHAR:
|
|
||||||
default:
|
|
||||||
pos = pos + sprintf(wbuf+pos,"%02x ", (unsigned char)((unsigned char *)buffer)[i]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sprintf(wbuf+pos,"\n");
|
sprintf(wbuf+pos,"\n");
|
||||||
g_log->log_component[component].print(g_log->log_component[component].stream,wbuf);
|
g_log->log_component[component].print(g_log->log_component[component].stream,wbuf);
|
||||||
free(wbuf);
|
free(wbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int set_log(int component, int level)
|
int set_log(int component, int level) {
|
||||||
{
|
|
||||||
/* Checking parameters */
|
/* Checking parameters */
|
||||||
DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS),
|
DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS),
|
||||||
component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS);
|
component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS);
|
||||||
@@ -530,38 +499,34 @@ int set_log(int component, int level)
|
|||||||
OAILOG_ERR);
|
OAILOG_ERR);
|
||||||
|
|
||||||
if ( g_log->log_component[component].level != OAILOG_DISABLE )
|
if ( g_log->log_component[component].level != OAILOG_DISABLE )
|
||||||
g_log->log_component[component].savedlevel = g_log->log_component[component].level;
|
g_log->log_component[component].savedlevel = g_log->log_component[component].level;
|
||||||
g_log->log_component[component].level = level;
|
|
||||||
|
|
||||||
|
g_log->log_component[component].level = level;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void set_glog(int level)
|
void set_glog(int level) {
|
||||||
{
|
|
||||||
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
||||||
set_log(c, level);
|
set_log(c, level);
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_glog_onlinelog(int enable)
|
|
||||||
{
|
|
||||||
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
|
||||||
if ( enable ) {
|
|
||||||
g_log->log_component[c].level = g_log->log_component[c].savedlevel;
|
|
||||||
g_log->log_component[c].vprint = vfprintf;
|
|
||||||
g_log->log_component[c].print = fprintf;
|
|
||||||
g_log->log_component[c].stream = stdout;
|
|
||||||
} else {
|
|
||||||
g_log->log_component[c].level = OAILOG_DISABLE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void set_glog_filelog(int enable)
|
|
||||||
{
|
void set_glog_onlinelog(int enable) {
|
||||||
static FILE *fptr;
|
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
||||||
|
if ( enable ) {
|
||||||
|
g_log->log_component[c].level = g_log->log_component[c].savedlevel;
|
||||||
|
g_log->log_component[c].vprint = vfprintf;
|
||||||
|
g_log->log_component[c].print = fprintf;
|
||||||
|
g_log->log_component[c].stream = stdout;
|
||||||
|
} else {
|
||||||
|
g_log->log_component[c].level = OAILOG_DISABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void set_glog_filelog(int enable) {
|
||||||
|
static FILE *fptr;
|
||||||
|
|
||||||
if ( enable ) {
|
if ( enable ) {
|
||||||
fptr = fopen(g_log->filelog_name,"w");
|
fptr = fopen(g_log->filelog_name,"w");
|
||||||
@@ -574,33 +539,35 @@ static FILE *fptr;
|
|||||||
} else {
|
} else {
|
||||||
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
||||||
g_log->log_component[c].filelog = 0;
|
g_log->log_component[c].filelog = 0;
|
||||||
|
|
||||||
if (fptr != NULL) {
|
if (fptr != NULL) {
|
||||||
fclose(fptr);
|
fclose(fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_log->log_component[c].stream = stdout;
|
g_log->log_component[c].stream = stdout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_component_filelog(int comp)
|
void set_component_filelog(int comp) {
|
||||||
{
|
if (g_log->log_component[comp].stream == NULL || g_log->log_component[comp].stream == stdout) {
|
||||||
if (g_log->log_component[comp].stream == NULL || g_log->log_component[comp].stream == stdout) {
|
g_log->log_component[comp].stream = fopen(g_log->log_component[comp].filelog_name,"w");
|
||||||
g_log->log_component[comp].stream = fopen(g_log->log_component[comp].filelog_name,"w");
|
}
|
||||||
}
|
|
||||||
g_log->log_component[comp].vprint = vfprintf;
|
|
||||||
g_log->log_component[comp].print = fprintf;
|
|
||||||
g_log->log_component[comp].filelog = 1;
|
|
||||||
}
|
|
||||||
void close_component_filelog(int comp)
|
|
||||||
{
|
|
||||||
g_log->log_component[comp].filelog = 0;
|
|
||||||
if (g_log->log_component[comp].stream != NULL && g_log->log_component[comp].stream != stdout ) {
|
|
||||||
fclose(g_log->log_component[comp].stream);
|
|
||||||
g_log->log_component[comp].stream = stdout;
|
|
||||||
}
|
|
||||||
g_log->log_component[comp].vprint = vfprintf;
|
|
||||||
g_log->log_component[comp].print = fprintf;
|
|
||||||
|
|
||||||
|
g_log->log_component[comp].vprint = vfprintf;
|
||||||
|
g_log->log_component[comp].print = fprintf;
|
||||||
|
g_log->log_component[comp].filelog = 1;
|
||||||
|
}
|
||||||
|
void close_component_filelog(int comp) {
|
||||||
|
g_log->log_component[comp].filelog = 0;
|
||||||
|
|
||||||
|
if (g_log->log_component[comp].stream != NULL && g_log->log_component[comp].stream != stdout ) {
|
||||||
|
fclose(g_log->log_component[comp].stream);
|
||||||
|
g_log->log_component[comp].stream = stdout;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_log->log_component[comp].vprint = vfprintf;
|
||||||
|
g_log->log_component[comp].print = fprintf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -608,8 +575,7 @@ void close_component_filelog(int comp)
|
|||||||
* with string value NULL
|
* with string value NULL
|
||||||
*/
|
*/
|
||||||
/* map a string to an int. Takes a mapping array and a string as arg */
|
/* map a string to an int. Takes a mapping array and a string as arg */
|
||||||
int map_str_to_int(mapping *map, const char *str)
|
int map_str_to_int(mapping *map, const char *str) {
|
||||||
{
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (map->name == NULL) {
|
if (map->name == NULL) {
|
||||||
return(-1);
|
return(-1);
|
||||||
@@ -624,8 +590,7 @@ int map_str_to_int(mapping *map, const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* map an int to a string. Takes a mapping array and a value */
|
/* map an int to a string. Takes a mapping array and a value */
|
||||||
char *map_int_to_str(mapping *map, int val)
|
char *map_int_to_str(mapping *map, int val) {
|
||||||
{
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (map->name == NULL) {
|
if (map->name == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -639,8 +604,7 @@ char *map_int_to_str(mapping *map, int val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_newline( char *str, int size)
|
int is_newline( char *str, int size) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for ( i = 0; i < size; i++ ) {
|
for ( i = 0; i < size; i++ ) {
|
||||||
@@ -653,85 +617,62 @@ int is_newline( char *str, int size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void logClean (void)
|
void logClean (void) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
LOG_UI(PHY,"\n");
|
LOG_UI(PHY,"\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||||
close_component_filelog(i);
|
close_component_filelog(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef LOG_TEST
|
#ifdef LOG_TEST
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
|
||||||
|
|
||||||
logInit();
|
logInit();
|
||||||
|
|
||||||
|
|
||||||
test_log();
|
test_log();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_log(void)
|
int test_log(void) {
|
||||||
{
|
|
||||||
LOG_ENTER(MAC); // because the default level is DEBUG
|
LOG_ENTER(MAC); // because the default level is DEBUG
|
||||||
LOG_I(EMU, "1 Starting OAI logs version %s Build date: %s on %s\n",
|
LOG_I(EMU, "1 Starting OAI logs version %s Build date: %s on %s\n",
|
||||||
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
||||||
LOG_D(MAC, "1 debug MAC \n");
|
LOG_D(MAC, "1 debug MAC \n");
|
||||||
LOG_W(MAC, "1 warning MAC \n");
|
LOG_W(MAC, "1 warning MAC \n");
|
||||||
|
|
||||||
set_log(EMU, OAILOG_INFO);
|
set_log(EMU, OAILOG_INFO);
|
||||||
set_log(MAC, OAILOG_WARNING);
|
set_log(MAC, OAILOG_WARNING);
|
||||||
|
|
||||||
LOG_I(EMU, "2 Starting OAI logs version %s Build date: %s on %s\n",
|
LOG_I(EMU, "2 Starting OAI logs version %s Build date: %s on %s\n",
|
||||||
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
||||||
LOG_E(MAC, "2 error MAC\n");
|
LOG_E(MAC, "2 error MAC\n");
|
||||||
LOG_D(MAC, "2 debug MAC \n");
|
LOG_D(MAC, "2 debug MAC \n");
|
||||||
LOG_W(MAC, "2 warning MAC \n");
|
LOG_W(MAC, "2 warning MAC \n");
|
||||||
LOG_I(MAC, "2 info MAC \n");
|
LOG_I(MAC, "2 info MAC \n");
|
||||||
|
|
||||||
|
|
||||||
set_log(MAC, OAILOG_NOTICE);
|
set_log(MAC, OAILOG_NOTICE);
|
||||||
|
|
||||||
LOG_ENTER(MAC);
|
LOG_ENTER(MAC);
|
||||||
LOG_I(EMU, "3 Starting OAI logs version %s Build date: %s on %s\n",
|
LOG_I(EMU, "3 Starting OAI logs version %s Build date: %s on %s\n",
|
||||||
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
||||||
LOG_D(MAC, "3 debug MAC \n");
|
LOG_D(MAC, "3 debug MAC \n");
|
||||||
LOG_W(MAC, "3 warning MAC \n");
|
LOG_W(MAC, "3 warning MAC \n");
|
||||||
LOG_I(MAC, "3 info MAC \n");
|
LOG_I(MAC, "3 info MAC \n");
|
||||||
|
|
||||||
set_log(MAC, LOG_DEBUG);
|
set_log(MAC, LOG_DEBUG);
|
||||||
set_log(EMU, LOG_DEBUG);
|
set_log(EMU, LOG_DEBUG);
|
||||||
|
|
||||||
LOG_ENTER(MAC);
|
LOG_ENTER(MAC);
|
||||||
LOG_I(EMU, "4 Starting OAI logs version %s Build date: %s on %s\n",
|
LOG_I(EMU, "4 Starting OAI logs version %s Build date: %s on %s\n",
|
||||||
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
||||||
LOG_D(MAC, "4 debug MAC \n");
|
LOG_D(MAC, "4 debug MAC \n");
|
||||||
LOG_W(MAC, "4 warning MAC \n");
|
LOG_W(MAC, "4 warning MAC \n");
|
||||||
LOG_I(MAC, "4 info MAC \n");
|
LOG_I(MAC, "4 info MAC \n");
|
||||||
|
|
||||||
|
|
||||||
set_log(MAC, LOG_DEBUG);
|
set_log(MAC, LOG_DEBUG);
|
||||||
set_log(EMU, LOG_DEBUG);
|
set_log(EMU, LOG_DEBUG);
|
||||||
|
|
||||||
LOG_I(LOG, "5 Starting OAI logs version %s Build date: %s on %s\n",
|
LOG_I(LOG, "5 Starting OAI logs version %s Build date: %s on %s\n",
|
||||||
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
||||||
LOG_D(MAC, "5 debug MAC \n");
|
LOG_D(MAC, "5 debug MAC \n");
|
||||||
LOG_W(MAC, "5 warning MAC \n");
|
LOG_W(MAC, "5 warning MAC \n");
|
||||||
LOG_I(MAC, "5 info MAC \n");
|
LOG_I(MAC, "5 info MAC \n");
|
||||||
|
|
||||||
|
|
||||||
set_log(MAC, LOG_TRACE);
|
set_log(MAC, LOG_TRACE);
|
||||||
set_log(EMU, LOG_TRACE);
|
set_log(EMU, LOG_TRACE);
|
||||||
|
|
||||||
LOG_ENTER(MAC);
|
LOG_ENTER(MAC);
|
||||||
LOG_I(LOG, "6 Starting OAI logs version %s Build date: %s on %s\n",
|
LOG_I(LOG, "6 Starting OAI logs version %s Build date: %s on %s\n",
|
||||||
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
BUILD_VERSION, BUILD_DATE, BUILD_HOST);
|
||||||
@@ -739,7 +680,6 @@ int test_log(void)
|
|||||||
LOG_W(MAC, "6 warning MAC \n");
|
LOG_W(MAC, "6 warning MAC \n");
|
||||||
LOG_I(MAC, "6 info MAC \n");
|
LOG_I(MAC, "6 info MAC \n");
|
||||||
LOG_EXIT(MAC);
|
LOG_EXIT(MAC);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+169
-164
@@ -45,14 +45,15 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#ifndef __STDC_FORMAT_MACROS
|
#ifndef __STDC_FORMAT_MACROS
|
||||||
#define __STDC_FORMAT_MACROS
|
#define __STDC_FORMAT_MACROS
|
||||||
#endif
|
#endif
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#ifndef _GNU_SOURCE
|
#ifndef _GNU_SOURCE
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#endif
|
#endif
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "T.h"
|
#include "T.h"
|
||||||
|
#include <common/utils/utils.h>
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -82,11 +83,11 @@ extern "C" {
|
|||||||
* @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8
|
* @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8
|
||||||
* @{*/
|
* @{*/
|
||||||
# define OAILOG_DISABLE -1 /*!< \brief disable all LOG messages, cannot be used in LOG macros, use only in LOG module */
|
# define OAILOG_DISABLE -1 /*!< \brief disable all LOG messages, cannot be used in LOG macros, use only in LOG module */
|
||||||
# define OAILOG_ERR 0 /*!< \brief critical error conditions, impact on "must have" fuctinalities */
|
# define OAILOG_ERR 0 /*!< \brief critical error conditions, impact on "must have" functionalities */
|
||||||
# define OAILOG_WARNING 1 /*!< \brief warning conditions, shouldn't happen but doesn't impact "must have" functionalities */
|
# define OAILOG_WARNING 1 /*!< \brief warning conditions, shouldn't happen but doesn't impact "must have" functionalities */
|
||||||
# define OAILOG_INFO 2 /*!< \brief informational messages most people don't need, shouldn't impact real-time behavior */
|
# define OAILOG_INFO 2 /*!< \brief informational messages most people don't need, shouldn't impact real-time behavior */
|
||||||
# define OAILOG_DEBUG 3 /*!< \brief first level debug-level messages, for developers , may impact real-time behavior */
|
# define OAILOG_DEBUG 3 /*!< \brief first level debug-level messages, for developers, may impact real-time behavior */
|
||||||
# define OAILOG_TRACE 4 /*!< \brief second level debug-level messages, for developers ,likely impact real-time behavior*/
|
# define OAILOG_TRACE 4 /*!< \brief second level debug-level messages, for developers, likely impact real-time behavior*/
|
||||||
|
|
||||||
#define NUM_LOG_LEVEL 5 /*!< \brief the number of message levels users have with LOG (OAILOG_DISABLE is not available to user as a level, so it is not included)*/
|
#define NUM_LOG_LEVEL 5 /*!< \brief the number of message levels users have with LOG (OAILOG_DISABLE is not available to user as a level, so it is not included)*/
|
||||||
/* @}*/
|
/* @}*/
|
||||||
@@ -150,22 +151,22 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
#define LOG_MASKMAP_INIT {\
|
#define LOG_MASKMAP_INIT {\
|
||||||
{"PRACH", DEBUG_PRACH},\
|
{"PRACH", DEBUG_PRACH},\
|
||||||
{"RU", DEBUG_RU},\
|
{"RU", DEBUG_RU},\
|
||||||
{"UE_PHYPROC", DEBUG_UE_PHYPROC},\
|
{"UE_PHYPROC", DEBUG_UE_PHYPROC},\
|
||||||
{"LTEESTIM", DEBUG_LTEESTIM},\
|
{"LTEESTIM", DEBUG_LTEESTIM},\
|
||||||
{"DLCELLSPEC", DEBUG_DLCELLSPEC},\
|
{"DLCELLSPEC", DEBUG_DLCELLSPEC},\
|
||||||
{"ULSCH", DEBUG_ULSCH},\
|
{"ULSCH", DEBUG_ULSCH},\
|
||||||
{"RRC", DEBUG_RRC},\
|
{"RRC", DEBUG_RRC},\
|
||||||
{"PDCP", DEBUG_PDCP},\
|
{"PDCP", DEBUG_PDCP},\
|
||||||
{"DFT", DEBUG_DFT},\
|
{"DFT", DEBUG_DFT},\
|
||||||
{"ASN1", DEBUG_ASN1},\
|
{"ASN1", DEBUG_ASN1},\
|
||||||
{"CTRLSOCKET", DEBUG_CTRLSOCKET},\
|
{"CTRLSOCKET", DEBUG_CTRLSOCKET},\
|
||||||
{"SECURITY", DEBUG_SECURITY},\
|
{"SECURITY", DEBUG_SECURITY},\
|
||||||
{"NAS", DEBUG_NAS},\
|
{"NAS", DEBUG_NAS},\
|
||||||
{"UE_TIMING", UE_TIMING},\
|
{"UE_TIMING", UE_TIMING},\
|
||||||
{NULL,-1}\
|
{NULL,-1}\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -178,51 +179,51 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MIN_LOG_COMPONENTS = 0,
|
MIN_LOG_COMPONENTS = 0,
|
||||||
PHY = MIN_LOG_COMPONENTS,
|
PHY = MIN_LOG_COMPONENTS,
|
||||||
MAC,
|
MAC,
|
||||||
EMU,
|
EMU,
|
||||||
SIM,
|
SIM,
|
||||||
OCG,
|
OCG,
|
||||||
OMG,
|
OMG,
|
||||||
OPT,
|
OPT,
|
||||||
OTG,
|
OTG,
|
||||||
OTG_LATENCY,
|
OTG_LATENCY,
|
||||||
OTG_LATENCY_BG,
|
OTG_LATENCY_BG,
|
||||||
OTG_GP,
|
OTG_GP,
|
||||||
OTG_GP_BG,
|
OTG_GP_BG,
|
||||||
OTG_JITTER,
|
OTG_JITTER,
|
||||||
RLC,
|
RLC,
|
||||||
PDCP,
|
PDCP,
|
||||||
RRC,
|
RRC,
|
||||||
NAS,
|
NAS,
|
||||||
PERF,
|
PERF,
|
||||||
OIP,
|
OIP,
|
||||||
CLI,
|
CLI,
|
||||||
MSC,
|
MSC,
|
||||||
OCM,
|
OCM,
|
||||||
UDP_,
|
UDP_,
|
||||||
GTPU,
|
GTPU,
|
||||||
SPGW,
|
SPGW,
|
||||||
S1AP,
|
S1AP,
|
||||||
SCTP,
|
SCTP,
|
||||||
HW,
|
HW,
|
||||||
OSA,
|
OSA,
|
||||||
RAL_ENB,
|
RAL_ENB,
|
||||||
RAL_UE,
|
RAL_UE,
|
||||||
ENB_APP,
|
ENB_APP,
|
||||||
FLEXRAN_AGENT,
|
FLEXRAN_AGENT,
|
||||||
TMR,
|
TMR,
|
||||||
USIM,
|
USIM,
|
||||||
LOCALIZE,
|
LOCALIZE,
|
||||||
X2AP,
|
X2AP,
|
||||||
GNB_APP,
|
GNB_APP,
|
||||||
NR_RRC,
|
NR_RRC,
|
||||||
NR_MAC,
|
NR_MAC,
|
||||||
NR_PHY,
|
NR_PHY,
|
||||||
LOADER,
|
LOADER,
|
||||||
ASN,
|
ASN,
|
||||||
MAX_LOG_PREDEF_COMPONENTS,
|
MAX_LOG_PREDEF_COMPONENTS,
|
||||||
}
|
}
|
||||||
comp_name_t;
|
comp_name_t;
|
||||||
|
|
||||||
@@ -231,42 +232,42 @@ comp_name_t;
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *name; /*!< \brief string name of item */
|
char *name; /*!< \brief string name of item */
|
||||||
int value; /*!< \brief integer value of mapping */
|
int value; /*!< \brief integer value of mapping */
|
||||||
} mapping;
|
} mapping;
|
||||||
|
|
||||||
typedef int(*log_vprint_func_t)(FILE *stream, const char *format, va_list ap );
|
typedef int(*log_vprint_func_t)(FILE *stream, const char *format, va_list ap );
|
||||||
typedef int(*log_print_func_t)(FILE *stream, const char *format, ... );
|
typedef int(*log_print_func_t)(FILE *stream, const char *format, ... );
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
int level;
|
int level;
|
||||||
int savedlevel;
|
int savedlevel;
|
||||||
int flag;
|
int flag;
|
||||||
int filelog;
|
int filelog;
|
||||||
char *filelog_name;
|
char *filelog_name;
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
log_vprint_func_t vprint;
|
log_vprint_func_t vprint;
|
||||||
log_print_func_t print;
|
log_print_func_t print;
|
||||||
/* SR: make the log buffer component relative */
|
/* SR: make the log buffer component relative */
|
||||||
char log_buffer[MAX_LOG_TOTAL];
|
char log_buffer[MAX_LOG_TOTAL];
|
||||||
} log_component_t;
|
} log_component_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
log_component_t log_component[MAX_LOG_COMPONENTS];
|
log_component_t log_component[MAX_LOG_COMPONENTS];
|
||||||
char level2string[NUM_LOG_LEVEL];
|
char level2string[NUM_LOG_LEVEL];
|
||||||
int flag;
|
int flag;
|
||||||
char* filelog_name;
|
char *filelog_name;
|
||||||
uint64_t debug_mask;
|
uint64_t debug_mask;
|
||||||
uint64_t dump_mask;
|
uint64_t dump_mask;
|
||||||
} log_t;
|
} log_t;
|
||||||
|
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
#if defined(ENABLE_ITTI)
|
||||||
typedef enum log_instance_type_e {
|
typedef enum log_instance_type_e {
|
||||||
LOG_INSTANCE_UNKNOWN,
|
LOG_INSTANCE_UNKNOWN,
|
||||||
LOG_INSTANCE_ENB,
|
LOG_INSTANCE_ENB,
|
||||||
LOG_INSTANCE_UE,
|
LOG_INSTANCE_UE,
|
||||||
} log_instance_type_t;
|
} log_instance_type_t;
|
||||||
|
|
||||||
void log_set_instance_type (log_instance_type_t instance);
|
void log_set_instance_type (log_instance_type_t instance);
|
||||||
@@ -277,9 +278,9 @@ void log_set_instance_type (log_instance_type_t instance);
|
|||||||
log_t *g_log;
|
log_t *g_log;
|
||||||
#else
|
#else
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
extern log_t *g_log;
|
extern log_t *g_log;
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -289,7 +290,7 @@ extern log_t *g_log;
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
int logInit (void);
|
int logInit (void);
|
||||||
void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
|
void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
|
||||||
void log_dump(int component, void *buffer, int buffsize,int datatype, const char* format, ... );
|
void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... );
|
||||||
int set_log(int component, int level);
|
int set_log(int component, int level);
|
||||||
void set_glog(int level);
|
void set_glog(int level);
|
||||||
|
|
||||||
@@ -332,22 +333,22 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
|
|||||||
#define LOG_CONFIG_DUMP_FORMAT "%s_dump"
|
#define LOG_CONFIG_DUMP_FORMAT "%s_dump"
|
||||||
|
|
||||||
#define LOG_CONFIG_HELP_OPTIONS " list of comma separated options to enable log module behavior. Available options: \n"\
|
#define LOG_CONFIG_HELP_OPTIONS " list of comma separated options to enable log module behavior. Available options: \n"\
|
||||||
" nocolor: disable color usage in log messages\n"\
|
" nocolor: disable color usage in log messages\n"\
|
||||||
" level: add log level indication in log messages\n"\
|
" level: add log level indication in log messages\n"\
|
||||||
" thread: add threads names in log messages\n"
|
" thread: add threads names in log messages\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
/* LOG globalconfiguration parameters */
|
/* LOG globalconfiguration parameters */
|
||||||
/* optname help paramflags XXXptr defXXXval type numelt */
|
/* optname help paramflags XXXptr defXXXval type numelt */
|
||||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
#define LOG_GLOBALPARAMS_DESC { \
|
#define LOG_GLOBALPARAMS_DESC { \
|
||||||
{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[2].name, TYPE_STRING, 0}, \
|
{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[2].name, TYPE_STRING, 0}, \
|
||||||
{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \
|
{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \
|
||||||
{LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0} \
|
{LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_OPTIONS_IDX 2
|
#define LOG_OPTIONS_IDX 2
|
||||||
/*----------------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------------*/
|
||||||
@@ -360,22 +361,22 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
|
|||||||
// debugging macros
|
// debugging macros
|
||||||
#define LOG_F LOG_I /* because LOG_F was originaly to dump a message or buffer but is also used as a regular level...., to dump use LOG_DUMPMSG */
|
#define LOG_F LOG_I /* because LOG_F was originaly to dump a message or buffer but is also used as a regular level...., to dump use LOG_DUMPMSG */
|
||||||
# if T_TRACER
|
# if T_TRACER
|
||||||
/* per component, level dependant macros */
|
/* per component, level dependant macros */
|
||||||
# define LOG_E(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} else { T(T_LEGACY_ ## c ## _ERROR, T_PRINTF(x)) ;}} while (0)
|
# define LOG_E(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} else { T(T_LEGACY_ ## c ## _ERROR, T_PRINTF(x)) ;}} while (0)
|
||||||
# define LOG_W(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} else { T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) ;}} while (0)
|
# define LOG_W(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} else { T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) ;}} while (0)
|
||||||
# define LOG_I(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} else { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ;}} while (0)
|
# define LOG_I(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} else { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ;}} while (0)
|
||||||
# define LOG_D(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} else { T(T_LEGACY_ ## c ## _DEBUG, T_PRINTF(x)) ;}} while (0)
|
# define LOG_D(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} else { T(T_LEGACY_ ## c ## _DEBUG, T_PRINTF(x)) ;}} while (0)
|
||||||
# define LOG_T(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} else { T(T_LEGACY_ ## c ## _TRACE, T_PRINTF(x)) ;}} while (0)
|
# define LOG_T(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} else { T(T_LEGACY_ ## c ## _TRACE, T_PRINTF(x)) ;}} while (0)
|
||||||
/* macro used to dump a buffer or a message as in openair2/RRC/LTE/RRC_eNB.c, replaces LOG_F macro */
|
/* macro used to dump a buffer or a message as in openair2/RRC/LTE/RRC_eNB.c, replaces LOG_F macro */
|
||||||
# define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */
|
# define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */
|
||||||
# define nfapi_log(FILE, FNC, LN, COMP, LVL, F...) do { if (T_stdout) { logRecord_mt(__FILE__, __FUNCTION__, __LINE__,COMP, LVL, F) ;}} while (0) /* */
|
# define nfapi_log(FILE, FNC, LN, COMP, LVL, F...) do { if (T_stdout) { logRecord_mt(__FILE__, __FUNCTION__, __LINE__,COMP, LVL, F) ;}} while (0) /* */
|
||||||
/* bitmask dependant macros, to isolate debugging code */
|
/* bitmask dependant macros, to isolate debugging code */
|
||||||
# define LOG_DEBUGFLAG(D) (g_log->debug_mask & D)
|
# define LOG_DEBUGFLAG(D) (g_log->debug_mask & D)
|
||||||
|
|
||||||
/* bitmask dependant macros, to generate debug file such as matlab file or message dump */
|
/* bitmask dependant macros, to generate debug file such as matlab file or message dump */
|
||||||
# define LOG_DUMPFLAG(D) (g_log->dump_mask & D)
|
# define LOG_DUMPFLAG(D) (g_log->dump_mask & D)
|
||||||
# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)/* */
|
# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)/* */
|
||||||
/* define variable only used in LOG macro's */
|
/* define variable only used in LOG macro's */
|
||||||
# define LOG_VAR(A,B) A B
|
# define LOG_VAR(A,B) A B
|
||||||
# else /* T_TRACER: remove all debugging and tracing messages, except errors */
|
# else /* T_TRACER: remove all debugging and tracing messages, except errors */
|
||||||
# define LOG_I(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0)/* */
|
# define LOG_I(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0)/* */
|
||||||
@@ -392,7 +393,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
|
|||||||
# define LOG_VAR(A,B)
|
# define LOG_VAR(A,B)
|
||||||
# endif /* T_TRACER */
|
# endif /* T_TRACER */
|
||||||
/* avoid warnings for variables only used in LOG macro's but set outside debug section */
|
/* avoid warnings for variables only used in LOG macro's but set outside debug section */
|
||||||
#define GCC_NOTUSED __attribute__((unused))
|
#define GCC_NOTUSED __attribute__((unused))
|
||||||
#define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B
|
#define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B
|
||||||
|
|
||||||
/* unfiltered macros, usefull for simulators or messages at init time, before log is configured */
|
/* unfiltered macros, usefull for simulators or messages at init time, before log is configured */
|
||||||
@@ -425,78 +426,82 @@ static __inline__ uint64_t rdtsc(void) {
|
|||||||
|
|
||||||
extern double cpuf;
|
extern double cpuf;
|
||||||
|
|
||||||
static inline uint64_t checkTCPU(int timeout, char * file, int line) {
|
static inline uint64_t checkTCPU(int timeout, char *file, int line) {
|
||||||
static __thread uint64_t lastCPUTime=0;
|
static __thread uint64_t lastCPUTime=0;
|
||||||
static __thread uint64_t last=0;
|
static __thread uint64_t last=0;
|
||||||
uint64_t cur=rdtsc();
|
uint64_t cur=rdtsc();
|
||||||
struct timespec CPUt;
|
struct timespec CPUt;
|
||||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &CPUt);
|
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &CPUt);
|
||||||
uint64_t CPUTime=CPUt.tv_sec*1000*1000+CPUt.tv_nsec/1000;
|
uint64_t CPUTime=CPUt.tv_sec*1000*1000+CPUt.tv_nsec/1000;
|
||||||
double microCycles=(double)(cpuf*1000);
|
double microCycles=(double)(cpuf*1000);
|
||||||
int duration=(int)((cur-last)/microCycles);
|
int duration=(int)((cur-last)/microCycles);
|
||||||
if ( last!=0 && duration > timeout ) {
|
|
||||||
//struct timespec ts;
|
if ( last!=0 && duration > timeout ) {
|
||||||
//clock_gettime(CLOCK_MONOTONIC, &ts);
|
//struct timespec ts;
|
||||||
printf("%s:%d lte-ue delay %d (exceed %d), CPU for this period: %lld\n", file, line,
|
//clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
duration, timeout, (long long)CPUTime-lastCPUTime );
|
printf("%s:%d lte-ue delay %d (exceed %d), CPU for this period: %lld\n", file, line,
|
||||||
}
|
duration, timeout, (long long)CPUTime-lastCPUTime );
|
||||||
last=cur;
|
}
|
||||||
lastCPUTime=CPUTime;
|
|
||||||
return cur;
|
last=cur;
|
||||||
|
lastCPUTime=CPUTime;
|
||||||
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long long checkT(int timeout, char * file, int line) {
|
static inline unsigned long long checkT(int timeout, char *file, int line) {
|
||||||
static __thread unsigned long long last=0;
|
static __thread unsigned long long last=0;
|
||||||
unsigned long long cur=rdtsc();
|
unsigned long long cur=rdtsc();
|
||||||
int microCycles=(int)(cpuf*1000);
|
int microCycles=(int)(cpuf*1000);
|
||||||
int duration=(int)((cur-last)/microCycles);
|
int duration=(int)((cur-last)/microCycles);
|
||||||
if ( last!=0 && duration > timeout )
|
|
||||||
printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line,
|
if ( last!=0 && duration > timeout )
|
||||||
duration, timeout);
|
printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line,
|
||||||
last=cur;
|
duration, timeout);
|
||||||
return cur;
|
|
||||||
|
last=cur;
|
||||||
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct m {
|
typedef struct m {
|
||||||
uint64_t iterations;
|
uint64_t iterations;
|
||||||
uint64_t sum;
|
uint64_t sum;
|
||||||
uint64_t maxArray[11];
|
uint64_t maxArray[11];
|
||||||
} Meas;
|
} Meas;
|
||||||
|
|
||||||
static inline void printMeas(char * txt, Meas *M, int period) {
|
static inline void printMeas(char *txt, Meas *M, int period) {
|
||||||
if (M->iterations%period == 0 ) {
|
if (M->iterations%period == 0 ) {
|
||||||
char txt2[512];
|
char txt2[512];
|
||||||
sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%"
|
sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%"
|
||||||
PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n",
|
PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n",
|
||||||
txt,
|
txt,
|
||||||
M->sum/M->iterations,
|
M->sum/M->iterations,
|
||||||
M->iterations,
|
M->iterations,
|
||||||
M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5],
|
M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5],
|
||||||
M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]);
|
M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]);
|
||||||
#if DISABLE_LOG_X
|
#if DISABLE_LOG_X
|
||||||
printf("%s",txt2);
|
printf("%s",txt2);
|
||||||
#else
|
#else
|
||||||
LOG_W(PHY, "%s",txt2);
|
LOG_W(PHY, "%s",txt2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int cmpint(const void* a, const void* b) {
|
static inline int cmpint(const void *a, const void *b) {
|
||||||
uint64_t* aa=(uint64_t*)a;
|
uint64_t *aa=(uint64_t *)a;
|
||||||
uint64_t* bb=(uint64_t*)b;
|
uint64_t *bb=(uint64_t *)b;
|
||||||
return (int)(*aa-*bb);
|
return (int)(*aa-*bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void updateTimes(uint64_t start, Meas *M, int period, char * txt) {
|
static inline void updateTimes(uint64_t start, Meas *M, int period, char *txt) {
|
||||||
if (start!=0) {
|
if (start!=0) {
|
||||||
uint64_t end=rdtsc();
|
uint64_t end=rdtsc();
|
||||||
long long diff=(end-start)/(cpuf*1000);
|
long long diff=(end-start)/(cpuf*1000);
|
||||||
M->maxArray[0]=diff;
|
M->maxArray[0]=diff;
|
||||||
M->sum+=diff;
|
M->sum+=diff;
|
||||||
M->iterations++;
|
M->iterations++;
|
||||||
qsort(M->maxArray, 11, sizeof(uint64_t), cmpint);
|
qsort(M->maxArray, 11, sizeof(uint64_t), cmpint);
|
||||||
printMeas(txt,M,period);
|
printMeas(txt,M,period);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define check(a) do { checkT(a,__FILE__,__LINE__); } while (0)
|
#define check(a) do { checkT(a,__FILE__,__LINE__); } while (0)
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
int T_stdout;
|
||||||
|
|
||||||
|
void exit_function(const char *file, const char *function, const int line, const char *s) {
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <intertask_interface.h>
|
#include <intertask_interface.h>
|
||||||
|
#include <common/utils/system.h>
|
||||||
|
|
||||||
typedef struct timer_elm_s {
|
typedef struct timer_elm_s {
|
||||||
timer_type_t type; ///< Timer type
|
timer_type_t type; ///< Timer type
|
||||||
@@ -280,22 +281,8 @@ extern "C" {
|
|||||||
|
|
||||||
int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p) {
|
int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p) {
|
||||||
task_list_t *t=&tasks[task_id];
|
task_list_t *t=&tasks[task_id];
|
||||||
AssertFatal ( pthread_create (&t->thread, NULL, start_routine, args_p) ==0,
|
threadCreate (&t->thread, start_routine, args_p, (char*)itti_get_task_name(task_id),-1,OAI_PRIORITY_RT);
|
||||||
"Thread creation for task %d failed!\n", task_id);
|
|
||||||
pthread_setname_np( t->thread, itti_get_task_name(task_id) );
|
|
||||||
LOG_I(TMR,"Created Posix thread %s\n", itti_get_task_name(task_id) );
|
LOG_I(TMR,"Created Posix thread %s\n", itti_get_task_name(task_id) );
|
||||||
#if 1 // BMC test RT prio
|
|
||||||
{
|
|
||||||
int policy;
|
|
||||||
struct sched_param sparam;
|
|
||||||
memset(&sparam, 0, sizeof(sparam));
|
|
||||||
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-10;
|
|
||||||
policy = SCHED_FIFO ;
|
|
||||||
if (pthread_setschedparam(t->thread, policy, &sparam) != 0) {
|
|
||||||
LOG_E(TMR,"task %s : Failed to set pthread priority\n", itti_get_task_name(task_id) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef __SIMPLE_EXE_H__
|
||||||
|
#define __SIMPLE_EXE_H__
|
||||||
|
#ifndef __USE_GNU
|
||||||
|
#define __USE_GNU
|
||||||
|
#endif
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
#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 <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <common/utils/assertions.h>
|
||||||
|
#include <common/utils/LOG/log.h>
|
||||||
|
#include "common_lib.h"
|
||||||
|
|
||||||
|
#ifdef T
|
||||||
|
#undef T
|
||||||
|
#define T(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
+83
-21
@@ -28,13 +28,23 @@
|
|||||||
* separate process solves this problem.
|
* separate process solves this problem.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <common/utils/assertions.h>
|
||||||
|
#include <common/utils/LOG/log.h>
|
||||||
#define MAX_COMMAND 4096
|
#define MAX_COMMAND 4096
|
||||||
|
|
||||||
static int command_pipe_read;
|
static int command_pipe_read;
|
||||||
@@ -50,37 +60,37 @@ static int module_initialized = 0;
|
|||||||
/* util functions */
|
/* util functions */
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
static void lock_system(void)
|
static void lock_system(void) {
|
||||||
{
|
|
||||||
if (pthread_mutex_lock(&lock) != 0) {
|
if (pthread_mutex_lock(&lock) != 0) {
|
||||||
printf("pthread_mutex_lock fails\n");
|
printf("pthread_mutex_lock fails\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unlock_system(void)
|
static void unlock_system(void) {
|
||||||
{
|
|
||||||
if (pthread_mutex_unlock(&lock) != 0) {
|
if (pthread_mutex_unlock(&lock) != 0) {
|
||||||
printf("pthread_mutex_unlock fails\n");
|
printf("pthread_mutex_unlock fails\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_pipe(int p, char *b, int size)
|
static void write_pipe(int p, char *b, int size) {
|
||||||
{
|
|
||||||
while (size) {
|
while (size) {
|
||||||
int ret = write(p, b, size);
|
int ret = write(p, b, size);
|
||||||
|
|
||||||
if (ret <= 0) exit(0);
|
if (ret <= 0) exit(0);
|
||||||
|
|
||||||
b += ret;
|
b += ret;
|
||||||
size -= ret;
|
size -= ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_pipe(int p, char *b, int size)
|
static void read_pipe(int p, char *b, int size) {
|
||||||
{
|
|
||||||
while (size) {
|
while (size) {
|
||||||
int ret = read(p, b, size);
|
int ret = read(p, b, size);
|
||||||
|
|
||||||
if (ret <= 0) exit(0);
|
if (ret <= 0) exit(0);
|
||||||
|
|
||||||
b += ret;
|
b += ret;
|
||||||
size -= ret;
|
size -= ret;
|
||||||
}
|
}
|
||||||
@@ -95,14 +105,13 @@ static void read_pipe(int p, char *b, int size)
|
|||||||
* when the main process exits, because then a "read" on the pipe
|
* when the main process exits, because then a "read" on the pipe
|
||||||
* will return 0, in which case "read_pipe" exits.
|
* will return 0, in which case "read_pipe" exits.
|
||||||
*/
|
*/
|
||||||
static void background_system_process(void)
|
static void background_system_process(void) {
|
||||||
{
|
|
||||||
int len;
|
int len;
|
||||||
int ret;
|
int ret;
|
||||||
char command[MAX_COMMAND+1];
|
char command[MAX_COMMAND+1];
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
read_pipe(command_pipe_read, (char*)&len, sizeof(int));
|
read_pipe(command_pipe_read, (char *)&len, sizeof(int));
|
||||||
read_pipe(command_pipe_read, command, len);
|
read_pipe(command_pipe_read, command, len);
|
||||||
ret = system(command);
|
ret = system(command);
|
||||||
write_pipe(result_pipe_write, (char *)&ret, sizeof(int));
|
write_pipe(result_pipe_write, (char *)&ret, sizeof(int));
|
||||||
@@ -114,8 +123,7 @@ static void background_system_process(void)
|
|||||||
/* return -1 on error, 0 on success */
|
/* return -1 on error, 0 on success */
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
int background_system(char *command)
|
int background_system(char *command) {
|
||||||
{
|
|
||||||
int res;
|
int res;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@@ -125,18 +133,22 @@ int background_system(char *command)
|
|||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(command)+1;
|
len = strlen(command)+1;
|
||||||
|
|
||||||
if (len > MAX_COMMAND) {
|
if (len > MAX_COMMAND) {
|
||||||
printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND);
|
printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND);
|
||||||
printf("command was: '%s'\n", command);
|
printf("command was: '%s'\n", command);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only one command can run at a time, so let's lock/unlock */
|
/* only one command can run at a time, so let's lock/unlock */
|
||||||
lock_system();
|
lock_system();
|
||||||
write_pipe(command_pipe_write, (char*)&len, sizeof(int));
|
write_pipe(command_pipe_write, (char *)&len, sizeof(int));
|
||||||
write_pipe(command_pipe_write, command, len);
|
write_pipe(command_pipe_write, command, len);
|
||||||
read_pipe(result_pipe_read, (char*)&res, sizeof(int));
|
read_pipe(result_pipe_read, (char *)&res, sizeof(int));
|
||||||
unlock_system();
|
unlock_system();
|
||||||
|
|
||||||
if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1;
|
if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,17 +158,16 @@ int background_system(char *command)
|
|||||||
/* to be called very early by the main processing */
|
/* to be called very early by the main processing */
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
void start_background_system(void)
|
void start_background_system(void) {
|
||||||
{
|
|
||||||
int p[2];
|
int p[2];
|
||||||
pid_t son;
|
pid_t son;
|
||||||
|
|
||||||
module_initialized = 1;
|
module_initialized = 1;
|
||||||
|
|
||||||
if (pipe(p) == -1) {
|
if (pipe(p) == -1) {
|
||||||
perror("pipe");
|
perror("pipe");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_pipe_read = p[0];
|
command_pipe_read = p[0];
|
||||||
command_pipe_write = p[1];
|
command_pipe_write = p[1];
|
||||||
|
|
||||||
@@ -164,10 +175,11 @@ void start_background_system(void)
|
|||||||
perror("pipe");
|
perror("pipe");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
result_pipe_read = p[0];
|
result_pipe_read = p[0];
|
||||||
result_pipe_write = p[1];
|
result_pipe_write = p[1];
|
||||||
|
|
||||||
son = fork();
|
son = fork();
|
||||||
|
|
||||||
if (son == -1) {
|
if (son == -1) {
|
||||||
perror("fork");
|
perror("fork");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -181,6 +193,56 @@ void start_background_system(void)
|
|||||||
|
|
||||||
close(result_pipe_read);
|
close(result_pipe_read);
|
||||||
close(command_pipe_write);
|
close(command_pipe_write);
|
||||||
|
|
||||||
background_system_process();
|
background_system_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){
|
||||||
|
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_FIFO);
|
||||||
|
struct sched_param sparam={0};
|
||||||
|
sparam.sched_priority = priority;
|
||||||
|
pthread_attr_setschedparam(&attr, &sparam);
|
||||||
|
|
||||||
|
pthread_create(t, &attr, func, param);
|
||||||
|
|
||||||
|
pthread_setname_np(*t, name);
|
||||||
|
if (affinity != -1 ) {
|
||||||
|
cpu_set_t cpuset;
|
||||||
|
CPU_ZERO(&cpuset);
|
||||||
|
CPU_SET(affinity, &cpuset);
|
||||||
|
AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block CPU C-states deep sleep
|
||||||
|
void configure_linux(void) {
|
||||||
|
int ret;
|
||||||
|
static int latency_target_fd=-1;
|
||||||
|
uint32_t latency_target_value=10; // in microseconds
|
||||||
|
if (latency_target_fd == -1) {
|
||||||
|
if ( (latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR)) != -1 ) {
|
||||||
|
ret = write(latency_target_fd, &latency_target_value, sizeof(latency_target_value));
|
||||||
|
if (ret == 0) {
|
||||||
|
printf("# error setting cpu_dma_latency to %d!: %s\n", latency_target_value, strerror(errno));
|
||||||
|
close(latency_target_fd);
|
||||||
|
latency_target_fd=-1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (latency_target_fd != -1)
|
||||||
|
LOG_I(HW,"# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
|
||||||
|
else
|
||||||
|
LOG_E(HW,"Can't set /dev/cpu_dma_latency to %dus\n", latency_target_value);
|
||||||
|
|
||||||
|
// Set CPU frequency to it's maximum
|
||||||
|
if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
|
||||||
|
LOG_W(HW,"Can't set cpu frequency\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,12 @@
|
|||||||
|
|
||||||
#ifndef _SYSTEM_H_OAI_
|
#ifndef _SYSTEM_H_OAI_
|
||||||
#define _SYSTEM_H_OAI_
|
#define _SYSTEM_H_OAI_
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
* send a command to the background process
|
* send a command to the background process
|
||||||
@@ -36,4 +42,23 @@ int background_system(char *command);
|
|||||||
|
|
||||||
void start_background_system(void);
|
void start_background_system(void);
|
||||||
|
|
||||||
|
void set_latency_target(void);
|
||||||
|
void configure_linux(void);
|
||||||
|
|
||||||
|
void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority);
|
||||||
|
#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO)
|
||||||
|
#define OAI_PRIORITY_RT sched_get_priority_max(SCHED_FIFO)-10
|
||||||
|
#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_FIFO)
|
||||||
|
|
||||||
|
void thread_top_init(char *thread_name,
|
||||||
|
int affinity,
|
||||||
|
uint64_t runtime,
|
||||||
|
uint64_t deadline,
|
||||||
|
uint64_t period);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* _SYSTEM_H_OAI_ */
|
#endif /* _SYSTEM_H_OAI_ */
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
all: measurement_display thread-pool-test
|
||||||
|
|
||||||
|
measurement_display: measurement_display.c thread-pool.h
|
||||||
|
gcc measurement_display.c -I ${OPENAIR_DIR}/ -I ${OPENAIR_DIR}/common/utils/ -I. ${OPENAIR_DIR}/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 ${OPENAIR_DIR}/ -I ${OPENAIR_DIR}/common/utils/ -I. ${OPENAIR_DIR}/common/utils/backtrace.c -I ${OPENAIR_DIR}/openair2/COMMON ${OPENAIR_DIR}/common/utils/LOG/log.c ${OPENAIR_DIR}/common/config/config_userapi.c ${OPENAIR_DIR}/common/config/config_load_configmodule.c ${OPENAIR_DIR}/common/config/config_cmdline.c -lpthread -ldl -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
Author: Laurent THOMAS, Open Cells
|
||||||
|
copyleft: OpenAirInterface Software Alliance and it's licence
|
||||||
|
*/
|
||||||
|
#include <common/utils/simple_executable.h>
|
||||||
|
|
||||||
|
#include "thread-pool.h"
|
||||||
|
|
||||||
|
#define SEP "\t"
|
||||||
|
|
||||||
|
uint64_t cpuCyclesMicroSec;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if(argc != 2) {
|
||||||
|
printf("Need one parameter: 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
//Configure the thread scheduler policy for Linux
|
||||||
|
// set the thread name for debugging
|
||||||
|
sprintf(pool->allthreads->name,"Tpool_%d",pool->allthreads->coreID);
|
||||||
|
threadCreate(&pool->allthreads->threadID, one_thread, (void *)pool->allthreads,
|
||||||
|
pool->allthreads->name, pool->allthreads->coreID, OAI_PRIORITY_RT);
|
||||||
|
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
|
||||||
|
|
||||||
|
void exit_function(const char *file, const char *function, const int line, const char *s) {
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
@@ -0,0 +1,257 @@
|
|||||||
|
/*
|
||||||
|
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>
|
||||||
|
#include <common/utils/system.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_nothreadSafe(notifiedFIFO_t *nf) {
|
||||||
|
nf->inF=NULL;
|
||||||
|
nf->outF=NULL;
|
||||||
|
}
|
||||||
|
static inline void initNotifiedFIFO(notifiedFIFO_t *nf) {
|
||||||
|
mutexinit(nf->lockF);
|
||||||
|
condinit (nf->notifF);
|
||||||
|
initNotifiedFIFO_nothreadSafe(nf);
|
||||||
|
// No delete function: the creator has only to free the memory
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pushNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg) {
|
||||||
|
msg->next=NULL;
|
||||||
|
|
||||||
|
if (nf->outF == NULL)
|
||||||
|
nf->outF = msg;
|
||||||
|
|
||||||
|
if (nf->inF != NULL)
|
||||||
|
nf->inF->next = msg;
|
||||||
|
|
||||||
|
nf->inF = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pushNotifiedFIFO(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg) {
|
||||||
|
mutexlock(nf->lockF);
|
||||||
|
pushNotifiedFIFO_nothreadSafe(nf,msg);
|
||||||
|
condbroadcast(nf->notifF);
|
||||||
|
mutexunlock(nf->lockF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline notifiedFIFO_elt_t *pullNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf) {
|
||||||
|
if (nf->outF == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
notifiedFIFO_elt_t *ret=nf->outF;
|
||||||
|
|
||||||
|
if (nf->outF==nf->outF->next)
|
||||||
|
LOG_E(TMR,"Circular list in thread pool: push several times the same buffer is forbidden\n");
|
||||||
|
|
||||||
|
nf->outF=nf->outF->next;
|
||||||
|
|
||||||
|
if (nf->outF==NULL)
|
||||||
|
nf->inF=NULL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline notifiedFIFO_elt_t *pullNotifiedFIFO(notifiedFIFO_t *nf) {
|
||||||
|
mutexlock(nf->lockF);
|
||||||
|
notifiedFIFO_elt_t *ret;
|
||||||
|
|
||||||
|
while((ret=pullNotifiedFIFO_nothreadSafe(nf)) == NULL)
|
||||||
|
condwait(nf->notifF, nf->lockF);
|
||||||
|
|
||||||
|
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=pullNotifiedFIFO_nothreadSafe(nf);
|
||||||
|
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 >= 0)
|
||||||
|
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
|
||||||
@@ -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.
|
||||||
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
void *calloc_or_fail(size_t size);
|
void *calloc_or_fail(size_t size);
|
||||||
void *malloc_or_fail(size_t size);
|
void *malloc_or_fail(size_t size);
|
||||||
@@ -14,4 +17,17 @@ int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int siz
|
|||||||
|
|
||||||
char *itoa(int i);
|
char *itoa(int i);
|
||||||
|
|
||||||
|
#define findInList(keY, result, list, element_type) {\
|
||||||
|
int i;\
|
||||||
|
for (i=0; i<sizeof(list)/sizeof(element_type) ; i++)\
|
||||||
|
if (list[i].key==keY) {\
|
||||||
|
result=list[i].val;\
|
||||||
|
break;\
|
||||||
|
}\
|
||||||
|
AssertFatal(i < sizeof(list)/sizeof(element_type), "List %s doesn't contain %s\n",#list, #keY); \
|
||||||
|
}
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,941 @@
|
|||||||
|
/*
|
||||||
|
* 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 lte-enb.c
|
||||||
|
* \brief Top-level threads for gNodeB
|
||||||
|
* \author R. Knopp, F. Kaltenberger, Navid Nikaein
|
||||||
|
* \date 2012
|
||||||
|
* \version 0.1
|
||||||
|
* \company Eurecom
|
||||||
|
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "time_utils.h"
|
||||||
|
|
||||||
|
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||||
|
|
||||||
|
#include "assertions.h"
|
||||||
|
#include <common/utils/LOG/log.h>
|
||||||
|
#include <common/utils/system.h>
|
||||||
|
|
||||||
|
#include "PHY/types.h"
|
||||||
|
|
||||||
|
#include "PHY/INIT/phy_init.h"
|
||||||
|
|
||||||
|
#include "PHY/defs_gNB.h"
|
||||||
|
#include "SCHED/sched_eNB.h"
|
||||||
|
#include "SCHED_NR/sched_nr.h"
|
||||||
|
#include "SCHED_NR/fapi_nr_l1.h"
|
||||||
|
#include "PHY/LTE_TRANSPORT/transport_proto.h"
|
||||||
|
|
||||||
|
#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 "../../ARCH/COMMON/common_lib.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/LTE_TRANSPORT/if4_tools.h"
|
||||||
|
#include "PHY/LTE_TRANSPORT/if5_tools.h"
|
||||||
|
|
||||||
|
#include "PHY/phy_extern.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "LAYER2/MAC/mac.h"
|
||||||
|
#include "LAYER2/MAC/mac_extern.h"
|
||||||
|
#include "LAYER2/MAC/mac_proto.h"
|
||||||
|
#include "RRC/LTE/rrc_extern.h"
|
||||||
|
#include "PHY_INTERFACE/phy_interface.h"
|
||||||
|
#include "common/utils/LOG/log_extern.h"
|
||||||
|
#include "UTIL/OTG/otg_tx.h"
|
||||||
|
#include "UTIL/OTG/otg_externs.h"
|
||||||
|
#include "UTIL/MATH/oml.h"
|
||||||
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||||
|
#include "UTIL/OPT/opt.h"
|
||||||
|
#include "enb_config.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OPENAIR2
|
||||||
|
#include "UTIL/OTG/otg_extern.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#include "T.h"
|
||||||
|
|
||||||
|
//#define DEBUG_THREADS 1
|
||||||
|
|
||||||
|
//#define USRP_DEBUG 1
|
||||||
|
// Fix per CC openair rf/if device update
|
||||||
|
// extern openair0_device openair0;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(ENABLE_ITTI)
|
||||||
|
extern volatile int start_gNB;
|
||||||
|
extern volatile int start_UE;
|
||||||
|
#endif
|
||||||
|
extern volatile int oai_exit;
|
||||||
|
|
||||||
|
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||||
|
|
||||||
|
extern int transmission_mode;
|
||||||
|
|
||||||
|
uint16_t sl_ahead=4;
|
||||||
|
uint16_t sf_ahead=4;
|
||||||
|
//pthread_t main_gNB_thread;
|
||||||
|
|
||||||
|
time_stats_t softmodem_stats_mt; // main thread
|
||||||
|
time_stats_t softmodem_stats_hw; // hw acquisition
|
||||||
|
time_stats_t softmodem_stats_rxtx_sf; // total tx time
|
||||||
|
time_stats_t nfapi_meas; // total tx time
|
||||||
|
time_stats_t softmodem_stats_rx_sf; // total rx time
|
||||||
|
|
||||||
|
/* mutex, cond and variable to serialize phy proc TX calls
|
||||||
|
* (this mechanism may be relaxed in the future for better
|
||||||
|
* performances)
|
||||||
|
*/
|
||||||
|
static struct {
|
||||||
|
pthread_mutex_t mutex_phy_proc_tx;
|
||||||
|
pthread_cond_t cond_phy_proc_tx;
|
||||||
|
volatile uint8_t phy_proc_CC_id;
|
||||||
|
} sync_phy_proc;
|
||||||
|
|
||||||
|
extern double cpuf;
|
||||||
|
|
||||||
|
void init_gNB(int,int);
|
||||||
|
void stop_gNB(int nb_inst);
|
||||||
|
|
||||||
|
int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB);
|
||||||
|
int wakeup_tx(PHY_VARS_gNB *gNB);
|
||||||
|
extern PARALLEL_CONF_t get_thread_parallel_conf(void);
|
||||||
|
extern WORKER_CONF_t get_thread_worker_conf(void);
|
||||||
|
|
||||||
|
|
||||||
|
void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe);
|
||||||
|
|
||||||
|
extern uint8_t nfapi_mode;
|
||||||
|
extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
|
||||||
|
extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
|
||||||
|
|
||||||
|
//#define TICK_TO_US(ts) (ts.diff)
|
||||||
|
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
|
||||||
|
|
||||||
|
|
||||||
|
static inline int rxtx(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc, char *thread_name) {
|
||||||
|
start_meas(&softmodem_stats_rxtx_sf);
|
||||||
|
|
||||||
|
// *******************************************************************
|
||||||
|
|
||||||
|
if (nfapi_mode == 1) {
|
||||||
|
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
|
||||||
|
uint16_t frame = proc->frame_rx;
|
||||||
|
uint16_t slot = proc->slot_rx;
|
||||||
|
//add_subframe(&frame, &subframe, 4);
|
||||||
|
//oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
|
||||||
|
//LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
|
||||||
|
start_meas(&nfapi_meas);
|
||||||
|
oai_subframe_ind(frame, slot);
|
||||||
|
stop_meas(&nfapi_meas);
|
||||||
|
|
||||||
|
if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
|
||||||
|
gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
|
||||||
|
gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
|
||||||
|
gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
|
||||||
|
gNB->UL_INFO.cqi_ind.number_of_cqis
|
||||||
|
) {
|
||||||
|
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
|
||||||
|
NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
|
||||||
|
NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
|
||||||
|
NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
|
||||||
|
NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
|
||||||
|
gNB->UL_INFO.cqi_ind.number_of_cqis,
|
||||||
|
proc->frame_rx, proc->slot_rx,
|
||||||
|
proc->frame_tx, proc->slot_tx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// NR disabling
|
||||||
|
// ****************************************
|
||||||
|
// Common RX procedures subframe n
|
||||||
|
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->slot_tx));
|
||||||
|
/*
|
||||||
|
// if this is IF5 or 3GPP_gNB
|
||||||
|
if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
|
||||||
|
wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// UE-specific RX processing for subframe n
|
||||||
|
if (nfapi_mode == 0 || nfapi_mode == 1) {
|
||||||
|
phy_procedures_gNB_uespec_RX(gNB, proc, no_relay );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
pthread_mutex_lock(&gNB->UL_INFO_mutex);
|
||||||
|
gNB->UL_INFO.frame = proc->frame_rx;
|
||||||
|
gNB->UL_INFO.slot = proc->slot_rx;
|
||||||
|
gNB->UL_INFO.module_id = gNB->Mod_id;
|
||||||
|
gNB->UL_INFO.CC_id = gNB->CC_id;
|
||||||
|
gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
|
||||||
|
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
|
||||||
|
|
||||||
|
/// end
|
||||||
|
// *****************************************
|
||||||
|
// TX processing for subframe n+sl_ahead
|
||||||
|
// run PHY TX procedures the one after the other for all CCs to avoid race conditions
|
||||||
|
// (may be relaxed in the future for performance reasons)
|
||||||
|
// *****************************************
|
||||||
|
//if (wait_CCs(proc)<0) return(-1);
|
||||||
|
|
||||||
|
if (oai_exit) return(-1);
|
||||||
|
|
||||||
|
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
|
||||||
|
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_meas( &softmodem_stats_rxtx_sf );
|
||||||
|
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->slot_rx, proc->frame_tx, proc->slot_tx);
|
||||||
|
#if 0
|
||||||
|
LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
|
||||||
|
softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now,
|
||||||
|
TICK_TO_US(gNB->phy_proc),
|
||||||
|
TICK_TO_US(gNB->phy_proc_tx),
|
||||||
|
TICK_TO_US(gNB->phy_proc_rx),
|
||||||
|
TICK_TO_US(gNB->rx_prach),
|
||||||
|
TICK_TO_US(gNB->ofdm_mod_stats),
|
||||||
|
softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now);
|
||||||
|
LOG_D(PHY,
|
||||||
|
"dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ",
|
||||||
|
TICK_TO_US(gNB->dlsch_encoding_stats),
|
||||||
|
TICK_TO_US(gNB->dlsch_modulation_stats),
|
||||||
|
TICK_TO_US(gNB->dlsch_scrambling_stats),
|
||||||
|
TICK_TO_US(gNB->dlsch_rate_matching_stats),
|
||||||
|
TICK_TO_US(gNB->dlsch_turbo_encoding_stats),
|
||||||
|
TICK_TO_US(gNB->dlsch_interleaving_stats),
|
||||||
|
TICK_TO_US(gNB->rx_dft_stats));
|
||||||
|
LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ",
|
||||||
|
TICK_TO_US(gNB->ulsch_channel_estimation_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_freq_offset_estimation_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_decoding_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_demodulation_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_rate_unmatching_stats));
|
||||||
|
LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ",
|
||||||
|
TICK_TO_US(gNB->ulsch_turbo_decoding_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_deinterleaving_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_demultiplexing_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_llr_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_tc_init_stats));
|
||||||
|
LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n",
|
||||||
|
TICK_TO_US(gNB->ulsch_tc_alpha_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_tc_beta_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_tc_gamma_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_tc_ext_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_tc_intl1_stats),
|
||||||
|
TICK_TO_US(gNB->ulsch_tc_intl2_stats)
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *gNB_L1_thread_tx(void *param) {
|
||||||
|
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
|
||||||
|
gNB_L1_proc_t *gNB_proc = &gNB->proc;
|
||||||
|
gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc_tx;
|
||||||
|
//PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
|
||||||
|
char thread_name[100];
|
||||||
|
sprintf(thread_name,"TXnp4_%d\n",&gNB->proc.L1_proc == proc ? 0 : 1);
|
||||||
|
|
||||||
|
//wait_sync("tx_thread");
|
||||||
|
|
||||||
|
while (!oai_exit) {
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 );
|
||||||
|
|
||||||
|
if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
|
||||||
|
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 );
|
||||||
|
|
||||||
|
if (oai_exit) break;
|
||||||
|
|
||||||
|
// *****************************************
|
||||||
|
// TX processing for subframe n+4
|
||||||
|
// run PHY TX procedures the one after the other for all CCs to avoid race conditions
|
||||||
|
// (may be relaxed in the future for performance reasons)
|
||||||
|
// *****************************************
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,proc->slot_tx);
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB,proc->slot_rx);
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,proc->frame_tx);
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_GNB,proc->frame_rx);
|
||||||
|
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||||
|
pthread_mutex_lock( &proc->mutex );
|
||||||
|
proc->instance_cnt = -1;
|
||||||
|
|
||||||
|
// the thread can now be woken up
|
||||||
|
if (pthread_cond_signal(&proc->cond) != 0) {
|
||||||
|
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
|
||||||
|
exit_fun( "ERROR pthread_cond_signal" );
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock( &proc->mutex );
|
||||||
|
wakeup_txfh(proc,gNB);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The RX UE-specific and TX thread of gNB.
|
||||||
|
* \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
|
||||||
|
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void *gNB_L1_thread( void *param ) {
|
||||||
|
static int gNB_thread_rxtx_status;
|
||||||
|
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
|
||||||
|
gNB_L1_proc_t *gNB_proc = &gNB->proc;
|
||||||
|
gNB_L1_rxtx_proc_t *proc = &gNB_proc->L1_proc;
|
||||||
|
//PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
|
||||||
|
char thread_name[100];
|
||||||
|
// set default return value
|
||||||
|
gNB_thread_rxtx_status = 0;
|
||||||
|
sprintf(thread_name,"RXn_TXnp4_%d",&gNB->proc.L1_proc == proc ? 0 : 1);
|
||||||
|
|
||||||
|
while (!oai_exit) {
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 );
|
||||||
|
|
||||||
|
if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
|
||||||
|
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 );
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,proc->slot_tx);
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,proc->slot_rx);
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,proc->frame_tx);
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,proc->frame_rx);
|
||||||
|
|
||||||
|
if (oai_exit) break;
|
||||||
|
|
||||||
|
if (gNB->CC_id==0) {
|
||||||
|
if (rxtx(gNB,proc,thread_name) < 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) {
|
||||||
|
phy_procedures_gNB_TX(gNB, proc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
|
||||||
|
|
||||||
|
if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||||
|
wakeup_tx(gNB);
|
||||||
|
} else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) {
|
||||||
|
wakeup_txfh(proc,gNB);
|
||||||
|
}
|
||||||
|
} // while !oai_exit
|
||||||
|
|
||||||
|
LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n");
|
||||||
|
gNB_thread_rxtx_status = 0;
|
||||||
|
return &gNB_thread_rxtx_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 //defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
|
||||||
|
// Wait for gNB application initialization to be complete (gNB registration to MME)
|
||||||
|
static void wait_system_ready (char *message, volatile int *start_flag) {
|
||||||
|
static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....",
|
||||||
|
" ....", " ...", " ..", " .", " "
|
||||||
|
};
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while ((!oai_exit) && (*start_flag == 0)) {
|
||||||
|
LOG_N(EMU, message, indicator[i]);
|
||||||
|
fflush(stdout);
|
||||||
|
i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0]));
|
||||||
|
usleep(200000);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_D(EMU,"\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru) {
|
||||||
|
gNB_L1_proc_t *proc = &gNB->proc;
|
||||||
|
gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
|
||||||
|
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||||
|
RU_proc_t *ru_proc=&ru->proc;
|
||||||
|
proc->frame_rx = frame_rx;
|
||||||
|
proc->slot_rx = slot_rx;
|
||||||
|
|
||||||
|
if (!oai_exit) {
|
||||||
|
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx));
|
||||||
|
L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot);
|
||||||
|
L1_proc->frame_rx = ru_proc->frame_rx;
|
||||||
|
L1_proc->slot_rx = ru_proc->tti_rx;
|
||||||
|
L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
|
||||||
|
L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame;
|
||||||
|
|
||||||
|
if (rxtx(gNB,L1_proc,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id);
|
||||||
|
|
||||||
|
ru_proc->timestamp_tx = L1_proc->timestamp_tx;
|
||||||
|
ru_proc->tti_tx = L1_proc->slot_tx;
|
||||||
|
ru_proc->frame_tx = L1_proc->frame_tx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int wakeup_txfh(gNB_L1_rxtx_proc_t *proc,PHY_VARS_gNB *gNB) {
|
||||||
|
RU_t *ru;
|
||||||
|
RU_proc_t *ru_proc;
|
||||||
|
struct timespec wait;
|
||||||
|
wait.tv_sec=0;
|
||||||
|
wait.tv_nsec=5000000L;
|
||||||
|
//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->slot_tx, proc->instance_cnt_RUs);
|
||||||
|
|
||||||
|
if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) {
|
||||||
|
LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->slot_tx);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&gNB->proc.mutex_RU_tx);
|
||||||
|
gNB->proc.RU_mask_tx = 0;
|
||||||
|
pthread_mutex_unlock(&gNB->proc.mutex_RU_tx);
|
||||||
|
|
||||||
|
if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1);
|
||||||
|
|
||||||
|
for(int i=0; i<gNB->num_RU; i++) {
|
||||||
|
ru = gNB->RU_list[i];
|
||||||
|
ru_proc = &ru->proc;
|
||||||
|
|
||||||
|
if (ru_proc->instance_cnt_gNBs == 0) {
|
||||||
|
LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->slot_rx);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_mutex_timedlock(&ru_proc->mutex_gNBs,&wait) != 0) {
|
||||||
|
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->tti_rx&1,ru_proc->instance_cnt_gNBs );
|
||||||
|
exit_fun( "error locking mutex_gNB" );
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ru_proc->instance_cnt_gNBs = 0;
|
||||||
|
ru_proc->timestamp_tx = proc->timestamp_tx;
|
||||||
|
ru_proc->tti_tx = proc->slot_tx;
|
||||||
|
ru_proc->frame_tx = proc->frame_tx;
|
||||||
|
LOG_I(PHY,"Signaling tx_thread_fh for %d.%d\n",ru_proc->frame_tx,ru_proc->tti_tx);
|
||||||
|
|
||||||
|
// the thread can now be woken up
|
||||||
|
if (pthread_cond_signal(&ru_proc->cond_gNBs) != 0) {
|
||||||
|
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
|
||||||
|
exit_fun( "ERROR pthread_cond_signal" );
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock( &ru_proc->mutex_gNBs );
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wakeup_tx(PHY_VARS_gNB *gNB) {
|
||||||
|
gNB_L1_proc_t *proc=&gNB->proc;
|
||||||
|
gNB_L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx;
|
||||||
|
gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
|
||||||
|
struct timespec wait;
|
||||||
|
wait.tv_sec=0;
|
||||||
|
wait.tv_nsec=5000000L;
|
||||||
|
|
||||||
|
if (pthread_mutex_timedlock(&L1_proc_tx->mutex,&wait) != 0) {
|
||||||
|
LOG_E(PHY, "[SCHED][eNB] ERROR locking mutex for eNB L1_thread_tx\n");
|
||||||
|
exit_fun("ERROR pthread_lock");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(L1_proc_tx->instance_cnt == 0) {
|
||||||
|
pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
L1_proc_tx->instance_cnt = 0;
|
||||||
|
L1_proc_tx->slot_rx = L1_proc->slot_rx;
|
||||||
|
L1_proc_tx->frame_rx = L1_proc->frame_rx;
|
||||||
|
L1_proc_tx->slot_tx = L1_proc->slot_tx;
|
||||||
|
L1_proc_tx->frame_tx = L1_proc->frame_tx;
|
||||||
|
L1_proc_tx->timestamp_tx = L1_proc->timestamp_tx;
|
||||||
|
|
||||||
|
// the thread can now be woken up
|
||||||
|
if (pthread_cond_signal(&L1_proc_tx->cond) != 0) {
|
||||||
|
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
|
||||||
|
exit_fun( "ERROR pthread_cond_signal" );
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock( &L1_proc_tx->mutex);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
||||||
|
gNB_L1_proc_t *proc=&gNB->proc;
|
||||||
|
gNB_L1_rxtx_proc_t *L1_proc=&proc->L1_proc;
|
||||||
|
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||||
|
RU_proc_t *ru_proc=&ru->proc;
|
||||||
|
int i;
|
||||||
|
struct timespec wait;
|
||||||
|
pthread_mutex_lock(&proc->mutex_RU);
|
||||||
|
|
||||||
|
for (i=0; i<gNB->num_RU; i++) {
|
||||||
|
if (ru == gNB->RU_list[i]) {
|
||||||
|
if ((proc->RU_mask&(1<<i)) > 0)
|
||||||
|
LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
|
||||||
|
gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask);
|
||||||
|
|
||||||
|
proc->RU_mask |= (1<<i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proc->RU_mask != (1<<gNB->num_RU)-1) { // not all RUs have provided their information so return
|
||||||
|
LOG_E(PHY,"Not all RUs have provided their info\n");
|
||||||
|
pthread_mutex_unlock(&proc->mutex_RU);
|
||||||
|
return(0);
|
||||||
|
} else { // all RUs have provided their information so continue on and wakeup gNB processing
|
||||||
|
proc->RU_mask = 0;
|
||||||
|
pthread_mutex_unlock(&proc->mutex_RU);
|
||||||
|
}
|
||||||
|
|
||||||
|
wait.tv_sec=0;
|
||||||
|
wait.tv_nsec=5000000L;
|
||||||
|
|
||||||
|
/* accept some delay in processing - up to 5ms */
|
||||||
|
for (i = 0; i < fp->slots_per_frame && L1_proc->instance_cnt == 0; i++) {
|
||||||
|
LOG_W( PHY,"[gNB] SFN.SL %d.%d, gNB RXn-TXnp4 thread busy!! (i %d, cnt %i)\n", L1_proc->frame_tx, L1_proc->slot_tx, i,L1_proc->instance_cnt);
|
||||||
|
usleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (L1_proc->instance_cnt == 0) {
|
||||||
|
exit_fun( "TX thread busy" );
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wake up TX for subframe n+sl_ahead
|
||||||
|
// lock the TX mutex and make sure the thread is ready
|
||||||
|
if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
|
||||||
|
LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt );
|
||||||
|
exit_fun( "error locking mutex" );
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
++L1_proc->instance_cnt;
|
||||||
|
// We have just received and processed the common part of a subframe, say n.
|
||||||
|
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
|
||||||
|
// transmitted timestamp of the next TX slot (first).
|
||||||
|
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
|
||||||
|
// we want to generate subframe (n+sl_ahead), so TS_tx = TX_rx+sl_ahead*samples_per_tti,
|
||||||
|
// and proc->slot_tx = proc->slot_rx+sl_ahead
|
||||||
|
L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot);
|
||||||
|
L1_proc->frame_rx = ru_proc->frame_rx;
|
||||||
|
L1_proc->slot_rx = ru_proc->tti_rx;
|
||||||
|
L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
|
||||||
|
L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame;
|
||||||
|
LOG_I(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead);
|
||||||
|
|
||||||
|
// the thread can now be woken up
|
||||||
|
if (pthread_cond_signal(&L1_proc->cond) != 0) {
|
||||||
|
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n");
|
||||||
|
exit_fun( "ERROR pthread_cond_signal" );
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock( &L1_proc->mutex );
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe) {
|
||||||
|
|
||||||
|
gNB_L1_proc_t *proc = &gNB->proc;
|
||||||
|
LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (ru!=NULL) {
|
||||||
|
pthread_mutex_lock(&proc->mutex_RU_PRACH);
|
||||||
|
for (i=0;i<gNB->num_RU;i++) {
|
||||||
|
if (ru == gNB->RU_list[i]) {
|
||||||
|
LOG_D(PHY,"frame %d, subframe %d: RU %d for gNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,gNB->Mod_id,proc->RU_mask_prach,gNB->num_RU);
|
||||||
|
if ((proc->RU_mask_prach&(1<<i)) > 0)
|
||||||
|
LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
|
||||||
|
gNB->Mod_id,frame,subframe,ru->idx,gNB->num_RU,proc->RU_mask_prach);
|
||||||
|
proc->RU_mask_prach |= (1<<i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (proc->RU_mask_prach != (1<<gNB->num_RU)-1) { // not all RUs have provided their information so return
|
||||||
|
pthread_mutex_unlock(&proc->mutex_RU_PRACH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else { // all RUs have provided their information so continue on and wakeup gNB processing
|
||||||
|
proc->RU_mask_prach = 0;
|
||||||
|
pthread_mutex_unlock(&proc->mutex_RU_PRACH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we have to detect PRACH first
|
||||||
|
if (is_prach_subframe(fp,frame,subframe)>0) {
|
||||||
|
LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe);
|
||||||
|
if (proc->instance_cnt_prach == 0) {
|
||||||
|
LOG_W(PHY,"[gNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wake up thread for PRACH RX
|
||||||
|
if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
|
||||||
|
LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach);
|
||||||
|
exit_fun( "error locking mutex_prach" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
++proc->instance_cnt_prach;
|
||||||
|
// set timing for prach thread
|
||||||
|
proc->frame_prach = frame;
|
||||||
|
proc->subframe_prach = subframe;
|
||||||
|
|
||||||
|
// the thread can now be woken up
|
||||||
|
if (pthread_cond_signal(&proc->cond_prach) != 0) {
|
||||||
|
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB PRACH thread %d\n", proc->thread_index);
|
||||||
|
exit_fun( "ERROR pthread_cond_signal" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock( &proc->mutex_prach );
|
||||||
|
}
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The prach receive thread of gNB.
|
||||||
|
* \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
|
||||||
|
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
static void* gNB_thread_prach( void* param ) {
|
||||||
|
static int gNB_thread_prach_status;
|
||||||
|
|
||||||
|
|
||||||
|
PHY_VARS_gNB *gNB= (PHY_VARS_gNB *)param;
|
||||||
|
gNB_L1_proc_t *proc = &gNB->proc;
|
||||||
|
|
||||||
|
// set default return value
|
||||||
|
gNB_thread_prach_status = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
while (!oai_exit) {
|
||||||
|
|
||||||
|
if (oai_exit) break;
|
||||||
|
|
||||||
|
|
||||||
|
if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break;
|
||||||
|
|
||||||
|
LOG_D(PHY,"Running gNB prach procedures\n");
|
||||||
|
prach_procedures(gNB
|
||||||
|
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||||
|
,0
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_I(PHY, "Exiting gNB thread PRACH\n");
|
||||||
|
|
||||||
|
gNB_thread_prach_status = 0;
|
||||||
|
return &gNB_thread_prach_status;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void init_td_thread(PHY_VARS_gNB *);
|
||||||
|
extern void init_te_thread(PHY_VARS_gNB *);
|
||||||
|
|
||||||
|
void init_gNB_proc(int inst) {
|
||||||
|
int i=0;
|
||||||
|
int CC_id;
|
||||||
|
PHY_VARS_gNB *gNB;
|
||||||
|
gNB_L1_proc_t *proc;
|
||||||
|
gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx;
|
||||||
|
LOG_I(PHY,"%s(inst:%d) RC.nb_nr_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_nr_CC[inst]);
|
||||||
|
|
||||||
|
for (CC_id=0; CC_id<RC.nb_nr_CC[inst]; CC_id++) {
|
||||||
|
gNB = RC.gNB[inst][CC_id];
|
||||||
|
#ifndef OCP_FRAMEWORK
|
||||||
|
LOG_I(PHY,"Initializing gNB processes instance:%d CC_id %d \n",inst,CC_id);
|
||||||
|
#endif
|
||||||
|
proc = &gNB->proc;
|
||||||
|
L1_proc = &proc->L1_proc;
|
||||||
|
L1_proc_tx = &proc->L1_proc_tx;
|
||||||
|
L1_proc->instance_cnt = -1;
|
||||||
|
L1_proc_tx->instance_cnt = -1;
|
||||||
|
L1_proc->instance_cnt_RUs = 0;
|
||||||
|
L1_proc_tx->instance_cnt_RUs = 0;
|
||||||
|
proc->instance_cnt_prach = -1;
|
||||||
|
proc->instance_cnt_asynch_rxtx = -1;
|
||||||
|
proc->CC_id = CC_id;
|
||||||
|
proc->first_rx =1;
|
||||||
|
proc->first_tx =1;
|
||||||
|
proc->RU_mask =0;
|
||||||
|
proc->RU_mask_tx = (1<<gNB->num_RU)-1;
|
||||||
|
proc->RU_mask_prach =0;
|
||||||
|
pthread_mutex_init( &gNB->UL_INFO_mutex, NULL);
|
||||||
|
pthread_mutex_init( &L1_proc->mutex, NULL);
|
||||||
|
pthread_mutex_init( &L1_proc_tx->mutex, NULL);
|
||||||
|
pthread_cond_init( &L1_proc->cond, NULL);
|
||||||
|
pthread_cond_init( &L1_proc_tx->cond, NULL);
|
||||||
|
pthread_mutex_init( &proc->mutex_prach, NULL);
|
||||||
|
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
|
||||||
|
pthread_mutex_init( &proc->mutex_RU,NULL);
|
||||||
|
pthread_mutex_init( &proc->mutex_RU_tx,NULL);
|
||||||
|
pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
|
||||||
|
pthread_cond_init( &proc->cond_prach, NULL);
|
||||||
|
pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
|
||||||
|
LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag);
|
||||||
|
|
||||||
|
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||||
|
threadCreate( &L1_proc->pthread, gNB_L1_thread, gNB, "L1_proc", -1, OAI_PRIORITY_RT );
|
||||||
|
threadCreate( &L1_proc_tx->pthread, gNB_L1_thread_tx, gNB,"L1_proc_tx", -1, OAI_PRIORITY_RT);
|
||||||
|
}
|
||||||
|
|
||||||
|
//pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB );
|
||||||
|
char name[16];
|
||||||
|
|
||||||
|
if (gNB->single_thread_flag==0) {
|
||||||
|
snprintf( name, sizeof(name), "L1 %d", i );
|
||||||
|
pthread_setname_np( L1_proc->pthread, name );
|
||||||
|
snprintf( name, sizeof(name), "L1TX %d", i );
|
||||||
|
pthread_setname_np( L1_proc_tx->pthread, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setup PHY proc TX sync mechanism */
|
||||||
|
pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
|
||||||
|
pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
|
||||||
|
sync_phy_proc.phy_proc_CC_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Terminate gNB TX and RX threads.
|
||||||
|
*/
|
||||||
|
void kill_gNB_proc(int inst) {
|
||||||
|
int *status;
|
||||||
|
PHY_VARS_gNB *gNB;
|
||||||
|
gNB_L1_proc_t *proc;
|
||||||
|
gNB_L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
|
||||||
|
|
||||||
|
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||||
|
gNB=RC.gNB[inst][CC_id];
|
||||||
|
proc = &gNB->proc;
|
||||||
|
L1_proc = &proc->L1_proc;
|
||||||
|
L1_proc_tx = &proc->L1_proc_tx;
|
||||||
|
LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );
|
||||||
|
|
||||||
|
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||||
|
pthread_mutex_lock(&L1_proc->mutex);
|
||||||
|
L1_proc->instance_cnt = 0;
|
||||||
|
pthread_cond_signal(&L1_proc->cond);
|
||||||
|
pthread_mutex_unlock(&L1_proc->mutex);
|
||||||
|
pthread_mutex_lock(&L1_proc_tx->mutex);
|
||||||
|
L1_proc_tx->instance_cnt = 0;
|
||||||
|
pthread_cond_signal(&L1_proc_tx->cond);
|
||||||
|
pthread_mutex_unlock(&L1_proc_tx->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
proc->instance_cnt_prach = 0;
|
||||||
|
pthread_cond_signal( &proc->cond_prach );
|
||||||
|
pthread_cond_signal( &proc->cond_asynch_rxtx );
|
||||||
|
pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
|
||||||
|
// LOG_D(PHY, "joining pthread_prach\n");
|
||||||
|
// pthread_join( proc->pthread_prach, (void**)&status );
|
||||||
|
LOG_I(PHY, "Destroying prach mutex/cond\n");
|
||||||
|
pthread_mutex_destroy( &proc->mutex_prach );
|
||||||
|
pthread_cond_destroy( &proc->cond_prach );
|
||||||
|
LOG_I(PHY, "Destroying UL_INFO mutex\n");
|
||||||
|
pthread_mutex_destroy(&gNB->UL_INFO_mutex);
|
||||||
|
|
||||||
|
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
|
||||||
|
LOG_I(PHY, "Joining L1_proc mutex/cond\n");
|
||||||
|
pthread_join( L1_proc->pthread, (void **)&status );
|
||||||
|
LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n");
|
||||||
|
pthread_join( L1_proc_tx->pthread, (void **)&status );
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_I(PHY, "Destroying L1_proc mutex/cond\n");
|
||||||
|
pthread_mutex_destroy( &L1_proc->mutex );
|
||||||
|
pthread_cond_destroy( &L1_proc->cond );
|
||||||
|
LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n");
|
||||||
|
pthread_mutex_destroy( &L1_proc_tx->mutex );
|
||||||
|
pthread_cond_destroy( &L1_proc_tx->cond );
|
||||||
|
pthread_mutex_destroy( &proc->mutex_RU );
|
||||||
|
pthread_mutex_destroy( &proc->mutex_RU_tx );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void reset_opp_meas(void) {
|
||||||
|
int sfn;
|
||||||
|
reset_meas(&softmodem_stats_mt);
|
||||||
|
reset_meas(&softmodem_stats_hw);
|
||||||
|
|
||||||
|
for (sfn=0; sfn < 10; sfn++) {
|
||||||
|
reset_meas(&softmodem_stats_rxtx_sf);
|
||||||
|
reset_meas(&softmodem_stats_rx_sf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_opp_meas(void) {
|
||||||
|
int sfn=0;
|
||||||
|
print_meas(&softmodem_stats_mt, "Main gNB Thread", NULL, NULL);
|
||||||
|
print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL);
|
||||||
|
|
||||||
|
for (sfn=0; sfn < 10; sfn++) {
|
||||||
|
print_meas(&softmodem_stats_rxtx_sf,"[gNB][total_phy_proc_rxtx]",NULL, NULL);
|
||||||
|
print_meas(&softmodem_stats_rx_sf,"[gNB][total_phy_proc_rx]",NULL,NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// eNB kept in function name for nffapi calls, TO FIX
|
||||||
|
void init_eNB_afterRU(void) {
|
||||||
|
int inst,CC_id,ru_id,i,aa;
|
||||||
|
PHY_VARS_gNB *gNB;
|
||||||
|
LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst);
|
||||||
|
|
||||||
|
for (inst=0; inst<RC.nb_nr_inst; inst++) {
|
||||||
|
LOG_I(PHY,"RC.nb_nr_CC[inst]:%d\n", RC.nb_nr_CC[inst]);
|
||||||
|
|
||||||
|
for (CC_id=0; CC_id<RC.nb_nr_CC[inst]; CC_id++) {
|
||||||
|
LOG_I(PHY,"RC.nb_nr_CC[inst:%d][CC_id:%d]:%p\n", inst, CC_id, RC.gNB[inst][CC_id]);
|
||||||
|
gNB = RC.gNB[inst][CC_id];
|
||||||
|
phy_init_nr_gNB(gNB,0,0);
|
||||||
|
|
||||||
|
// map antennas and PRACH signals to gNB RX
|
||||||
|
if (0) AssertFatal(gNB->num_RU>0,"Number of RU attached to gNB %d is zero\n",gNB->Mod_id);
|
||||||
|
|
||||||
|
LOG_I(PHY,"Mapping RX ports from %d RUs to gNB %d\n",gNB->num_RU,gNB->Mod_id);
|
||||||
|
//LOG_I(PHY,"Overwriting gNB->prach_vars.rxsigF[0]:%p\n", gNB->prach_vars.rxsigF[0]);
|
||||||
|
gNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *));
|
||||||
|
LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU);
|
||||||
|
|
||||||
|
for (ru_id=0,aa=0; ru_id<gNB->num_RU; ru_id++) {
|
||||||
|
AssertFatal(gNB->RU_list[ru_id]->common.rxdataF!=NULL,
|
||||||
|
"RU %d : common.rxdataF is NULL\n",
|
||||||
|
gNB->RU_list[ru_id]->idx);
|
||||||
|
AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF!=NULL,
|
||||||
|
"RU %d : prach_rxsigF is NULL\n",
|
||||||
|
gNB->RU_list[ru_id]->idx);
|
||||||
|
|
||||||
|
for (i=0; i<gNB->RU_list[ru_id]->nb_rx; aa++,i++) {
|
||||||
|
LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
|
||||||
|
gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
|
||||||
|
gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: review this code, there is something wrong.
|
||||||
|
* In monolithic mode, we come here with nb_antennas_rx == 0
|
||||||
|
* (not tested in other modes).
|
||||||
|
*/
|
||||||
|
//init_precoding_weights(RC.gNB[inst][CC_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
init_gNB_proc(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
|
||||||
|
AssertFatal(RC.ru[ru_id]!=NULL,"ru_id %d is null\n",ru_id);
|
||||||
|
RC.ru[ru_id]->nr_wakeup_rxtx = wakeup_rxtx;
|
||||||
|
// RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_gNB;
|
||||||
|
RC.ru[ru_id]->gNB_top = gNB_top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_gNB(int single_thread_flag,int wait_for_sync) {
|
||||||
|
int CC_id;
|
||||||
|
int inst;
|
||||||
|
PHY_VARS_gNB *gNB;
|
||||||
|
LOG_I(PHY,"[nr-softmodem.c] gNB structure about to allocated RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC[0]:%d\n",RC.nb_nr_L1_inst,RC.nb_nr_L1_CC[0]);
|
||||||
|
|
||||||
|
if (RC.gNB == NULL) RC.gNB = (PHY_VARS_gNB ***) malloc(RC.nb_nr_L1_inst*sizeof(PHY_VARS_gNB **));
|
||||||
|
|
||||||
|
LOG_I(PHY,"[lte-softmodem.c] gNB structure RC.gNB allocated\n");
|
||||||
|
|
||||||
|
for (inst=0; inst<RC.nb_nr_L1_inst; inst++) {
|
||||||
|
if (RC.gNB[inst] == NULL) RC.gNB[inst] = (PHY_VARS_gNB **) malloc(RC.nb_nr_CC[inst]*sizeof(PHY_VARS_gNB *));
|
||||||
|
|
||||||
|
for (CC_id=0; CC_id<RC.nb_nr_L1_CC[inst]; CC_id++) {
|
||||||
|
if (RC.gNB[inst][CC_id] == NULL) RC.gNB[inst][CC_id] = (PHY_VARS_gNB *) malloc(sizeof(PHY_VARS_gNB));
|
||||||
|
|
||||||
|
gNB = RC.gNB[inst][CC_id];
|
||||||
|
gNB->abstraction_flag = 0;
|
||||||
|
gNB->single_thread_flag = single_thread_flag;
|
||||||
|
/*nr_polar_init(&gNB->nrPolar_params,
|
||||||
|
NR_POLAR_PBCH_MESSAGE_TYPE,
|
||||||
|
NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||||
|
NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
|
||||||
|
LOG_I(PHY,"Initializing gNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag);
|
||||||
|
#ifndef OCP_FRAMEWORK
|
||||||
|
LOG_I(PHY,"Initializing gNB %d CC_id %d\n",inst,CC_id);
|
||||||
|
#endif
|
||||||
|
LOG_I(PHY,"Registering with MAC interface module\n");
|
||||||
|
AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface");
|
||||||
|
gNB->if_inst->NR_Schedule_response = nr_schedule_response;
|
||||||
|
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
|
||||||
|
memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
|
||||||
|
memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO));
|
||||||
|
LOG_I(PHY,"Setting indication lists\n");
|
||||||
|
gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list;
|
||||||
|
gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list;
|
||||||
|
gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list;
|
||||||
|
gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
|
||||||
|
gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
|
||||||
|
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;
|
||||||
|
gNB->prach_energy_counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_I(PHY,"[nr-softmodem.c] gNB structure allocated\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void stop_gNB(int nb_inst) {
|
||||||
|
for (int inst=0; inst<nb_inst; inst++) {
|
||||||
|
LOG_I(PHY,"Killing gNB %d processing threads\n",inst);
|
||||||
|
kill_gNB_proc(inst);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2280
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,240 @@
|
|||||||
|
#ifndef NR_SOFTMODEM_H
|
||||||
|
#define NR_SOFTMODEM_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 "targets/ARCH/COMMON/common_lib.h"
|
||||||
|
#undef MALLOC
|
||||||
|
#include "assertions.h"
|
||||||
|
#include "msc.h"
|
||||||
|
#include "PHY/types.h"
|
||||||
|
|
||||||
|
#include "flexran_agent.h"
|
||||||
|
#include "PHY/defs_gNB.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_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_DISABLNBIOT "disable nb-iot, even if defined in config\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"
|
||||||
|
|
||||||
|
/***************************************************************************************************************************************/
|
||||||
|
/* 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
|
||||||
|
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#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}, \
|
||||||
|
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
|
||||||
|
{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \
|
||||||
|
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
|
||||||
|
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, 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:DEFAULT_DLF, TYPE_UINT, 0}, \
|
||||||
|
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
|
||||||
|
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
|
||||||
|
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
|
||||||
|
{"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 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 **)¶llel_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
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int *argc;
|
||||||
|
char **argv;
|
||||||
|
} scopeParms_t;
|
||||||
|
|
||||||
|
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_gNB;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "threads_t.h"
|
||||||
|
extern threads_t threads;
|
||||||
|
|
||||||
|
// In nr-gnb.c
|
||||||
|
extern void init_gNB(int single_thread_flag,int wait_for_sync);
|
||||||
|
extern void stop_gNB(int);
|
||||||
|
extern void kill_gNB_proc(int inst);
|
||||||
|
|
||||||
|
// In nr-ru.c
|
||||||
|
extern void init_RU(const char *);
|
||||||
|
extern void init_RU_proc(RU_t *ru);
|
||||||
|
extern void stop_RU(int nb_ru);
|
||||||
|
extern void kill_RU_proc(int inst);
|
||||||
|
extern void set_function_spec_param(RU_t *ru);
|
||||||
|
|
||||||
|
extern void reset_opp_meas(void);
|
||||||
|
extern void print_opp_meas(void);
|
||||||
|
|
||||||
|
extern void init_fep_thread(PHY_VARS_gNB *);
|
||||||
|
|
||||||
|
void init_gNB_afterRU(void);
|
||||||
|
|
||||||
|
extern int stop_L1L2(module_id_t gnb_id);
|
||||||
|
extern int restart_L1L2(module_id_t gnb_id);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,768 @@
|
|||||||
|
/*
|
||||||
|
* 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/system.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
|
||||||
|
|
||||||
|
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;
|
||||||
|
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));
|
||||||
|
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 {
|
||||||
|
UE_nr_rxtx_proc_t proc;
|
||||||
|
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;
|
||||||
|
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) {
|
||||||
|
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 {
|
||||||
|
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( &syncD->proc, 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.ul_config = NULL;
|
||||||
|
UE_mac->scheduled_response.tx_request = NULL;
|
||||||
|
UE_mac->scheduled_response.module_id = UE->Mod_id;
|
||||||
|
UE_mac->scheduled_response.CC_id = 0;
|
||||||
|
UE_mac->scheduled_response.frame = proc->frame_rx;
|
||||||
|
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);
|
||||||
|
#ifdef UE_SLOT_PARALLELISATION
|
||||||
|
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
|
||||||
|
#else
|
||||||
|
uint64_t a=rdtsc();
|
||||||
|
phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode);
|
||||||
|
LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500);
|
||||||
|
// 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 < UE->frame_parms.samples_per_frame/2 &&
|
||||||
|
UE->rx_offset > 0 ) {
|
||||||
|
//LOG_I(PHY,"!!!adjusting -1 samples!!!\n");
|
||||||
|
return -1 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( UE->rx_offset > UE->frame_parms.samples_per_frame/2 &&
|
||||||
|
UE->rx_offset < UE->frame_parms.samples_per_frame ) {
|
||||||
|
//LOG_I(PHY,"!!!adjusting +1 samples!!!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *UE_thread(void *arg) {
|
||||||
|
//this thread should be over the processing thread to keep in real time
|
||||||
|
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);
|
||||||
|
int nbSlotProcessing=0;
|
||||||
|
int thread_idx=0;
|
||||||
|
notifiedFIFO_t freeBlocks;
|
||||||
|
initNotifiedFIFO_nothreadSafe(&freeBlocks);
|
||||||
|
|
||||||
|
for (int i=0; i<RX_NB_TH+1; i++) // RX_NB_TH working + 1 we are making to be pushed
|
||||||
|
pushNotifiedFIFO_nothreadSafe(&freeBlocks,
|
||||||
|
newNotifiedFIFO_elt(sizeof(processingData_t), 0,&nf,UE_processing));
|
||||||
|
|
||||||
|
bool syncRunning=false;
|
||||||
|
const int nb_slot_frame = 10*UE->frame_parms.slots_per_subframe;
|
||||||
|
int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0;
|
||||||
|
|
||||||
|
while (!oai_exit) {
|
||||||
|
if (syncRunning) {
|
||||||
|
notifiedFIFO_elt_t *res=tryPullTpool(&nf, Tpool);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
syncRunning=false;
|
||||||
|
syncData_t *tmp=(syncData_t *)NotifiedFifoData(res);
|
||||||
|
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
|
||||||
|
decoded_frame_rx=(tmp->proc.decoded_frame_rx+trashed_frames) % MAX_FRAME_NUMBER;
|
||||||
|
delNotifiedFIFO_elt(res);
|
||||||
|
} else {
|
||||||
|
trashFrame(UE, ×tamp);
|
||||||
|
trashed_frames++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertFatal( !syncRunning, "At this point synchronisation can't be running\n");
|
||||||
|
|
||||||
|
if (!UE->is_synchronized) {
|
||||||
|
readFrame(UE, ×tamp);
|
||||||
|
notifiedFIFO_elt_t *Msg=newNotifiedFIFO_elt(sizeof(syncData_t),0,&nf,UE_synch);
|
||||||
|
syncData_t *syncMsg=(syncData_t *)NotifiedFifoData(Msg);
|
||||||
|
syncMsg->UE=UE;
|
||||||
|
memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
|
||||||
|
pushTpool(Tpool, Msg);
|
||||||
|
trashed_frames=0;
|
||||||
|
syncRunning=true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start_rx_stream==0) {
|
||||||
|
start_rx_stream=1;
|
||||||
|
syncInFrame(UE, ×tamp);
|
||||||
|
UE->rx_offset=0;
|
||||||
|
UE->time_sync_cell=0;
|
||||||
|
// read in first symbol
|
||||||
|
AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
|
||||||
|
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||||
|
×tamp,
|
||||||
|
(void **)UE->common_vars.rxdata,
|
||||||
|
UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
|
||||||
|
UE->frame_parms.nb_antennas_rx),"");
|
||||||
|
// we have the decoded frame index in the return of the synch process
|
||||||
|
// and we shifted above to the first slot of next frame
|
||||||
|
decoded_frame_rx++;
|
||||||
|
// we do ++ first in the regular processing, so it will be beging of frame;
|
||||||
|
absolute_slot=decoded_frame_rx*nb_slot_frame + nb_slot_frame -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
absolute_slot++;
|
||||||
|
// whatever means thread_idx
|
||||||
|
// Fix me: will be wrong when slot 1 is slow, as slot 2 finishes
|
||||||
|
// Slot 3 will overlap if RX_NB_TH is 2
|
||||||
|
// this is general failure in UE !!!
|
||||||
|
thread_idx = absolute_slot % RX_NB_TH;
|
||||||
|
int slot_nr = absolute_slot % nb_slot_frame;
|
||||||
|
notifiedFIFO_elt_t *msgToPush;
|
||||||
|
AssertFatal((msgToPush=pullNotifiedFIFO_nothreadSafe(&freeBlocks)) != NULL,"chained list failure");
|
||||||
|
processingData_t *curMsg=(processingData_t *)NotifiedFifoData(msgToPush);
|
||||||
|
curMsg->UE=UE;
|
||||||
|
// update thread index for received subframe
|
||||||
|
curMsg->proc.nr_tti_rx= slot_nr;
|
||||||
|
curMsg->UE->current_thread_id[slot_nr] = thread_idx;
|
||||||
|
curMsg->proc.subframe_rx=table_sf_slot[slot_nr];
|
||||||
|
curMsg->proc.nr_tti_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
|
||||||
|
curMsg->proc.subframe_tx=curMsg->proc.nr_tti_rx;
|
||||||
|
curMsg->proc.frame_rx = ( absolute_slot/nb_slot_frame ) % MAX_FRAME_NUMBER;
|
||||||
|
curMsg->proc.frame_tx = ( (absolute_slot + DURATION_RX_TO_TX) /nb_slot_frame ) % MAX_FRAME_NUMBER;
|
||||||
|
curMsg->proc.decoded_frame_rx=-1;
|
||||||
|
LOG_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][curMsg->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,
|
||||||
|
×tamp,
|
||||||
|
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,
|
||||||
|
×tamp,
|
||||||
|
(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
curMsg->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;
|
||||||
|
notifiedFIFO_elt_t *res;
|
||||||
|
|
||||||
|
while (nbSlotProcessing >= RX_NB_TH) {
|
||||||
|
if ( (res=tryPullTpool(&nf, Tpool)) != NULL ) {
|
||||||
|
nbSlotProcessing--;
|
||||||
|
processingData_t *tmp=(processingData_t *)res->msgData;
|
||||||
|
|
||||||
|
if (tmp->proc.decoded_frame_rx != -1)
|
||||||
|
decoded_frame_rx=tmp->proc.decoded_frame_rx;
|
||||||
|
|
||||||
|
pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( decoded_frame_rx != curMsg->proc.frame_rx &&
|
||||||
|
((decoded_frame_rx+1) % MAX_FRAME_NUMBER) != curMsg->proc.frame_rx )
|
||||||
|
LOG_D(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
|
||||||
|
decoded_frame_rx, curMsg->proc.frame_rx );
|
||||||
|
|
||||||
|
nbSlotProcessing++;
|
||||||
|
msgToPush->key=slot_nr;
|
||||||
|
pushTpool(Tpool, msgToPush);
|
||||||
|
|
||||||
|
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
|
||||||
|
// We must receive one message, that proves the slot processing is done
|
||||||
|
res=pullTpool(&nf, Tpool);
|
||||||
|
nbSlotProcessing--;
|
||||||
|
processingData_t *tmp=(processingData_t *)res->msgData;
|
||||||
|
|
||||||
|
if (tmp->proc.decoded_frame_rx != -1)
|
||||||
|
decoded_frame_rx=tmp->proc.decoded_frame_rx;
|
||||||
|
|
||||||
|
pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
|
||||||
|
}
|
||||||
|
} // 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];
|
||||||
|
|
||||||
|
for (inst=0; inst < nb_inst; inst++) {
|
||||||
|
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(inst);
|
||||||
|
mac_inst->if_module = UE->if_inst;
|
||||||
|
// Initial bandwidth part configuration -- full carrier bandwidth
|
||||||
|
mac_inst->initial_bwp_dl.bwp_id = 0;
|
||||||
|
mac_inst->initial_bwp_dl.location = 0;
|
||||||
|
mac_inst->initial_bwp_dl.scs = UE->frame_parms.subcarrier_spacing;
|
||||||
|
mac_inst->initial_bwp_dl.N_RB = UE->frame_parms.N_RB_DL;
|
||||||
|
mac_inst->initial_bwp_dl.cyclic_prefix = UE->frame_parms.Ncp;
|
||||||
|
mac_inst->initial_bwp_ul.bwp_id = 0;
|
||||||
|
mac_inst->initial_bwp_ul.location = 0;
|
||||||
|
mac_inst->initial_bwp_ul.scs = UE->frame_parms.subcarrier_spacing;
|
||||||
|
mac_inst->initial_bwp_ul.N_RB = UE->frame_parms.N_RB_UL;
|
||||||
|
mac_inst->initial_bwp_ul.cyclic_prefix = UE->frame_parms.Ncp;
|
||||||
|
LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
|
||||||
|
threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("UE threads created by %ld\n", gettid());
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,775 @@
|
|||||||
|
/*
|
||||||
|
* 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 "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_phy_scope_nrue *form_nrue[NUMBER_OF_UE_MAX];
|
||||||
|
//FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||||
|
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
|
||||||
|
char title[255];
|
||||||
|
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];
|
||||||
|
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) {
|
||||||
|
sleep(5);
|
||||||
|
|
||||||
|
while (!oai_exit) {
|
||||||
|
phy_scope_nrUE(form_nrue[0],
|
||||||
|
PHY_vars_UE_g[0][0],
|
||||||
|
0,0,1);
|
||||||
|
usleep(100*1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_exit((void *)arg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void init_scope(void) {
|
||||||
|
#ifdef XFORMS
|
||||||
|
int fl_argc=1;
|
||||||
|
|
||||||
|
if (do_forms==1) {
|
||||||
|
char *name="5G-UE-scope";
|
||||||
|
fl_initialize (&fl_argc, &name, NULL, 0, 0);
|
||||||
|
int UE_id = 0;
|
||||||
|
form_nrue[UE_id] = create_phy_scope_nrue();
|
||||||
|
sprintf (title, "NR DL SCOPE UE");
|
||||||
|
fl_show_form (form_nrue[UE_id]->phy_scope_nrue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
|
||||||
|
threadCreate(&forms_thread, scope_thread, NULL, "scope", -1, OAI_PRIORITY_RT_LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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);
|
||||||
|
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;
|
||||||
|
// 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";
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
configure_linux();
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include "rt_wrapper.h"
|
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -22,22 +21,23 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include "rt_wrapper.h"
|
|
||||||
#include "../../ARCH/COMMON/common_lib.h"
|
#include "../../ARCH/COMMON/common_lib.h"
|
||||||
#undef MALLOC
|
#undef MALLOC
|
||||||
#include "assertions.h"
|
#include "assertions.h"
|
||||||
#include "msc.h"
|
|
||||||
#include "PHY/types.h"
|
#include "PHY/types.h"
|
||||||
#include "PHY/defs_nr_UE.h"
|
#include "PHY/defs_nr_UE.h"
|
||||||
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
||||||
|
#include <threadPool/thread-pool.h>
|
||||||
|
#include <openair2/LAYER2/NR_MAC_gNB/mac_proto.h>
|
||||||
|
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
#if defined(ENABLE_ITTI)
|
||||||
#if defined(ENABLE_USE_MME)
|
#if defined(ENABLE_USE_MME)
|
||||||
#include "s1ap_eNB.h"
|
#include "s1ap_eNB.h"
|
||||||
#ifdef PDCP_USE_NETLINK
|
#ifdef PDCP_USE_NETLINK
|
||||||
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\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_UENANTT "set UE number of tx antennas\n"
|
||||||
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\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_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_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_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_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
|
||||||
@@ -105,15 +105,15 @@
|
|||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
#define CMDLINE_UEMODEPARAMS_DESC { \
|
#define CMDLINE_UEMODEPARAMS_DESC { \
|
||||||
{"calib-ue-rx", CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
{"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-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}, \
|
{"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}, \
|
{"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}, \
|
{"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}, \
|
{"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}, \
|
{"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}, \
|
{"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
|
||||||
}
|
}
|
||||||
#define CMDLINE_CALIBUERX_IDX 0
|
#define CMDLINE_CALIBUERX_IDX 0
|
||||||
#define CMDLINE_CALIBUERXMED_IDX 1
|
#define CMDLINE_CALIBUERXMED_IDX 1
|
||||||
#define CMDLINE_CALIBUERXBYP_IDX 2
|
#define CMDLINE_CALIBUERXBYP_IDX 2
|
||||||
@@ -130,19 +130,19 @@
|
|||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
#define CMDLINE_UEPARAMS_DESC { \
|
#define CMDLINE_UEPARAMS_DESC { \
|
||||||
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
|
{"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-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-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-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-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-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-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}, \
|
{"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}, \
|
{"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}, \
|
{"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-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} \
|
{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFAULT_DLF 2680000000
|
#define DEFAULT_DLF 2680000000
|
||||||
|
|
||||||
@@ -151,43 +151,31 @@
|
|||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
#define CMDLINE_PARAMS_DESC { \
|
#define CMDLINE_PARAMS_DESC { \
|
||||||
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \
|
{"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}, \
|
{"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}, \
|
{"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}, \
|
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \
|
||||||
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
|
{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 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}, \
|
||||||
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
|
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
|
||||||
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
|
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
|
||||||
{"threadoffset", NULL, 0, iptr:&(threads_offset), defintval:0, TYPE_INT, 0}, \
|
{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \
|
||||||
{"threadMain", NULL, 0, iptr:&(threads.main), defintval:-1, TYPE_INT, 0}, \
|
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
|
||||||
{"threadSync", NULL, 0, iptr:&(threads.sync), defintval:-1, TYPE_INT, 0}, \
|
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, iptr:&do_forms, defintval:0, TYPE_INT, 0}, \
|
||||||
{"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:-1, TYPE_INT, 0}, \
|
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \
|
||||||
{"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:-1, TYPE_INT, 0}, \
|
{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
|
||||||
{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:-1, TYPE_INT, 0}, \
|
{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
|
||||||
{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:-1, TYPE_INT, 0}, \
|
{"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \
|
||||||
{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:-1, TYPE_INT, 0}, \
|
{"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \
|
||||||
{"threadSlot1ProcThree", NULL, 0, iptr:&(threads.slot1_proc_three), defintval:-1, TYPE_INT, 0}, \
|
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
|
||||||
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
|
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
|
||||||
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
|
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
|
||||||
{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \
|
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
|
||||||
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
|
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
|
||||||
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, iptr:&do_forms, defintval:0, TYPE_INT, 0}, \
|
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||||
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \
|
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||||
{"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \
|
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, 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 **)¶llel_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_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_LOGL "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n"
|
||||||
@@ -198,11 +186,11 @@
|
|||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
#define CMDLINE_LOGPARAMS_DESC { \
|
#define CMDLINE_LOGPARAMS_DESC { \
|
||||||
{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
|
{"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_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
|
||||||
{"G" , CONFIG_HLP_LOGV, 0, uptr:&glog_verbosity, defintval:0, TYPE_UINT16, 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}, \
|
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
|
||||||
}
|
}
|
||||||
#define CMDLINE_ONLINELOG_IDX 0
|
#define CMDLINE_ONLINELOG_IDX 0
|
||||||
#define CMDLINE_GLOGLEVEL_IDX 1
|
#define CMDLINE_GLOGLEVEL_IDX 1
|
||||||
#define CMDLINE_GLOGVERBO_IDX 2
|
#define CMDLINE_GLOGVERBO_IDX 2
|
||||||
@@ -240,19 +228,19 @@ extern int transmission_mode;
|
|||||||
extern double cpuf;
|
extern double cpuf;
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
#if defined(ENABLE_ITTI)
|
||||||
extern volatile int start_eNB;
|
extern volatile int start_eNB;
|
||||||
extern volatile int start_UE;
|
extern volatile int start_UE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "threads_t.h"
|
|
||||||
extern threads_t threads;
|
|
||||||
|
|
||||||
// In nr-ue.c
|
// In nr-ue.c
|
||||||
extern int setup_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
|
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 fill_ue_band_info(void);
|
||||||
extern void init_UE(int);
|
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 reset_opp_meas(void);
|
||||||
extern void print_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
|
#endif
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
#ifndef OPENAIRINTERFACE5G_LIMITS_H_
|
||||||
|
#define OPENAIRINTERFACE5G_LIMITS_H_
|
||||||
|
|
||||||
|
#if 1 /*defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)*/
|
||||||
|
#define NUMBER_OF_eNB_MAX 1
|
||||||
|
#define NUMBER_OF_gNB_MAX 1
|
||||||
|
#define NUMBER_OF_RU_MAX 2
|
||||||
|
#define NUMBER_OF_NR_RU_MAX 2
|
||||||
|
#ifndef PHYSIM
|
||||||
|
#ifndef UE_EXPANSION
|
||||||
|
#define NUMBER_OF_UE_MAX 4
|
||||||
|
#define NUMBER_OF_NR_UE_MAX 4
|
||||||
|
#define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||||
|
#define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||||
|
#else
|
||||||
|
#define NUMBER_OF_UE_MAX 256
|
||||||
|
#define NUMBER_OF_NR_UE_MAX 256
|
||||||
|
#define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||||
|
#define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define NUMBER_OF_UE_MAX 1
|
||||||
|
#define NUMBER_OF_NR_UE_MAX 1
|
||||||
|
#define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||||
|
#define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define NUMBER_OF_eNB_MAX 7
|
||||||
|
#define NUMBER_OF_gNB_MAX 7
|
||||||
|
#define NUMBER_OF_RU_MAX 32
|
||||||
|
#define NUMBER_OF_NR_RU_MAX 32
|
||||||
|
#ifndef UE_EXPANSION
|
||||||
|
#define NUMBER_OF_UE_MAX 20
|
||||||
|
#define NUMBER_OF_NR_UE_MAX 20
|
||||||
|
#define NUMBER_OF_CONNECTED_eNB_MAX 3
|
||||||
|
#define NUMBER_OF_CONNECTED_gNB_MAX 3
|
||||||
|
#else
|
||||||
|
#define NUMBER_OF_UE_MAX 256
|
||||||
|
#define NUMBER_OF_NR_UE_MAX 256
|
||||||
|
#define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||||
|
#define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||||
|
#endif
|
||||||
|
#if defined(STANDALONE) && STANDALONE==1
|
||||||
|
#undef NUMBER_OF_eNB_MAX
|
||||||
|
#undef NUMBER_OF_gNB_MAX
|
||||||
|
|
||||||
|
#undef NUMBER_OF_UE_MAX
|
||||||
|
#undef NUMBER_OF_NR_UE_MAX
|
||||||
|
|
||||||
|
#undef NUMBER_OF_RU_MAX
|
||||||
|
#undef NUMBER_OF_NR_RU_MAX
|
||||||
|
|
||||||
|
#define NUMBER_OF_eNB_MAX 3
|
||||||
|
#define NUMBER_OF_gNB_MAX 3
|
||||||
|
|
||||||
|
#define NUMBER_OF_UE_MAX 3
|
||||||
|
#define NUMBER_OF_NR_UE_MAX 3
|
||||||
|
|
||||||
|
#define NUMBER_OF_RU_MAX 3
|
||||||
|
#define NUMBER_OF_NR_RU_MAX 3
|
||||||
|
#endif
|
||||||
|
#if defined(LARGE_SCALE) && LARGE_SCALE
|
||||||
|
#undef NUMBER_OF_eNB_MAX
|
||||||
|
#undef NUMBER_OF_gNB_MAX
|
||||||
|
|
||||||
|
#undef NUMBER_OF_UE_MAX
|
||||||
|
#undef NUMBER_OF_NR_UE_MAX
|
||||||
|
|
||||||
|
#undef NUMBER_OF_CONNECTED_eNB_MAX
|
||||||
|
#undef NUMBER_OF_CONNECTED_gNB_MAX
|
||||||
|
|
||||||
|
#undef NUMBER_OF_RU_MAX
|
||||||
|
#undef NUMBER_OF_NR_RU_MAX
|
||||||
|
|
||||||
|
#define NUMBER_OF_eNB_MAX 2
|
||||||
|
#define NUMBER_OF_gNB_MAX 2
|
||||||
|
|
||||||
|
#define NUMBER_OF_UE_MAX 120
|
||||||
|
#define NUMBER_OF_NR_UE_MAX 120
|
||||||
|
|
||||||
|
#define NUMBER_OF_RU_MAX 16
|
||||||
|
#define NUMBER_OF_NR_RU_MAX 16
|
||||||
|
|
||||||
|
#define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory
|
||||||
|
#define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OPENAIRINTERFACE5G_LIMITS_H_ */
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Header file generated by fdesign on Thu Aug 28 12:13:51 2014 */
|
||||||
|
|
||||||
|
#ifndef FD_stats_form_h_
|
||||||
|
#define FD_stats_form_h_
|
||||||
|
|
||||||
|
#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 );
|
||||||
|
|
||||||
|
#endif /* FD_stats_form_h_ */
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef _THREADS_T_H_
|
||||||
|
#define _THREADS_T_H_
|
||||||
|
|
||||||
|
typedef struct threads_s {
|
||||||
|
int main;
|
||||||
|
int sync;
|
||||||
|
int one;
|
||||||
|
int two;
|
||||||
|
int three;
|
||||||
|
int slot1_proc_one;
|
||||||
|
int slot1_proc_two;
|
||||||
|
int slot1_proc_three;
|
||||||
|
//int dlsch_td_one;
|
||||||
|
//int dlsch_td_two;
|
||||||
|
//int dlsch_td_three;
|
||||||
|
//int dlsch_td1_one;
|
||||||
|
//int dlsch_td1_two;
|
||||||
|
//int dlsch_td1_three;
|
||||||
|
} threads_t;
|
||||||
|
|
||||||
|
#endif /* _THREADS_T_H_ */
|
||||||
@@ -31,12 +31,12 @@ typedef struct {
|
|||||||
/*typedef struct {
|
/*typedef struct {
|
||||||
nfapi_tl_t tl;
|
nfapi_tl_t tl;
|
||||||
int64_t value;
|
int64_t value;
|
||||||
} nfapi_int64_tlv_t;
|
} nfapi_int64_tlv_t;*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nfapi_tl_t tl;
|
nfapi_tl_t tl;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
} nfapi_uint64_tlv_t;*/
|
} nfapi_uint64_tlv_t;
|
||||||
|
|
||||||
// nFAPI enums
|
// nFAPI enums
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -75,7 +75,7 @@ typedef struct
|
|||||||
|
|
||||||
// These TLVs are used by the VNF to configure the RF in the PNF
|
// These TLVs are used by the VNF to configure the RF in the PNF
|
||||||
// nfapi_uint16_tlv_t max_transmit_power;
|
// nfapi_uint16_tlv_t max_transmit_power;
|
||||||
nfapi_uint16_tlv_t nrarfcn;
|
nfapi_uint32_tlv_t nrarfcn;
|
||||||
|
|
||||||
// nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands;
|
// nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands;
|
||||||
// nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands;
|
// nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands;
|
||||||
@@ -178,8 +178,8 @@ typedef struct {
|
|||||||
nfapi_uint16_tlv_t physical_cell_id;
|
nfapi_uint16_tlv_t physical_cell_id;
|
||||||
nfapi_uint16_tlv_t half_frame_index;
|
nfapi_uint16_tlv_t half_frame_index;
|
||||||
nfapi_uint16_tlv_t ssb_subcarrier_offset;
|
nfapi_uint16_tlv_t ssb_subcarrier_offset;
|
||||||
nfapi_uint16_tlv_t ssb_sib1_position_in_burst;
|
nfapi_uint16_tlv_t ssb_sib1_position_in_burst; // in sib1
|
||||||
nfapi_uint16_tlv_t ssb_scg_position_in_burst;
|
nfapi_uint64_tlv_t ssb_scg_position_in_burst; // in servingcellconfigcommon
|
||||||
nfapi_uint16_tlv_t ssb_periodicity;
|
nfapi_uint16_tlv_t ssb_periodicity;
|
||||||
nfapi_uint16_tlv_t ss_pbch_block_power;
|
nfapi_uint16_tlv_t ss_pbch_block_power;
|
||||||
nfapi_uint16_tlv_t n_ssb_crb;
|
nfapi_uint16_tlv_t n_ssb_crb;
|
||||||
@@ -673,4 +673,45 @@ typedef struct {
|
|||||||
nfapi_vendor_extension_tlv_t vendor_extension;
|
nfapi_vendor_extension_tlv_t vendor_extension;
|
||||||
} nfapi_nr_dl_config_request_t;
|
} 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
|
#endif
|
||||||
|
|||||||
@@ -11,116 +11,137 @@
|
|||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
|
#include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
|
||||||
#include "PHY/CODING/coding_defs.h"
|
#include "PHY/CODING/coding_defs.h"
|
||||||
#include "SIMULATION/TOOLS/sim.h"
|
#include "SIMULATION/TOOLS/sim.h"
|
||||||
|
//#include "PHY/NR_TRANSPORT/nr_transport.h"
|
||||||
|
//#include "common/utils/LOG/log.h"
|
||||||
|
|
||||||
//#define DEBUG_DCI_POLAR_PARAMS
|
//#define DEBUG_DCI_POLAR_PARAMS
|
||||||
//#define DEBUG_POLAR_TIMING
|
//#define DEBUG_POLAR_TIMING
|
||||||
//#define DEBUG_CRC
|
//#define DEBUG_POLARTEST
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
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.)
|
//Default simulation values (Aim for iterations = 1000000.)
|
||||||
|
int decoder_int16=0;
|
||||||
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
|
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
|
||||||
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
|
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
|
||||||
double SNR, SNR_lin;
|
double SNR, SNR_lin;
|
||||||
int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks).
|
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.
|
uint32_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error.
|
||||||
uint16_t testLength = 0, coderLength = 0, blockErrorCumulative=0, bitErrorCumulative=0;
|
uint16_t testLength = NR_POLAR_PBCH_PAYLOAD_BITS, coderLength = NR_POLAR_PBCH_E;
|
||||||
|
uint16_t blockErrorCumulative=0, bitErrorCumulative=0;
|
||||||
double timeEncoderCumulative = 0, timeDecoderCumulative = 0;
|
double timeEncoderCumulative = 0, timeDecoderCumulative = 0;
|
||||||
uint8_t aggregation_level = 8, decoderListSize = 8, pathMetricAppr = 0;
|
uint8_t aggregation_level = 8, decoderListSize = 8, logFlag = 0;
|
||||||
|
uint16_t rnti=0;
|
||||||
|
|
||||||
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:hqg")) != -1)
|
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:p:hqgFL:k:")) != -1)
|
||||||
switch (arguments) {
|
switch (arguments) {
|
||||||
case 's':
|
case 's':
|
||||||
SNRstart = atof(optarg);
|
SNRstart = atof(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
SNRinc = atof(optarg);
|
SNRinc = atof(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
SNRstop = atof(optarg);
|
SNRstop = atof(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
polarMessageType = atoi(optarg);
|
polarMessageType = atoi(optarg);
|
||||||
break;
|
if (polarMessageType!=0 && polarMessageType!=1 && polarMessageType!=2)
|
||||||
|
printf("Illegal polar message type %d (should be 0,1 or 2)\n", polarMessageType);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
iterations = atoi(optarg);
|
iterations = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
decoderListSize = (uint8_t) atoi(optarg);
|
decoderListSize = (uint8_t) atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'q':
|
||||||
pathMetricAppr = (uint8_t) atoi(optarg);
|
decoder_int16 = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'q':
|
case 'g':
|
||||||
decoder_int16 = 1;
|
iterations = 1;
|
||||||
break;
|
SNRstart = -6.0;
|
||||||
|
SNRstop = -6.0;
|
||||||
|
decoder_int16 = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'g':
|
case 'F':
|
||||||
iterations = 1;
|
logFlag = 1;
|
||||||
SNRstart = -6.0;
|
break;
|
||||||
SNRstop = -6.0;
|
|
||||||
decoder_int16 = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'h':
|
case 'L':
|
||||||
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=PBCH|1=DCI|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n");
|
aggregation_level=atoi(optarg);
|
||||||
exit(-1);
|
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);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
case 'k':
|
||||||
perror("[polartest.c] Problem at argument parsing with getopt");
|
testLength=atoi(optarg);
|
||||||
exit(-1);
|
if (testLength < 12 || testLength > 60) {
|
||||||
|
printf("Illegal packet bitlength %d \n",testLength);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
printf("./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n"
|
||||||
|
"-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n"
|
||||||
|
"-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n");
|
||||||
|
exit(-1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
perror("[polartest.c] Problem at argument parsing with getopt");
|
||||||
|
exit(-1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
|
||||||
|
time_stats_t timeEncoder,timeDecoder;
|
||||||
|
opp_enabled=1;
|
||||||
|
cpu_freq_GHz = get_cpu_freq_GHz();
|
||||||
|
reset_meas(&timeEncoder);
|
||||||
|
reset_meas(&timeDecoder);
|
||||||
|
randominit(0);
|
||||||
|
crcTableInit();
|
||||||
|
|
||||||
if (polarMessageType == 0) { //PBCH
|
if (polarMessageType == 0) { //PBCH
|
||||||
testLength = 64;//NR_POLAR_PBCH_PAYLOAD_BITS;
|
aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
|
||||||
coderLength = NR_POLAR_PBCH_E;
|
|
||||||
aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
|
|
||||||
} else if (polarMessageType == 1) { //DCI
|
} else if (polarMessageType == 1) { //DCI
|
||||||
//testLength = nr_get_dci_size(params_rel15->dci_format, params_rel15->rnti_type, &fp->initial_bwp_dl, cfg);
|
coderLength = 108*aggregation_level;
|
||||||
testLength = 41; //20;
|
|
||||||
coderLength = 108*8; //to be changed by aggregate level function.
|
|
||||||
} else if (polarMessageType == -1) { //UCI
|
} else if (polarMessageType == -1) { //UCI
|
||||||
//testLength = ;
|
printf("UCI testing not supported yet\n");
|
||||||
//coderLength = ;
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Logging
|
//Logging
|
||||||
time_t currentTime;
|
time_t currentTime;
|
||||||
time (¤tTime);
|
|
||||||
char fileName[512], currentTimeInfo[25];
|
char fileName[512], currentTimeInfo[25];
|
||||||
char folderName[] = ".";
|
char folderName[] = ".";
|
||||||
/*
|
FILE *logFile;
|
||||||
folderName=getenv("HOME");
|
/*folderName=getenv("HOME");
|
||||||
strcat(folderName,"/Desktop/polartestResults");
|
strcat(folderName,"/Desktop/polartestResults");*/
|
||||||
*/
|
|
||||||
|
if (logFlag){
|
||||||
|
time (¤tTime);
|
||||||
#ifdef DEBUG_POLAR_TIMING
|
#ifdef DEBUG_POLAR_TIMING
|
||||||
sprintf(fileName,"%s/TIMING_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
|
sprintf(fileName,"%s/TIMING_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations);
|
||||||
#else
|
#else
|
||||||
sprintf(fileName,"%s/_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
|
sprintf(fileName,"%s/_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations);
|
||||||
#endif
|
#endif
|
||||||
strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(¤tTime));
|
strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(¤tTime));
|
||||||
strcat(fileName,currentTimeInfo);
|
strcat(fileName,currentTimeInfo);
|
||||||
//Create "~/Desktop/polartestResults" folder if it doesn't already exist.
|
//Create "~/Desktop/polartestResults" folder if it doesn't already exist.
|
||||||
/*
|
/*struct stat folder = {0};
|
||||||
struct stat folder = {0};
|
if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);*/
|
||||||
if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);
|
|
||||||
*/
|
|
||||||
FILE *logFile;
|
|
||||||
logFile = fopen(fileName, "w");
|
logFile = fopen(fileName, "w");
|
||||||
|
|
||||||
if (logFile==NULL) {
|
if (logFile==NULL) {
|
||||||
@@ -129,11 +150,12 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_POLAR_TIMING
|
#ifdef DEBUG_POLAR_TIMING
|
||||||
fprintf(logFile,
|
fprintf(logFile,",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n");
|
||||||
",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n");
|
|
||||||
#else
|
#else
|
||||||
fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
|
fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t testArrayLength = ceil(testLength / 32.0);
|
uint8_t testArrayLength = ceil(testLength / 32.0);
|
||||||
uint8_t coderArrayLength = ceil(coderLength / 32.0);
|
uint8_t coderArrayLength = ceil(coderLength / 32.0);
|
||||||
uint32_t testInput[testArrayLength]; //generate randomly
|
uint32_t testInput[testArrayLength]; //generate randomly
|
||||||
@@ -146,253 +168,156 @@ int main(int argc, char *argv[]) {
|
|||||||
double modulatedInput[coderLength]; //channel input
|
double modulatedInput[coderLength]; //channel input
|
||||||
double channelOutput[coderLength]; //add noise
|
double channelOutput[coderLength]; //add noise
|
||||||
int16_t channelOutput_int16[coderLength];
|
int16_t channelOutput_int16[coderLength];
|
||||||
|
|
||||||
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level);
|
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level);
|
||||||
|
|
||||||
#ifdef DEBUG_DCI_POLAR_PARAMS
|
#ifdef DEBUG_DCI_POLAR_PARAMS
|
||||||
uint32_t dci_pdu[4];
|
uint32_t dci_pdu[4];
|
||||||
memset(dci_pdu,0,sizeof(uint32_t)*4);
|
memset(dci_pdu,0,sizeof(uint32_t)*4);
|
||||||
dci_pdu[0]=0x01189400;
|
dci_pdu[0]=0x01189400;
|
||||||
printf("dci_pdu: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
|
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]);
|
||||||
dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]);
|
uint16_t size=41;
|
||||||
|
rnti=3;
|
||||||
|
aggregation_level=8;
|
||||||
uint32_t encoder_output[54];
|
uint32_t encoder_output[54];
|
||||||
memset(encoder_output,0,sizeof(uint32_t)*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);
|
t_nrPolar_params *currentPtrDCI=nr_polar_params(1, size, aggregation_level);
|
||||||
polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti);
|
|
||||||
|
|
||||||
for (int i=0; i<54; i++)
|
polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti);
|
||||||
printf("encoder_output: [%2d]->0x%08x \n",i, encoder_output[i]);
|
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);
|
uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength);
|
||||||
double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength);
|
double *modulated_input = malloc (sizeof(double) * currentPtrDCI->encoderLength);
|
||||||
uint32_t dci_estimation[4];
|
double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength);
|
||||||
memset(dci_estimation,0,sizeof(uint32_t)*4);
|
uint32_t dci_est[4];
|
||||||
printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
|
memset(dci_est,0,sizeof(uint32_t)*4);
|
||||||
dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]);
|
printf("dci_est: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_est[0], dci_est[1], dci_est[2], dci_est[3]);
|
||||||
nr_bit2byte_uint32_8_t(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte);
|
nr_bit2byte_uint32_8(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte);
|
||||||
printf("[polartest] 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++) printf("%d-", encoder_outputByte[i]);
|
SNR_lin = pow(10, 0/10); //SNR = 0 dB
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
for(int i=0; i<currentPtrDCI->encoderLength; i++) {
|
for(int i=0; i<currentPtrDCI->encoderLength; i++) {
|
||||||
if (encoder_outputByte[i] == 0) {
|
if (encoder_outputByte[i] == 0)
|
||||||
channel_output[i]=1/sqrt(2);
|
modulated_input[i]=1/sqrt(2);
|
||||||
} else {
|
else
|
||||||
channel_output[i]=(-1)/sqrt(2);
|
modulated_input[i]=(-1)/sqrt(2);
|
||||||
}
|
channel_output[i] = modulated_input[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
|
||||||
}
|
}
|
||||||
|
decoderState = polar_decoder_dci(channel_output, dci_est, currentPtrDCI, NR_POLAR_DECODER_LISTSIZE, rnti);
|
||||||
decoderState = polar_decoder_dci(channel_output,
|
printf("dci_est: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_est[0], dci_est[1], dci_est[2], dci_est[3]);
|
||||||
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(encoder_outputByte);
|
||||||
free(channel_output);
|
free(channel_output);
|
||||||
|
free(modulated_input);
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#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_t(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
|
|
||||||
#ifdef DEBUG_POLAR_TIMING
|
|
||||||
|
|
||||||
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
|
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
|
||||||
SNR_lin = pow(10, SNR / 10);
|
printf("SNR %f\n",SNR);
|
||||||
|
SNR_lin = pow(10, SNR/10);
|
||||||
|
|
||||||
for (itr = 1; itr <= iterations; itr++) {
|
for (itr = 1; itr <= iterations; itr++) {
|
||||||
for (int j=0; j<ceil(testLength / 32.0); j++) {
|
//Generate random values for all the bits of "testInput", not just as much as "currentPtr->payloadBits".
|
||||||
for(int i=0; i<32; i++) {
|
for (int i = 0; i < testArrayLength; i++) {
|
||||||
testInput[j] |= ( ((uint32_t) (rand()%2)) &1);
|
for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) {
|
||||||
testInput[j]<<=1;
|
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
|
||||||
}
|
testInput[i]<<=1;
|
||||||
}
|
}
|
||||||
|
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
|
||||||
|
}
|
||||||
|
|
||||||
printf("testInput: [0]->0x%08x \n", testInput[0]);
|
#ifdef DEBUG_POLARTEST
|
||||||
polar_encoder_timing(testInput, encoderOutput, currentPtr, cpu_freq_GHz, logFile);
|
//testInput[0] = 0x360f8a5c;
|
||||||
}
|
printf("testInput: [0]->0x%08x\n", testInput[0]);
|
||||||
}
|
|
||||||
|
|
||||||
fclose(logFile);
|
|
||||||
free(testInput);
|
|
||||||
free(encoderOutput);
|
|
||||||
free(modulatedInput);
|
|
||||||
free(channelOutput);
|
|
||||||
free(estimatedOutput);
|
|
||||||
return (0);
|
|
||||||
#endif
|
#endif
|
||||||
// We assume no a priori knowledge available about the payload.
|
int len_mod64=currentPtr->payloadBits&63;
|
||||||
double aPrioriArray[currentPtr->payloadBits];
|
((uint64_t *)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<<len_mod64)-1);
|
||||||
|
|
||||||
for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN;
|
start_meas(&timeEncoder);
|
||||||
|
if (decoder_int16==1) {
|
||||||
|
polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, currentPtr);
|
||||||
|
//polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0, currentPtr);
|
||||||
|
} else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
|
||||||
|
if (polarMessageType == 0)
|
||||||
|
polar_encoder(testInput, encoderOutput, currentPtr);
|
||||||
|
else if (polarMessageType == 1)
|
||||||
|
polar_encoder_dci(testInput, encoderOutput, currentPtr, rnti);
|
||||||
|
}
|
||||||
|
stop_meas(&timeEncoder);
|
||||||
|
|
||||||
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
|
#ifdef DEBUG_POLARTEST
|
||||||
printf("SNR %f\n",SNR);
|
printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]);
|
||||||
SNR_lin = pow(10, SNR/10);
|
//for (int i=1;i<coderArrayLength;i++) printf("encoderOutput: [i]->0x%08x\n", i, encoderOutput[1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*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)
|
|
||||||
polar_encoder(testInput, encoderOutput, currentPtr);
|
|
||||||
else
|
|
||||||
polar_encoder_fast((uint64_t *)testInput, encoderOutput,0, 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]);*/
|
|
||||||
//Bit-to-byte:
|
//Bit-to-byte:
|
||||||
nr_bit2byte_uint32_8_t(encoderOutput, coderLength, encoderOutputByte);
|
nr_bit2byte_uint32_8(encoderOutput, coderLength, encoderOutputByte);
|
||||||
|
|
||||||
//BPSK modulation
|
//BPSK modulation
|
||||||
for(int i=0; i<coderLength; i++) {
|
for(int i=0; i<coderLength; i++) {
|
||||||
if (encoderOutputByte[i] == 0)
|
if (encoderOutputByte[i] == 0)
|
||||||
modulatedInput[i]=1/sqrt(2);
|
modulatedInput[i]=1/sqrt(2);
|
||||||
else
|
else
|
||||||
modulatedInput[i]=(-1)/sqrt(2);
|
modulatedInput[i]=(-1)/sqrt(2);
|
||||||
|
|
||||||
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
|
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
|
||||||
|
|
||||||
if (decoder_int16==1) {
|
if (decoder_int16==1) {
|
||||||
if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
|
if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
|
||||||
else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
|
else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
|
||||||
else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
|
else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
start_meas(&timeDecoder);
|
start_meas(&timeDecoder);
|
||||||
|
|
||||||
/*decoderState = polar_decoder(channelOutput,
|
if (decoder_int16==1) {
|
||||||
estimatedOutput,
|
decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, currentPtr);
|
||||||
currentPtr,
|
} else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
|
||||||
NR_POLAR_DECODER_LISTSIZE,
|
if (polarMessageType == 0) {
|
||||||
aPrioriArray,
|
decoderState = polar_decoder(channelOutput,
|
||||||
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION);*/
|
estimatedOutput,
|
||||||
if (decoder_int16==0)
|
currentPtr,
|
||||||
decoderState = polar_decoder_aPriori(channelOutput,
|
decoderListSize);
|
||||||
estimatedOutput,
|
} else if (polarMessageType == 1) {
|
||||||
currentPtr,
|
decoderState = polar_decoder_dci(channelOutput,
|
||||||
NR_POLAR_DECODER_LISTSIZE,
|
estimatedOutput,
|
||||||
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
|
currentPtr,
|
||||||
aPrioriArray);
|
decoderListSize,
|
||||||
else
|
rnti);
|
||||||
decoderState = polar_decoder_int16(channelOutput_int16,
|
}
|
||||||
(uint64_t *)estimatedOutput,
|
}
|
||||||
currentPtr);
|
|
||||||
|
|
||||||
stop_meas(&timeDecoder);
|
stop_meas(&timeDecoder);
|
||||||
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
|
|
||||||
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/
|
#ifdef DEBUG_POLARTEST
|
||||||
|
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);
|
||||||
|
#endif
|
||||||
|
|
||||||
//calculate errors
|
//calculate errors
|
||||||
if (decoderState!=0) {
|
if (decoderState!=0) {
|
||||||
blockErrorState=-1;
|
blockErrorState=-1;
|
||||||
nBitError=-1;
|
nBitError=-1;
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < currentPtr->payloadBits; j++) {
|
for (int i = 0; i < (testArrayLength-1); i++) {
|
||||||
if (((estimatedOutput[0]>>j) & 1) != ((testInput[0]>>j) & 1)) nBitError++;
|
for (int j = 0; j < 32; j++) {
|
||||||
|
if ( ((estimatedOutput[i]>>j) & 1) != ((testInput[i]>>j) & 1) )
|
||||||
// printf("bit %d: %d => %d\n",j,(testInput[0]>>j)&1,(estimatedOutput[0]>>j)&1);
|
nBitError++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (nBitError>0) {
|
for (int j = 0; j < testLength - ((testArrayLength-1) * 32); j++)
|
||||||
blockErrorState=1;
|
if ( ((estimatedOutput[(testArrayLength-1)]>>j) & 1) != ((testInput[(testArrayLength-1)]>>j) & 1) )
|
||||||
// printf("Error: Input %x, Output %x\n",testInput[0],estimatedOutput[0]);
|
nBitError++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (nBitError>0) blockErrorState=1;
|
||||||
|
#ifdef DEBUG_POLARTEST
|
||||||
|
for (int i = 0; i < testArrayLength; i++)
|
||||||
|
printf("[polartest/decoderState=%d] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n",decoderState, i, testInput[i], i, estimatedOutput[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
//Iteration times are in microseconds.
|
//Iteration times are in microseconds.
|
||||||
timeEncoderCumulative+=(timeEncoder.diff/(cpu_freq_GHz*1000.0));
|
timeEncoderCumulative+=(timeEncoder.diff/(cpu_freq_GHz*1000.0));
|
||||||
timeDecoderCumulative+=(timeDecoder.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,
|
if (logFlag) 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)));
|
||||||
(timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0)));
|
|
||||||
|
|
||||||
if (nBitError<0) {
|
if (nBitError<0) {
|
||||||
blockErrorCumulative++;
|
blockErrorCumulative++;
|
||||||
@@ -405,17 +330,19 @@ int main(int argc, char *argv[]) {
|
|||||||
decoderState=0;
|
decoderState=0;
|
||||||
nBitError=0;
|
nBitError=0;
|
||||||
blockErrorState=0;
|
blockErrorState=0;
|
||||||
|
memset(testInput,0,sizeof(uint32_t) * testArrayLength);
|
||||||
|
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
|
||||||
|
memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Calculate error statistics for the SNR.
|
//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",
|
printf("[ListSize=%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),
|
decoderListSize, SNR, ((double)blockErrorCumulative/iterations),
|
||||||
((double)bitErrorCumulative / (iterations*testLength)),
|
((double)bitErrorCumulative / (iterations*testLength)),
|
||||||
(double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0));
|
(double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0));
|
||||||
//(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);
|
//(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);
|
||||||
|
|
||||||
if (blockErrorCumulative==0 && bitErrorCumulative==0)
|
if (blockErrorCumulative==0 && bitErrorCumulative==0) break;
|
||||||
break;
|
|
||||||
|
|
||||||
blockErrorCumulative = 0;
|
blockErrorCumulative = 0;
|
||||||
bitErrorCumulative = 0;
|
bitErrorCumulative = 0;
|
||||||
@@ -425,6 +352,6 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
print_meas(&timeEncoder,"polar_encoder",NULL,NULL);
|
print_meas(&timeEncoder,"polar_encoder",NULL,NULL);
|
||||||
print_meas(&timeDecoder,"polar_decoder",NULL,NULL);
|
print_meas(&timeDecoder,"polar_decoder",NULL,NULL);
|
||||||
fclose(logFile);
|
if (logFlag) fclose(logFile);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
|
||||||
|
#include "SIMULATION/TOOLS/sim.h"
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
//#define DEBUG_SMALLBLOCKTEST
|
||||||
|
|
||||||
|
signed char quantize(double D, double x, unsigned char B)
|
||||||
|
{
|
||||||
|
double qxd;
|
||||||
|
short maxlev;
|
||||||
|
qxd = floor(x/D);
|
||||||
|
|
||||||
|
maxlev = 1<<(B-1);//(char)(pow(2,B-1));
|
||||||
|
|
||||||
|
if (qxd <= -maxlev)
|
||||||
|
qxd = -maxlev;
|
||||||
|
else if (qxd >= maxlev)
|
||||||
|
qxd = maxlev-1;
|
||||||
|
|
||||||
|
return((char)qxd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
time_stats_t timeEncoder,timeDecoder;
|
||||||
|
opp_enabled=1;
|
||||||
|
cpu_freq_GHz = get_cpu_freq_GHz();
|
||||||
|
reset_meas(&timeEncoder);
|
||||||
|
reset_meas(&timeDecoder);
|
||||||
|
randominit(0);
|
||||||
|
|
||||||
|
int arguments, iterations = 1000, messageLength = 11;
|
||||||
|
//int matlabDebug = 0;
|
||||||
|
uint32_t testInput, encoderOutput, codingDifference, nBitError=0, blockErrorState = 0, blockErrorCumulative=0, bitErrorCumulative=0;
|
||||||
|
uint16_t estimatedOutput;
|
||||||
|
double SNRstart = -20.0, SNRstop = 5.0, SNRinc= 0.5; //dB
|
||||||
|
double SNR, SNR_lin, sigma;
|
||||||
|
double modulatedInput[NR_SMALL_BLOCK_CODED_BITS], channelOutput[NR_SMALL_BLOCK_CODED_BITS];
|
||||||
|
//int16_t channelOutput_int16[NR_SMALL_BLOCK_CODED_BITS];
|
||||||
|
int8_t channelOutput_int8[NR_SMALL_BLOCK_CODED_BITS];
|
||||||
|
unsigned char qbits=8;
|
||||||
|
|
||||||
|
while ((arguments = getopt (argc, argv, "s:d:f:l:i:mhg")) != -1)
|
||||||
|
switch (arguments)
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
SNRstart = atof(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
SNRinc = atof(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
SNRstop = atof(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
messageLength = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
iterations = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*case 'm':
|
||||||
|
matlabDebug = 1;
|
||||||
|
//#define DEBUG_POLAR_MATLAB
|
||||||
|
break;*/
|
||||||
|
|
||||||
|
case 'g':
|
||||||
|
iterations = 1;
|
||||||
|
SNRstart = -6.0;
|
||||||
|
SNRstop = -6.0;
|
||||||
|
messageLength = 11;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
//printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations -m Matlab Debug\n");
|
||||||
|
printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations\n");
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
default:
|
||||||
|
perror("[smallblocktest.c] Problem at argument parsing with getopt");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t mask = 0x07ff >> (11-messageLength);
|
||||||
|
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
|
||||||
|
printf("SNR %f\n",SNR);
|
||||||
|
SNR_lin = pow(10, SNR/10.0);
|
||||||
|
sigma = 1.0/sqrt(SNR_lin);
|
||||||
|
|
||||||
|
for (int itr = 1; itr <= iterations; itr++) {
|
||||||
|
|
||||||
|
//Generate random test input of length "messageLength"
|
||||||
|
testInput = 0;
|
||||||
|
for (int i = 1; i < messageLength; i++) {
|
||||||
|
testInput |= ( ((uint32_t) (rand()%2)) &1);
|
||||||
|
testInput<<=1;
|
||||||
|
}
|
||||||
|
testInput |= ( ((uint32_t) (rand()%2)) &1);
|
||||||
|
//Encoding
|
||||||
|
start_meas(&timeEncoder);
|
||||||
|
encoderOutput = encodeSmallBlock((uint16_t*)&testInput, (uint8_t)messageLength);
|
||||||
|
stop_meas(&timeEncoder);
|
||||||
|
|
||||||
|
for (int i=0; i<NR_SMALL_BLOCK_CODED_BITS; i++) {
|
||||||
|
//BPSK modulation
|
||||||
|
if ((encoderOutput>>i) & 1 ) {
|
||||||
|
modulatedInput[i]=-1;
|
||||||
|
} else {
|
||||||
|
modulatedInput[i]=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//AWGN
|
||||||
|
channelOutput[i] = modulatedInput[i] + ( gaussdouble(0.0,1.0) * ( 1/sqrt(SNR_lin) ) );
|
||||||
|
|
||||||
|
//Quantization
|
||||||
|
channelOutput_int8[i] = quantize(sigma/16.0, channelOutput[i], qbits);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Decoding
|
||||||
|
start_meas(&timeDecoder);
|
||||||
|
estimatedOutput = decodeSmallBlock(channelOutput_int8, (uint8_t)messageLength);
|
||||||
|
stop_meas(&timeDecoder);
|
||||||
|
|
||||||
|
#ifdef DEBUG_SMALLBLOCKTEST
|
||||||
|
printf("[smallblocktest] Input = 0x%x, Output = 0x%x, DecoderOutput = 0x%x\n", testInput, encoderOutput, estimatedOutput);
|
||||||
|
for (int i=0;i<32;i++)
|
||||||
|
printf("[smallblocktest] Input[%d] = %d, Output[%d] = %d, codingDifference[%d]=%d, Mask[%d] = %d\n", i, (testInput>>i)&1, i, (estimatedOutput>>i)&1, i, (codingDifference>>i)&1, i, (mask>>i)&1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Error Calculation
|
||||||
|
estimatedOutput &= mask;
|
||||||
|
codingDifference = ((uint32_t)estimatedOutput) ^ testInput; // Count the # of 1's in codingDifference by Brian Kernighan’s algorithm.
|
||||||
|
|
||||||
|
for (nBitError = 0; codingDifference; nBitError++)
|
||||||
|
codingDifference &= codingDifference - 1;
|
||||||
|
|
||||||
|
blockErrorState = (nBitError > 0) ? 1 : 0;
|
||||||
|
|
||||||
|
blockErrorCumulative+=blockErrorState;
|
||||||
|
bitErrorCumulative+=nBitError;
|
||||||
|
|
||||||
|
nBitError = 0; blockErrorState = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Error statistics for the SNR; iteration times are in nanoseconds and microseconds, respectively.
|
||||||
|
printf("[smallblocktest] SNR=%+7.3f, BER=%9.6f, BLER=%9.6f, t_Encoder=%9.3fns, t_Decoder=%7.3fus\n",
|
||||||
|
SNR,
|
||||||
|
((double)bitErrorCumulative / (iterations*messageLength)),
|
||||||
|
((double)blockErrorCumulative/iterations),
|
||||||
|
((double)timeEncoder.diff/timeEncoder.trials)/(cpu_freq_GHz),
|
||||||
|
((double)timeDecoder.diff/timeDecoder.trials)/(cpu_freq_GHz*1000.0));
|
||||||
|
|
||||||
|
blockErrorCumulative=0;
|
||||||
|
bitErrorCumulative=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_meas(&timeEncoder, "smallblock_encoder", NULL, NULL);
|
||||||
|
print_meas(&timeDecoder, "smallblock_decoder", NULL, NULL);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
@@ -453,7 +453,7 @@ int32_t nr_segmentation(unsigned char *input_buffer,
|
|||||||
unsigned int B,
|
unsigned int B,
|
||||||
unsigned int *C,
|
unsigned int *C,
|
||||||
unsigned int *K,
|
unsigned int *K,
|
||||||
unsigned int *Zout,
|
unsigned int *Zout,
|
||||||
unsigned int *F);
|
unsigned int *F);
|
||||||
|
|
||||||
uint32_t nr_compute_tbs(uint8_t mcs,
|
uint32_t nr_compute_tbs(uint8_t mcs,
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "coding_defs.h"
|
#include "coding_defs.h"
|
||||||
|
#include "assertions.h"
|
||||||
|
|
||||||
/*ref 36-212 v8.6.0 , pp 8-9 */
|
/*ref 36-212 v8.6.0 , pp 8-9 */
|
||||||
/* the highest degree is set by default */
|
/* the highest degree is set by default */
|
||||||
@@ -105,17 +106,6 @@ void crcTableInit (void)
|
|||||||
} while (++c);
|
} while (++c);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Generic version
|
|
||||||
void crcTable256Init (uint32_t poly, uint32_t* crc256Table)
|
|
||||||
{
|
|
||||||
unsigned char c = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
crc256Table[c] = crcbit(&c, 1, poly);
|
|
||||||
} while (++c);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
|
|
||||||
Byte by byte implementations,
|
Byte by byte implementations,
|
||||||
@@ -235,30 +225,10 @@ crc8 (unsigned char * inptr, int bitlen)
|
|||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Generic version
|
|
||||||
unsigned int crcPayload(unsigned char * inptr, int bitlen, uint32_t* crc256Table)
|
|
||||||
{
|
|
||||||
int octetlen, resbit;
|
|
||||||
unsigned int crc = 0;
|
|
||||||
octetlen = bitlen/8; // Change in bytes
|
|
||||||
resbit = (bitlen % 8);
|
|
||||||
|
|
||||||
while (octetlen-- > 0)
|
|
||||||
{
|
|
||||||
crc = (crc << 8) ^ crc256Table[(*inptr++) ^ (crc >> 24)];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resbit > 0)
|
|
||||||
{
|
|
||||||
crc = (crc << resbit) ^ crc256Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
|
|
||||||
}
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
|
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
|
||||||
{
|
{
|
||||||
uint32_t crc=0,oldcrc=0;
|
uint32_t crc=0,oldcrc=0;
|
||||||
uint8_t crc_len,temp;
|
uint8_t crc_len=0;
|
||||||
|
|
||||||
switch (crc_type) {
|
switch (crc_type) {
|
||||||
case CRC24_A:
|
case CRC24_A:
|
||||||
@@ -275,7 +245,7 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
crc_len=3;
|
AssertFatal(1,"Invalid crc_type \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<crc_len; i++)
|
for (int i=0; i<crc_len; i++)
|
||||||
@@ -309,6 +279,9 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
|
|||||||
crc = crc8(decoded_bytes,
|
crc = crc8(decoded_bytes,
|
||||||
n-8)>>24;
|
n-8)>>24;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
AssertFatal(1,"Invalid crc_type \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crc == oldcrc)
|
if (crc == oldcrc)
|
||||||
@@ -331,7 +304,7 @@ main()
|
|||||||
{
|
{
|
||||||
unsigned char test[] = "Thebigredfox";
|
unsigned char test[] = "Thebigredfox";
|
||||||
crcTableInit();
|
crcTableInit();
|
||||||
printf("%x\n", crcbit(test, sizeof(test) - 1, poly24));
|
printf("%x\n", crcbit(test, sizeof(test) - 1, poly24a));
|
||||||
printf("%x\n", crc24(test, (sizeof(test) - 1)*8));
|
printf("%x\n", crc24(test, (sizeof(test) - 1)*8));
|
||||||
printf("%x\n", crcbit(test, sizeof(test) - 1, poly8));
|
printf("%x\n", crcbit(test, sizeof(test) - 1, poly8));
|
||||||
printf("%x\n", crc8(test, (sizeof(test) - 1)*8));
|
printf("%x\n", crc8(test, (sizeof(test) - 1)*8));
|
||||||
|
|||||||
@@ -1,117 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "time_meas.h"
|
|
||||||
#include <math.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
// global var for openair performance profiler
|
|
||||||
extern int opp_enabled;
|
|
||||||
|
|
||||||
|
|
||||||
double get_cpu_freq_GHz(void) {
|
|
||||||
|
|
||||||
time_stats_t ts = {0};
|
|
||||||
reset_meas(&ts);
|
|
||||||
ts.trials++;
|
|
||||||
ts.in = rdtsc_oai();
|
|
||||||
sleep(1);
|
|
||||||
ts.diff = (rdtsc_oai()-ts.in);
|
|
||||||
cpu_freq_GHz = (double)ts.diff/1000000000;
|
|
||||||
printf("CPU Freq is %f \n", cpu_freq_GHz);
|
|
||||||
return cpu_freq_GHz;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name){
|
|
||||||
|
|
||||||
if (opp_enabled) {
|
|
||||||
|
|
||||||
//static double cpu_freq_GHz = 3.2;
|
|
||||||
|
|
||||||
//if (cpu_freq_GHz == 0.0)
|
|
||||||
//cpu_freq_GHz = get_cpu_freq_GHz(); // super slow
|
|
||||||
|
|
||||||
if (ts->trials>0) {
|
|
||||||
|
|
||||||
//fprintf(file_name,"Name %25s: Processing %15.3f ms for SF %d, diff_now %15.3f \n", name,(ts->diff_now/(cpu_freq_GHz*1000000.0)),subframe,ts->diff_now);
|
|
||||||
fprintf(file_name,"%15.3f ms, diff_now %15.3f \n",(ts->diff_now/(cpu_freq_GHz*1000000.0)),(double)ts->diff_now);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_meas(time_stats_t *ts, const char* name, time_stats_t * total_exec_time, time_stats_t * sf_exec_time)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (opp_enabled) {
|
|
||||||
|
|
||||||
static int first_time = 0;
|
|
||||||
static double cpu_freq_GHz = 0.0;
|
|
||||||
|
|
||||||
if (cpu_freq_GHz == 0.0)
|
|
||||||
cpu_freq_GHz = get_cpu_freq_GHz();
|
|
||||||
|
|
||||||
if (first_time == 0) {
|
|
||||||
first_time=1;
|
|
||||||
|
|
||||||
if ((total_exec_time == NULL) || (sf_exec_time== NULL))
|
|
||||||
fprintf(stderr, "%25s %25s %25s %25s %25s %6f\n","Name","Total","Per Trials", "Num Trials","CPU_F_GHz", cpu_freq_GHz);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "%25s %25s %25s %20s %15s %6f\n","Name","Total","Average/Frame","Trials", "CPU_F_GHz", cpu_freq_GHz);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ts->trials>0) {
|
|
||||||
//printf("%20s: total: %10.3f ms, average: %10.3f us (%10d trials)\n", name, ts->diff/cpu_freq_GHz/1000000.0, ts->diff/ts->trials/cpu_freq_GHz/1000.0, ts->trials);
|
|
||||||
|
|
||||||
if ((total_exec_time == NULL) || (sf_exec_time== NULL)) {
|
|
||||||
fprintf(stderr, "%25s: %15.3f ms ; %15.3f us; %15d;\n",
|
|
||||||
name,
|
|
||||||
(ts->diff/cpu_freq_GHz/1000000.0),
|
|
||||||
(ts->diff/ts->trials/cpu_freq_GHz/1000.0),
|
|
||||||
ts->trials);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "%25s: %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n",
|
|
||||||
name,
|
|
||||||
(ts->diff/cpu_freq_GHz/1000000.0),
|
|
||||||
((ts->diff/cpu_freq_GHz/1000000.0)/(total_exec_time->diff/cpu_freq_GHz/1000000.0))*100, // percentage
|
|
||||||
(ts->diff/ts->trials/cpu_freq_GHz/1000.0),
|
|
||||||
((ts->diff/ts->trials/cpu_freq_GHz/1000.0)/(sf_exec_time->diff/sf_exec_time->trials/cpu_freq_GHz/1000.0))*100, // percentage
|
|
||||||
ts->trials);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
double get_time_meas_us(time_stats_t *ts)
|
|
||||||
{
|
|
||||||
|
|
||||||
static double cpu_freq_GHz = 0.0;
|
|
||||||
|
|
||||||
if (cpu_freq_GHz == 0.0)
|
|
||||||
cpu_freq_GHz = get_cpu_freq_GHz();
|
|
||||||
|
|
||||||
if (ts->trials>0)
|
|
||||||
return (ts->diff/ts->trials/cpu_freq_GHz/1000.0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,156 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __TIME_MEAS_DEFS__H__
|
|
||||||
#define __TIME_MEAS_DEFS__H__
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
// global var to enable openair performance profiler
|
|
||||||
static int opp_enabled = 1;
|
|
||||||
double cpu_freq_GHz;
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
|
|
||||||
long long in;
|
|
||||||
long long diff;
|
|
||||||
long long diff_now;
|
|
||||||
long long p_time; /*!< \brief absolute process duration */
|
|
||||||
long long diff_square; /*!< \brief process duration square */
|
|
||||||
long long max;
|
|
||||||
int trials;
|
|
||||||
int meas_flag;
|
|
||||||
} time_stats_t;
|
|
||||||
#elif defined(__arm__)
|
|
||||||
typedef struct {
|
|
||||||
uint32_t in;
|
|
||||||
uint32_t diff_now;
|
|
||||||
uint32_t diff;
|
|
||||||
uint32_t p_time; /*!< \brief absolute process duration */
|
|
||||||
uint32_t diff_square; /*!< \brief process duration square */
|
|
||||||
uint32_t max;
|
|
||||||
int trials;
|
|
||||||
} time_stats_t;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
static inline void start_meas(time_stats_t *ts) __attribute__((always_inline));
|
|
||||||
static inline void stop_meas(time_stats_t *ts) __attribute__((always_inline));
|
|
||||||
|
|
||||||
|
|
||||||
void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name);
|
|
||||||
//void print_meas(time_stats_t *ts, const char* name, time_stats_t * total_exec_time, time_stats_t * sf_exec_time);
|
|
||||||
double get_time_meas_us(time_stats_t *ts);
|
|
||||||
double get_cpu_freq_GHz(void);
|
|
||||||
|
|
||||||
#if defined(__i386__)
|
|
||||||
static inline unsigned long long rdtsc_oai(void) __attribute__((always_inline));
|
|
||||||
static inline unsigned long long rdtsc_oai(void)
|
|
||||||
{
|
|
||||||
unsigned long long int x;
|
|
||||||
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
#elif defined(__x86_64__)
|
|
||||||
static inline unsigned long long rdtsc_oai(void) __attribute__((always_inline));
|
|
||||||
static inline unsigned long long rdtsc_oai(void)
|
|
||||||
{
|
|
||||||
unsigned long long a, d;
|
|
||||||
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
|
|
||||||
return (d<<32) | a;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(__arm__)
|
|
||||||
static inline uint32_t rdtsc_oai(void) __attribute__((always_inline));
|
|
||||||
static inline uint32_t rdtsc_oai(void)
|
|
||||||
{
|
|
||||||
uint32_t r = 0;
|
|
||||||
asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(r) );
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void start_meas(time_stats_t *ts)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (opp_enabled) {
|
|
||||||
if (ts->meas_flag==0) {
|
|
||||||
ts->trials++;
|
|
||||||
ts->in = rdtsc_oai();
|
|
||||||
ts->meas_flag=1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ts->in = rdtsc_oai();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stop_meas(time_stats_t *ts)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (opp_enabled) {
|
|
||||||
long long out = rdtsc_oai();
|
|
||||||
|
|
||||||
ts->diff_now = (out-ts->in);
|
|
||||||
|
|
||||||
ts->diff_now = (out-ts->in);
|
|
||||||
ts->diff += (out-ts->in);
|
|
||||||
/// process duration is the difference between two clock points
|
|
||||||
ts->p_time = (out-ts->in);
|
|
||||||
ts->diff_square += (out-ts->in)*(out-ts->in);
|
|
||||||
|
|
||||||
if ((out-ts->in) > ts->max)
|
|
||||||
ts->max = out-ts->in;
|
|
||||||
|
|
||||||
ts->meas_flag=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void reset_meas(time_stats_t *ts) {
|
|
||||||
|
|
||||||
ts->trials=0;
|
|
||||||
ts->diff=0;
|
|
||||||
ts->diff_now=0;
|
|
||||||
ts->p_time=0;
|
|
||||||
ts->diff_square=0;
|
|
||||||
ts->max=0;
|
|
||||||
ts->meas_flag=0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (opp_enabled) {
|
|
||||||
dst_ts->trials=src_ts->trials;
|
|
||||||
dst_ts->diff=src_ts->diff;
|
|
||||||
dst_ts->max=src_ts->max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
#ifndef __NR_LDPC_TYPES__H__
|
#ifndef __NR_LDPC_TYPES__H__
|
||||||
#define __NR_LDPC_TYPES__H__
|
#define __NR_LDPC_TYPES__H__
|
||||||
|
|
||||||
#include "./nrLDPC_tools/time_meas.h"
|
#include "PHY/TOOLS/time_meas.h"
|
||||||
|
|
||||||
// ==============================================================================
|
// ==============================================================================
|
||||||
// TYPES
|
// TYPES
|
||||||
|
|||||||
@@ -19,9 +19,20 @@
|
|||||||
* contact@openairinterface.org
|
* contact@openairinterface.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!\file PHY/CODING/nrPolar_tools/nr_bitwise_operations.c
|
||||||
|
* \brief
|
||||||
|
* \author Turker Yilmaz
|
||||||
|
* \date 2018
|
||||||
|
* \version 0.1
|
||||||
|
* \company EURECOM
|
||||||
|
* \email turker.yilmaz@eurecom.fr
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||||
|
|
||||||
void nr_bit2byte_uint32_8_t(uint32_t *in, uint16_t arraySize, uint8_t *out) {
|
void nr_bit2byte_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out) {
|
||||||
uint8_t arrayInd = ceil(arraySize / 32.0);
|
uint8_t arrayInd = ceil(arraySize / 32.0);
|
||||||
for (int i = 0; i < (arrayInd-1); i++) {
|
for (int i = 0; i < (arrayInd-1); i++) {
|
||||||
for (int j = 0; j < 32; j++) {
|
for (int j = 0; j < 32; j++) {
|
||||||
@@ -29,10 +40,11 @@ void nr_bit2byte_uint32_8_t(uint32_t *in, uint16_t arraySize, uint8_t *out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < arraySize - ((arrayInd-1) * 32); j++) out[j + ((arrayInd-1) * 32)] = (in[(arrayInd-1)] >> j) & 1;
|
for (int j = 0; j < arraySize - ((arrayInd-1) * 32); j++)
|
||||||
|
out[j + ((arrayInd-1) * 32)] = (in[(arrayInd-1)] >> j) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_byte2bit_uint8_32_t(uint8_t *in, uint16_t arraySize, uint32_t *out) {
|
void nr_byte2bit_uint8_32(uint8_t *in, uint16_t arraySize, uint32_t *out) {
|
||||||
uint8_t arrayInd = ceil(arraySize / 32.0);
|
uint8_t arrayInd = ceil(arraySize / 32.0);
|
||||||
for (int i = 0; i < arrayInd; i++) {
|
for (int i = 0; i < arrayInd; i++) {
|
||||||
out[i]=0;
|
out[i]=0;
|
||||||
@@ -43,16 +55,3 @@ void nr_byte2bit_uint8_32_t(uint8_t *in, uint16_t arraySize, uint32_t *out) {
|
|||||||
out[i]|=in[(i*32)];
|
out[i]|=in[(i*32)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_crc_bit2bit_uint32_8_t(uint32_t *in, uint16_t arraySize, uint8_t *out) {
|
|
||||||
out[0]=0xff;
|
|
||||||
out[1]=0xff;
|
|
||||||
out[2]=0xff;
|
|
||||||
uint8_t arrayInd = ceil(arraySize / 32.0);
|
|
||||||
for (int i = 0; i < arrayInd; i++) {
|
|
||||||
out[3+i*4] = ((in[i] & (0x0000000f))<<4) | ((in[i] & (0x000000f0))>>4);
|
|
||||||
out[4+i*4] = (((in[i] & (0x00000f00))<<4) | ((in[i] & (0x0000f000))>>4))>>8;
|
|
||||||
out[5+i*4] = (((in[i] & (0x000f0000))<<4) | ((in[i] & (0x00f00000))>>4))>>16;
|
|
||||||
out[6+i*4] = (((in[i] & (0x0f000000))<<4) | ((in[i] & (0xf0000000))>>4))>>24;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -21,43 +21,36 @@
|
|||||||
|
|
||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||||
|
|
||||||
|
|
||||||
// ----- Old implementation ----
|
// ----- Old implementation ----
|
||||||
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits){
|
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits){
|
||||||
|
|
||||||
uint8_t crcPolynomialPattern[25] = {1,1,0,1,1,0,0,1,0,1,0,1,1,0,0,0,1,0,0,0,1,0,1,1,1};
|
uint8_t crcPolynomialPattern[25] = {1,1,0,1,1,0,0,1,0,1,0,1,1,0,0,0,1,0,0,0,1,0,1,1,1};
|
||||||
// 1011 0010 1011 0001 0001 0111 D^24 + D^23 + D^21 + D^20 + D^17 + D^15 + D^13 + D^12 + D^8 + D^4 + D^2 + D + 1
|
// 1011 0010 1011 0001 0001 0111 D^24 + D^23 + D^21 + D^20 + D^17 + D^15 + D^13 + D^12 + D^8 + D^4 + D^2 + D + 1
|
||||||
uint8_t crcPolynomialSize = 24;// 24 because crc24c
|
uint8_t crcPolynomialSize = 24;
|
||||||
uint8_t temp1[crcPolynomialSize], temp2[crcPolynomialSize];
|
uint8_t temp1[crcPolynomialSize], temp2[crcPolynomialSize];
|
||||||
|
|
||||||
uint8_t **crc_generator_matrix = malloc(payloadSizeBits * sizeof(uint8_t *));
|
uint8_t **crc_generator_matrix = malloc(payloadSizeBits * sizeof(uint8_t *));
|
||||||
if (crc_generator_matrix)
|
if (crc_generator_matrix)
|
||||||
{
|
|
||||||
for (int i = 0; i < payloadSizeBits; i++)
|
for (int i = 0; i < payloadSizeBits; i++)
|
||||||
{
|
|
||||||
crc_generator_matrix[i] = malloc(crcPolynomialSize * sizeof(uint8_t));
|
crc_generator_matrix[i] = malloc(crcPolynomialSize * sizeof(uint8_t));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < crcPolynomialSize; i++) crc_generator_matrix[payloadSizeBits-1][i]=crcPolynomialPattern[i+1];
|
for (int i = 0; i < crcPolynomialSize; i++) crc_generator_matrix[payloadSizeBits-1][i]=crcPolynomialPattern[i+1];
|
||||||
|
|
||||||
for (int i = payloadSizeBits-2; i >= 0; i--){
|
for (int i = payloadSizeBits-2; i >= 0; i--){
|
||||||
|
|
||||||
for (int j = 0; j < crcPolynomialSize-1; j++) temp1[j]=crc_generator_matrix[i+1][j+1];
|
for (int j = 0; j < crcPolynomialSize-1; j++) temp1[j]=crc_generator_matrix[i+1][j+1];
|
||||||
|
|
||||||
temp1[crcPolynomialSize-1]=0;
|
temp1[crcPolynomialSize-1]=0;
|
||||||
|
|
||||||
for (int j = 0; j < crcPolynomialSize; j++) temp2[j]=crc_generator_matrix[i+1][0]*crcPolynomialPattern[j+1];
|
for (int j = 0; j < crcPolynomialSize; j++)
|
||||||
|
temp2[j]=crc_generator_matrix[i+1][0]*crcPolynomialPattern[j+1];
|
||||||
|
|
||||||
for (int j = 0; j < crcPolynomialSize; j++){
|
for (int j = 0; j < crcPolynomialSize; j++){
|
||||||
if(temp1[j]+temp2[j] == 1){
|
if(temp1[j]+temp2[j] == 1)
|
||||||
crc_generator_matrix[i][j]=1;
|
crc_generator_matrix[i][j]=1;
|
||||||
} else {
|
else
|
||||||
crc_generator_matrix[i][j]=0;
|
crc_generator_matrix[i][j]=0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return crc_generator_matrix;
|
return crc_generator_matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,30 +63,26 @@ uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits){
|
|||||||
|
|
||||||
uint8_t **crc_generator_matrix = malloc(payloadSizeBits * sizeof(uint8_t *));
|
uint8_t **crc_generator_matrix = malloc(payloadSizeBits * sizeof(uint8_t *));
|
||||||
if (crc_generator_matrix)
|
if (crc_generator_matrix)
|
||||||
{
|
|
||||||
for (int i = 0; i < payloadSizeBits; i++)
|
for (int i = 0; i < payloadSizeBits; i++)
|
||||||
{
|
|
||||||
crc_generator_matrix[i] = malloc(crcPolynomialSize * sizeof(uint8_t));
|
crc_generator_matrix[i] = malloc(crcPolynomialSize * sizeof(uint8_t));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < crcPolynomialSize; i++) crc_generator_matrix[payloadSizeBits-1][i]=crcPolynomialPattern[i+1];
|
for (int i = 0; i < crcPolynomialSize; i++) crc_generator_matrix[payloadSizeBits-1][i]=crcPolynomialPattern[i+1];
|
||||||
|
|
||||||
for (int i = payloadSizeBits-2; i >= 0; i--){
|
for (int i = payloadSizeBits-2; i >= 0; i--){
|
||||||
|
for (int j = 0; j < crcPolynomialSize-1; j++)
|
||||||
|
temp1[j]=crc_generator_matrix[i+1][j+1];
|
||||||
|
|
||||||
for (int j = 0; j < crcPolynomialSize-1; j++) temp1[j]=crc_generator_matrix[i+1][j+1];
|
|
||||||
temp1[crcPolynomialSize-1]=0;
|
temp1[crcPolynomialSize-1]=0;
|
||||||
|
|
||||||
for (int j = 0; j < crcPolynomialSize; j++) temp2[j]=crc_generator_matrix[i+1][0]*crcPolynomialPattern[j+1];
|
for (int j = 0; j < crcPolynomialSize; j++)
|
||||||
|
temp2[j]=crc_generator_matrix[i+1][0]*crcPolynomialPattern[j+1];
|
||||||
|
|
||||||
for (int j = 0; j < crcPolynomialSize; j++){
|
for (int j = 0; j < crcPolynomialSize; j++){
|
||||||
if(temp1[j]+temp2[j] == 1){
|
if(temp1[j]+temp2[j] == 1)
|
||||||
crc_generator_matrix[i][j]=1;
|
crc_generator_matrix[i][j]=1;
|
||||||
} else {
|
else
|
||||||
crc_generator_matrix[i][j]=0;
|
crc_generator_matrix[i][j]=0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return crc_generator_matrix;
|
return crc_generator_matrix;
|
||||||
@@ -105,33 +94,30 @@ uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits){
|
|||||||
// 0110 0001 D^6 + D^5 + 1
|
// 0110 0001 D^6 + D^5 + 1
|
||||||
uint8_t crcPolynomialSize = 6;
|
uint8_t crcPolynomialSize = 6;
|
||||||
uint8_t temp1[crcPolynomialSize], temp2[crcPolynomialSize];
|
uint8_t temp1[crcPolynomialSize], temp2[crcPolynomialSize];
|
||||||
|
|
||||||
uint8_t **crc_generator_matrix = malloc(payloadSizeBits * sizeof(uint8_t *));
|
uint8_t **crc_generator_matrix = malloc(payloadSizeBits * sizeof(uint8_t *));
|
||||||
if (crc_generator_matrix)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < payloadSizeBits; i++)
|
|
||||||
{
|
|
||||||
crc_generator_matrix[i] = malloc(crcPolynomialSize * sizeof(uint8_t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < crcPolynomialSize; i++) crc_generator_matrix[payloadSizeBits-1][i]=crcPolynomialPattern[i+1];
|
if (crc_generator_matrix)
|
||||||
|
for (int i = 0; i < payloadSizeBits; i++)
|
||||||
|
crc_generator_matrix[i] = malloc(crcPolynomialSize * sizeof(uint8_t));
|
||||||
|
|
||||||
|
for (int i = 0; i < crcPolynomialSize; i++)
|
||||||
|
crc_generator_matrix[payloadSizeBits-1][i]=crcPolynomialPattern[i+1];
|
||||||
|
|
||||||
for (int i = payloadSizeBits-2; i >= 0; i--){
|
for (int i = payloadSizeBits-2; i >= 0; i--){
|
||||||
|
for (int j = 0; j < crcPolynomialSize-1; j++)
|
||||||
|
temp1[j]=crc_generator_matrix[i+1][j+1];
|
||||||
|
|
||||||
for (int j = 0; j < crcPolynomialSize-1; j++) temp1[j]=crc_generator_matrix[i+1][j+1];
|
|
||||||
temp1[crcPolynomialSize-1]=0;
|
temp1[crcPolynomialSize-1]=0;
|
||||||
|
|
||||||
for (int j = 0; j < crcPolynomialSize; j++) temp2[j]=crc_generator_matrix[i+1][0]*crcPolynomialPattern[j+1];
|
for (int j = 0; j < crcPolynomialSize; j++)
|
||||||
|
temp2[j]=crc_generator_matrix[i+1][0]*crcPolynomialPattern[j+1];
|
||||||
|
|
||||||
for (int j = 0; j < crcPolynomialSize; j++){
|
for (int j = 0; j < crcPolynomialSize; j++){
|
||||||
if(temp1[j]+temp2[j] == 1){
|
if(temp1[j]+temp2[j] == 1)
|
||||||
crc_generator_matrix[i][j]=1;
|
crc_generator_matrix[i][j]=1;
|
||||||
} else {
|
else
|
||||||
crc_generator_matrix[i][j]=0;
|
crc_generator_matrix[i][j]=0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return crc_generator_matrix;
|
return crc_generator_matrix;
|
||||||
|
|||||||
@@ -21,11 +21,11 @@
|
|||||||
|
|
||||||
/*!\file PHY/CODING/nrPolar_tools/nr_polar_decoder.c
|
/*!\file PHY/CODING/nrPolar_tools/nr_polar_decoder.c
|
||||||
* \brief
|
* \brief
|
||||||
* \author Turker Yilmaz
|
* \author Raymond Knopp, Turker Yilmaz
|
||||||
* \date 2018
|
* \date 2018
|
||||||
* \version 0.1
|
* \version 0.1
|
||||||
* \company EURECOM
|
* \company EURECOM
|
||||||
* \email turker.yilmaz@eurecom.fr
|
* \email raymond.knopp@eurecom.fr, turker.yilmaz@eurecom.fr
|
||||||
* \note
|
* \note
|
||||||
* \warning
|
* \warning
|
||||||
*/
|
*/
|
||||||
@@ -39,12 +39,11 @@
|
|||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||||
#include "assertions.h"
|
#include "assertions.h"
|
||||||
|
|
||||||
int8_t polar_decoder(
|
int8_t polar_decoder(double *input,
|
||||||
double *input,
|
uint32_t *out,
|
||||||
uint8_t *out,
|
t_nrPolar_params *polarParams,
|
||||||
t_nrPolar_params *polarParams,
|
uint8_t listSize)
|
||||||
uint8_t listSize,
|
{
|
||||||
uint8_t pathMetricAppr) {
|
|
||||||
//Assumes no a priori knowledge.
|
//Assumes no a priori knowledge.
|
||||||
uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
|
uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
|
||||||
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
||||||
@@ -118,12 +117,12 @@ int8_t polar_decoder(
|
|||||||
uint8_t listIndex[2*listSize], copyIndex;
|
uint8_t listIndex[2*listSize], copyIndex;
|
||||||
|
|
||||||
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
|
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
|
||||||
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
|
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1));
|
||||||
|
|
||||||
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
|
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
|
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit);
|
||||||
} else { //Information or CRC bit.
|
} else { //Information or CRC bit.
|
||||||
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
|
updatePathMetric2(pathMetric, llr, currentListSize, currentBit);
|
||||||
|
|
||||||
for (int i = 0; i < currentListSize; i++) {
|
for (int i = 0; i < currentListSize; i++) {
|
||||||
for (int j = 0; j < polarParams->N; j++) {
|
for (int j = 0; j < polarParams->N; j++) {
|
||||||
@@ -293,567 +292,14 @@ int8_t polar_decoder(
|
|||||||
/*
|
/*
|
||||||
* Return bits.
|
* Return bits.
|
||||||
*/
|
*/
|
||||||
//nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
|
nr_byte2bit_uint8_32(polarParams->nr_polar_A, polarParams->payloadBits, out);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t polar_decoder_aPriori(double *input,
|
|
||||||
uint32_t *out,
|
|
||||||
t_nrPolar_params *polarParams,
|
|
||||||
uint8_t listSize,
|
|
||||||
uint8_t pathMetricAppr,
|
|
||||||
double *aPrioriPayload) {
|
|
||||||
uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
|
|
||||||
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
|
||||||
uint8_t **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
|
||||||
double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
|
|
||||||
uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize);
|
|
||||||
double *pathMetric = malloc(sizeof(double)*(2*listSize));
|
|
||||||
uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
|
|
||||||
|
|
||||||
for (int i=0; i<(2*listSize); i++) {
|
|
||||||
pathMetric[i] = 0;
|
|
||||||
crcState[i]=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<polarParams->N; i++) {
|
|
||||||
llrUpdated[i][polarParams->n]=1;
|
|
||||||
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
|
|
||||||
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
|
|
||||||
|
|
||||||
for (int i = 0; i < polarParams->K; i++) {
|
|
||||||
extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
|
|
||||||
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<polarParams->payloadBits; i++) {
|
|
||||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
|
||||||
tempECGM[i][j]=polarParams->crc_generator_matrix[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
|
|
||||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
|
||||||
if( (i-polarParams->payloadBits) == j ) {
|
|
||||||
tempECGM[i][j]=1;
|
|
||||||
} else {
|
|
||||||
tempECGM[i][j]=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<polarParams->K; i++) {
|
|
||||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
|
||||||
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//The index of the last 1-valued bit that appears in each column.
|
|
||||||
uint16_t last1ind[polarParams->crcParityBits];
|
|
||||||
|
|
||||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
|
||||||
for (int i=0; i<polarParams->K; i++) {
|
|
||||||
if (extended_crc_generator_matrix[i][j]==1) last1ind[j]=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double *d_tilde = malloc(sizeof(double) * polarParams->N);
|
|
||||||
nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
|
|
||||||
|
|
||||||
for (int j = 0; j < polarParams->N; j++) llr[j][polarParams->n][0]=d_tilde[j];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SCL polar decoder.
|
|
||||||
*/
|
|
||||||
uint32_t nonFrozenBit=0;
|
|
||||||
uint8_t currentListSize=1;
|
|
||||||
uint8_t decoderIterationCheck=0;
|
|
||||||
int16_t checkCrcBits=-1;
|
|
||||||
uint8_t listIndex[2*listSize], copyIndex;
|
|
||||||
|
|
||||||
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
|
|
||||||
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
|
|
||||||
|
|
||||||
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
|
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
|
|
||||||
} else { //Information or CRC bit.
|
|
||||||
if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) &&
|
|
||||||
(aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) {
|
|
||||||
//Information bit with known value of "0".
|
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr);
|
|
||||||
bitUpdated[currentBit][0]=1; //0=False, 1=True
|
|
||||||
} else if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) &&
|
|
||||||
(aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) {
|
|
||||||
//Information bit with known value of "1".
|
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr);
|
|
||||||
|
|
||||||
for (uint8_t i=0; i<currentListSize; i++) bit[currentBit][0][i]=1;
|
|
||||||
|
|
||||||
bitUpdated[currentBit][0]=1;
|
|
||||||
updateCrcChecksum(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
|
||||||
} else {
|
|
||||||
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
|
|
||||||
|
|
||||||
for (int i = 0; i < currentListSize; i++) {
|
|
||||||
for (int j = 0; j < polarParams->N; j++) {
|
|
||||||
for (int k = 0; k < (polarParams->n+1); k++) {
|
|
||||||
bit[j][k][i+currentListSize]=bit[j][k][i];
|
|
||||||
llr[j][k][i+currentListSize]=llr[j][k][i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < currentListSize; i++) {
|
|
||||||
bit[currentBit][0][i]=0;
|
|
||||||
crcState[i+currentListSize]=crcState[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1;
|
|
||||||
|
|
||||||
bitUpdated[currentBit][0]=1;
|
|
||||||
updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
|
||||||
currentListSize*=2;
|
|
||||||
|
|
||||||
//Keep only the best "listSize" number of entries.
|
|
||||||
if (currentListSize > listSize) {
|
|
||||||
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
|
|
||||||
|
|
||||||
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
|
|
||||||
//sort listIndex[listSize, ..., 2*listSize-1] in descending order.
|
|
||||||
uint8_t swaps, tempInd;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < listSize; i++) {
|
|
||||||
swaps = 0;
|
|
||||||
|
|
||||||
for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
|
|
||||||
if (listIndex[j+1] > listIndex[j]) {
|
|
||||||
tempInd = listIndex[j];
|
|
||||||
listIndex[j] = listIndex[j + 1];
|
|
||||||
listIndex[j + 1] = tempInd;
|
|
||||||
swaps++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (swaps == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//First, backup the best "listSize" number of entries.
|
|
||||||
for (int k=(listSize-1); k>0; k--) {
|
|
||||||
for (int i=0; i<polarParams->N; i++) {
|
|
||||||
for (int j=0; j<(polarParams->n+1); j++) {
|
|
||||||
bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]];
|
|
||||||
llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int k=(listSize-1); k>0; k--) {
|
|
||||||
for (int i = 0; i < polarParams->crcParityBits; i++) {
|
|
||||||
crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int k=(listSize-1); k>0; k--) crcState[listIndex[(2*listSize-1)-k]]=crcState[listIndex[k]];
|
|
||||||
|
|
||||||
//Copy the best "listSize" number of entries to the first indices.
|
|
||||||
for (int k = 0; k < listSize; k++) {
|
|
||||||
if (k > listIndex[k]) {
|
|
||||||
copyIndex = listIndex[(2*listSize-1)-k];
|
|
||||||
} else { //Use the backup.
|
|
||||||
copyIndex = listIndex[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < polarParams->N; i++) {
|
|
||||||
for (int j = 0; j < (polarParams->n + 1); j++) {
|
|
||||||
bit[i][j][k] = bit[i][j][copyIndex];
|
|
||||||
llr[i][j][k] = llr[i][j][copyIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int k = 0; k < listSize; k++) {
|
|
||||||
if (k > listIndex[k]) {
|
|
||||||
copyIndex = listIndex[(2*listSize-1)-k];
|
|
||||||
} else { //Use the backup.
|
|
||||||
copyIndex = listIndex[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < polarParams->crcParityBits; i++) {
|
|
||||||
crcChecksum[i][k]=crcChecksum[i][copyIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int k = 0; k < listSize; k++) {
|
|
||||||
if (k > listIndex[k]) {
|
|
||||||
copyIndex = listIndex[(2*listSize-1)-k];
|
|
||||||
} else { //Use the backup.
|
|
||||||
copyIndex = listIndex[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
crcState[k]=crcState[copyIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
currentListSize = listSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<polarParams->crcParityBits; i++) {
|
|
||||||
if (last1ind[i]==nonFrozenBit) {
|
|
||||||
checkCrcBits=i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( checkCrcBits > (-1) ) {
|
|
||||||
for (uint8_t i = 0; i < currentListSize; i++) {
|
|
||||||
if (crcChecksum[checkCrcBits][i]==1) {
|
|
||||||
crcState[i]=0; //0=False, 1=True
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i];
|
|
||||||
|
|
||||||
if (decoderIterationCheck==0) {
|
|
||||||
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
|
|
||||||
free(d_tilde);
|
|
||||||
free(pathMetric);
|
|
||||||
free(crcState);
|
|
||||||
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
|
|
||||||
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
|
|
||||||
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
nonFrozenBit++;
|
|
||||||
decoderIterationCheck=0;
|
|
||||||
checkCrcBits=-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
|
|
||||||
|
|
||||||
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
|
|
||||||
if ( crcState[listIndex[i]] == 1 ) {
|
|
||||||
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]];
|
|
||||||
|
|
||||||
//Extract the information bits (û to ĉ)
|
|
||||||
nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
|
|
||||||
//Deinterleaving (ĉ to b)
|
|
||||||
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
|
|
||||||
|
|
||||||
//Remove the CRC (â)
|
|
||||||
for (int j = 0; j < polarParams->payloadBits; j++)
|
|
||||||
polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(d_tilde);
|
|
||||||
free(pathMetric);
|
|
||||||
free(crcState);
|
|
||||||
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
|
|
||||||
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
|
|
||||||
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
|
|
||||||
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K);
|
|
||||||
nr_free_uint8_2D_array(tempECGM, polarParams->K);
|
|
||||||
/*
|
|
||||||
* Return bits.
|
|
||||||
*/
|
|
||||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int8_t polar_decoder_aPriori_timing(double *input,
|
|
||||||
uint32_t *out,
|
|
||||||
t_nrPolar_params *polarParams,
|
|
||||||
uint8_t listSize,
|
|
||||||
uint8_t pathMetricAppr,
|
|
||||||
double *aPrioriPayload,
|
|
||||||
double cpuFreqGHz,
|
|
||||||
FILE *logFile) {
|
|
||||||
uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
|
|
||||||
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
|
||||||
uint8_t **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
|
||||||
double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
|
|
||||||
uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize);
|
|
||||||
double *pathMetric = malloc(sizeof(double)*(2*listSize));
|
|
||||||
uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
|
|
||||||
|
|
||||||
for (int i=0; i<(2*listSize); i++) {
|
|
||||||
pathMetric[i] = 0;
|
|
||||||
crcState[i]=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<polarParams->N; i++) {
|
|
||||||
llrUpdated[i][polarParams->n]=1;
|
|
||||||
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
|
|
||||||
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
|
|
||||||
|
|
||||||
for (int i = 0; i < polarParams->K; i++) {
|
|
||||||
extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
|
|
||||||
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<polarParams->payloadBits; i++) {
|
|
||||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
|
||||||
tempECGM[i][j]=polarParams->crc_generator_matrix[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
|
|
||||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
|
||||||
if( (i-polarParams->payloadBits) == j ) {
|
|
||||||
tempECGM[i][j]=1;
|
|
||||||
} else {
|
|
||||||
tempECGM[i][j]=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<polarParams->K; i++) {
|
|
||||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
|
||||||
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//The index of the last 1-valued bit that appears in each column.
|
|
||||||
uint16_t last1ind[polarParams->crcParityBits];
|
|
||||||
|
|
||||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
|
||||||
for (int i=0; i<polarParams->K; i++) {
|
|
||||||
if (extended_crc_generator_matrix[i][j]==1) last1ind[j]=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double *d_tilde = malloc(sizeof(double) * polarParams->N);
|
|
||||||
nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
|
|
||||||
|
|
||||||
for (int j = 0; j < polarParams->N; j++) llr[j][polarParams->n][0]=d_tilde[j];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SCL polar decoder.
|
|
||||||
*/
|
|
||||||
uint32_t nonFrozenBit=0;
|
|
||||||
uint8_t currentListSize=1;
|
|
||||||
uint8_t decoderIterationCheck=0;
|
|
||||||
int16_t checkCrcBits=-1;
|
|
||||||
uint8_t listIndex[2*listSize], copyIndex;
|
|
||||||
|
|
||||||
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
|
|
||||||
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
|
|
||||||
|
|
||||||
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
|
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
|
|
||||||
} else { //Information or CRC bit.
|
|
||||||
if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) &&
|
|
||||||
(aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) {
|
|
||||||
//Information bit with known value of "0".
|
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr);
|
|
||||||
bitUpdated[currentBit][0]=1; //0=False, 1=True
|
|
||||||
} else if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) &&
|
|
||||||
(aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) {
|
|
||||||
//Information bit with known value of "1".
|
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr);
|
|
||||||
|
|
||||||
for (uint8_t i=0; i<currentListSize; i++) bit[currentBit][0][i]=1;
|
|
||||||
|
|
||||||
bitUpdated[currentBit][0]=1;
|
|
||||||
updateCrcChecksum(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
|
||||||
} else {
|
|
||||||
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
|
|
||||||
|
|
||||||
for (int i = 0; i < currentListSize; i++) {
|
|
||||||
for (int j = 0; j < polarParams->N; j++) {
|
|
||||||
for (int k = 0; k < (polarParams->n+1); k++) {
|
|
||||||
bit[j][k][i+currentListSize]=bit[j][k][i];
|
|
||||||
llr[j][k][i+currentListSize]=llr[j][k][i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < currentListSize; i++) {
|
|
||||||
bit[currentBit][0][i]=0;
|
|
||||||
crcState[i+currentListSize]=crcState[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1;
|
|
||||||
|
|
||||||
bitUpdated[currentBit][0]=1;
|
|
||||||
updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
|
||||||
currentListSize*=2;
|
|
||||||
|
|
||||||
//Keep only the best "listSize" number of entries.
|
|
||||||
if (currentListSize > listSize) {
|
|
||||||
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
|
|
||||||
|
|
||||||
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
|
|
||||||
//sort listIndex[listSize, ..., 2*listSize-1] in descending order.
|
|
||||||
uint8_t swaps, tempInd;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < listSize; i++) {
|
|
||||||
swaps = 0;
|
|
||||||
|
|
||||||
for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
|
|
||||||
if (listIndex[j+1] > listIndex[j]) {
|
|
||||||
tempInd = listIndex[j];
|
|
||||||
listIndex[j] = listIndex[j + 1];
|
|
||||||
listIndex[j + 1] = tempInd;
|
|
||||||
swaps++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (swaps == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//First, backup the best "listSize" number of entries.
|
|
||||||
for (int k=(listSize-1); k>0; k--) {
|
|
||||||
for (int i=0; i<polarParams->N; i++) {
|
|
||||||
for (int j=0; j<(polarParams->n+1); j++) {
|
|
||||||
bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]];
|
|
||||||
llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int k=(listSize-1); k>0; k--) {
|
|
||||||
for (int i = 0; i < polarParams->crcParityBits; i++) {
|
|
||||||
crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int k=(listSize-1); k>0; k--) crcState[listIndex[(2*listSize-1)-k]]=crcState[listIndex[k]];
|
|
||||||
|
|
||||||
//Copy the best "listSize" number of entries to the first indices.
|
|
||||||
for (int k = 0; k < listSize; k++) {
|
|
||||||
if (k > listIndex[k]) {
|
|
||||||
copyIndex = listIndex[(2*listSize-1)-k];
|
|
||||||
} else { //Use the backup.
|
|
||||||
copyIndex = listIndex[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < polarParams->N; i++) {
|
|
||||||
for (int j = 0; j < (polarParams->n + 1); j++) {
|
|
||||||
bit[i][j][k] = bit[i][j][copyIndex];
|
|
||||||
llr[i][j][k] = llr[i][j][copyIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int k = 0; k < listSize; k++) {
|
|
||||||
if (k > listIndex[k]) {
|
|
||||||
copyIndex = listIndex[(2*listSize-1)-k];
|
|
||||||
} else { //Use the backup.
|
|
||||||
copyIndex = listIndex[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < polarParams->crcParityBits; i++) {
|
|
||||||
crcChecksum[i][k]=crcChecksum[i][copyIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int k = 0; k < listSize; k++) {
|
|
||||||
if (k > listIndex[k]) {
|
|
||||||
copyIndex = listIndex[(2*listSize-1)-k];
|
|
||||||
} else { //Use the backup.
|
|
||||||
copyIndex = listIndex[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
crcState[k]=crcState[copyIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
currentListSize = listSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<polarParams->crcParityBits; i++) {
|
|
||||||
if (last1ind[i]==nonFrozenBit) {
|
|
||||||
checkCrcBits=i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( checkCrcBits > (-1) ) {
|
|
||||||
for (uint8_t i = 0; i < currentListSize; i++) {
|
|
||||||
if (crcChecksum[checkCrcBits][i]==1) {
|
|
||||||
crcState[i]=0; //0=False, 1=True
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i];
|
|
||||||
|
|
||||||
if (decoderIterationCheck==0) {
|
|
||||||
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
|
|
||||||
free(d_tilde);
|
|
||||||
free(pathMetric);
|
|
||||||
free(crcState);
|
|
||||||
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
|
|
||||||
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
|
|
||||||
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
nonFrozenBit++;
|
|
||||||
decoderIterationCheck=0;
|
|
||||||
checkCrcBits=-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
|
|
||||||
|
|
||||||
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
|
|
||||||
if ( crcState[listIndex[i]] == 1 ) {
|
|
||||||
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]];
|
|
||||||
|
|
||||||
//Extract the information bits (û to ĉ)
|
|
||||||
nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
|
|
||||||
//Deinterleaving (ĉ to b)
|
|
||||||
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
|
|
||||||
|
|
||||||
//Remove the CRC (â)
|
|
||||||
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(d_tilde);
|
|
||||||
free(pathMetric);
|
|
||||||
free(crcState);
|
|
||||||
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
|
|
||||||
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
|
|
||||||
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
|
|
||||||
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K);
|
|
||||||
nr_free_uint8_2D_array(tempECGM, polarParams->K);
|
|
||||||
/*
|
|
||||||
* Return bits.
|
|
||||||
*/
|
|
||||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int8_t polar_decoder_dci(double *input,
|
int8_t polar_decoder_dci(double *input,
|
||||||
uint32_t *out,
|
uint32_t *out,
|
||||||
t_nrPolar_params *polarParams,
|
t_nrPolar_params *polarParams,
|
||||||
uint8_t listSize,
|
uint8_t listSize,
|
||||||
uint8_t pathMetricAppr,
|
|
||||||
uint16_t n_RNTI) {
|
uint16_t n_RNTI) {
|
||||||
uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
|
uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
|
||||||
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
||||||
@@ -941,12 +387,12 @@ int8_t polar_decoder_dci(double *input,
|
|||||||
uint8_t listIndex[2*listSize], copyIndex;
|
uint8_t listIndex[2*listSize], copyIndex;
|
||||||
|
|
||||||
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
|
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
|
||||||
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
|
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1));
|
||||||
|
|
||||||
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
|
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
|
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit);
|
||||||
} else { //Information or CRC bit.
|
} else { //Information or CRC bit.
|
||||||
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
|
updatePathMetric2(pathMetric, llr, currentListSize, currentBit);
|
||||||
|
|
||||||
for (int i = 0; i < currentListSize; i++) {
|
for (int i = 0; i < currentListSize; i++) {
|
||||||
for (int j = 0; j < polarParams->N; j++) {
|
for (int j = 0; j < polarParams->N; j++) {
|
||||||
@@ -1116,7 +562,7 @@ int8_t polar_decoder_dci(double *input,
|
|||||||
/*
|
/*
|
||||||
* Return bits.
|
* Return bits.
|
||||||
*/
|
*/
|
||||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
|
nr_byte2bit_uint8_32(polarParams->nr_polar_A, polarParams->payloadBits, out);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,27 +37,26 @@
|
|||||||
//#define DEBUG_NEW_IMPL 1
|
//#define DEBUG_NEW_IMPL 1
|
||||||
|
|
||||||
void updateLLR(double ***llr,
|
void updateLLR(double ***llr,
|
||||||
uint8_t **llrU,
|
uint8_t **llrU,
|
||||||
uint8_t ***bit,
|
uint8_t ***bit,
|
||||||
uint8_t **bitU,
|
uint8_t **bitU,
|
||||||
uint8_t listSize,
|
uint8_t listSize,
|
||||||
uint16_t row,
|
uint16_t row,
|
||||||
uint16_t col,
|
uint16_t col,
|
||||||
uint16_t xlen,
|
uint16_t xlen,
|
||||||
uint8_t ylen,
|
uint8_t ylen)
|
||||||
uint8_t approximation)
|
|
||||||
{
|
{
|
||||||
uint16_t offset = (xlen/(pow(2,(ylen-col-1))));
|
uint16_t offset = (xlen/(pow(2,(ylen-col-1))));
|
||||||
for (uint8_t i=0; i<listSize; i++) {
|
for (uint8_t i=0; i<listSize; i++) {
|
||||||
if (( (row) % (2*offset) ) >= offset ) {
|
if (( (row) % (2*offset) ) >= offset ) {
|
||||||
if(bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen);
|
if(bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen);
|
||||||
if(llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation);
|
if(llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen);
|
||||||
if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation);
|
if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen);
|
||||||
llr[row][col][i] = (pow((-1),bit[row-offset][col][i])*llr[row-offset][col+1][i]) + llr[row][col+1][i];
|
llr[row][col][i] = (pow((-1),bit[row-offset][col][i])*llr[row-offset][col+1][i]) + llr[row][col+1][i];
|
||||||
} else {
|
} else {
|
||||||
if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation);
|
if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen);
|
||||||
if(llrU[row+offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
|
if(llrU[row+offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen);
|
||||||
computeLLR(llr, row, col, i, offset, approximation);
|
computeLLR(llr, row, col, i, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
llrU[row][col]=1;
|
llrU[row][col]=1;
|
||||||
@@ -73,7 +72,6 @@ void updateBit(uint8_t ***bit,
|
|||||||
uint16_t xlen,
|
uint16_t xlen,
|
||||||
uint8_t ylen)
|
uint8_t ylen)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
|
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
|
||||||
|
|
||||||
for (uint8_t i=0; i<listSize; i++) {
|
for (uint8_t i=0; i<listSize; i++) {
|
||||||
@@ -91,78 +89,47 @@ void updateBit(uint8_t ***bit,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updatePathMetric(double *pathMetric,
|
void updatePathMetric(double *pathMetric,
|
||||||
double ***llr,
|
double ***llr,
|
||||||
uint8_t listSize,
|
uint8_t listSize,
|
||||||
uint8_t bitValue,
|
uint8_t bitValue,
|
||||||
uint16_t row,
|
uint16_t row)
|
||||||
uint8_t approximation)
|
|
||||||
{
|
{
|
||||||
if (approximation) { //eq. (12)
|
int8_t multiplier = (2*bitValue) - 1;
|
||||||
for (uint8_t i=0; i<listSize; i++) {
|
for (uint8_t i=0; i<listSize; i++)
|
||||||
if ((2*bitValue) != ( 1 - copysign(1.0,llr[row][0][i]) )) pathMetric[i] += fabs(llr[row][0][i]);
|
pathMetric[i] += log ( 1 + exp(multiplier*llr[row][0][i]) ) ; //eq. (11b)
|
||||||
}
|
|
||||||
} else { //eq. (11b)
|
|
||||||
int8_t multiplier = (2*bitValue) - 1;
|
|
||||||
for (uint8_t i=0; i<listSize; i++) pathMetric[i] += log ( 1 + exp(multiplier*llr[row][0][i]) ) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void updatePathMetric2(double *pathMetric,
|
void updatePathMetric2(double *pathMetric,
|
||||||
double ***llr,
|
double ***llr,
|
||||||
uint8_t listSize,
|
uint8_t listSize,
|
||||||
uint16_t row,
|
uint16_t row)
|
||||||
uint8_t appr)
|
|
||||||
{
|
{
|
||||||
double *tempPM = malloc(sizeof(double) * listSize);
|
double *tempPM = malloc(sizeof(double) * listSize);
|
||||||
for (int i=0; i < listSize; i++) tempPM[i]=pathMetric[i];
|
memcpy(tempPM, pathMetric, (sizeof(double) * listSize));
|
||||||
|
|
||||||
|
|
||||||
uint8_t bitValue = 0;
|
uint8_t bitValue = 0;
|
||||||
if (appr) { //eq. (12)
|
int8_t multiplier = (2 * bitValue) - 1;
|
||||||
for (uint8_t i = 0; i < listSize; i++) {
|
for (uint8_t i = 0; i < listSize; i++)
|
||||||
if ((2 * bitValue) != (1 - copysign(1.0, llr[row][0][i]))) pathMetric[i] += fabs(llr[row][0][i]);
|
pathMetric[i] += log(1 + exp(multiplier * llr[row][0][i])); //eq. (11b)
|
||||||
}
|
|
||||||
} else { //eq. (11b)
|
|
||||||
int8_t multiplier = (2 * bitValue) - 1;
|
|
||||||
for (uint8_t i = 0; i < listSize; i++) pathMetric[i] += log(1 + exp(multiplier * llr[row][0][i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
bitValue = 1;
|
bitValue = 1;
|
||||||
if (appr) { //eq. (12)
|
multiplier = (2 * bitValue) - 1;
|
||||||
for (uint8_t i = listSize; i < 2*listSize; i++) {
|
for (uint8_t i = listSize; i < 2*listSize; i++)
|
||||||
if ((2 * bitValue) != (1 - copysign(1.0, llr[row][0][(i-listSize)]))) pathMetric[i] = tempPM[(i-listSize)] + fabs(llr[row][0][(i-listSize)]);
|
pathMetric[i] = tempPM[(i-listSize)] + log(1 + exp(multiplier * llr[row][0][(i-listSize)])); //eq. (11b)
|
||||||
}
|
|
||||||
} else { //eq. (11b)
|
|
||||||
int8_t multiplier = (2 * bitValue) - 1;
|
|
||||||
for (uint8_t i = listSize; i < 2*listSize; i++) pathMetric[i] = tempPM[(i-listSize)] + log(1 + exp(multiplier * llr[row][0][(i-listSize)]));
|
|
||||||
}
|
|
||||||
|
|
||||||
free(tempPM);
|
free(tempPM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void computeLLR(double ***llr,
|
void computeLLR(double ***llr,
|
||||||
uint16_t row,
|
uint16_t row,
|
||||||
uint16_t col,
|
uint16_t col,
|
||||||
uint8_t i,
|
uint8_t i,
|
||||||
uint16_t offset,
|
uint16_t offset)
|
||||||
uint8_t approximation)
|
|
||||||
{
|
{
|
||||||
double a = llr[row][col + 1][i];
|
double a = llr[row][col + 1][i];
|
||||||
double absA = fabs(a);
|
|
||||||
double b = llr[row + offset][col + 1][i];
|
double b = llr[row + offset][col + 1][i];
|
||||||
double absB = fabs(b);
|
llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b))); //eq. (8a)
|
||||||
|
|
||||||
if (approximation || isinf(absA) || isinf(absB)) { //eq. (9)
|
|
||||||
llr[row][col][i] = copysign(1.0, a) * copysign(1.0, b) * fmin(absA, absB);
|
|
||||||
} else { //eq. (8a)
|
|
||||||
llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateCrcChecksum(uint8_t **crcChecksum,
|
void updateCrcChecksum(uint8_t **crcChecksum,
|
||||||
@@ -193,7 +160,7 @@ void updateCrcChecksum2(uint8_t **crcChecksum,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
decoder_node_t *new_decoder_node(int first_leaf_index,int level) {
|
decoder_node_t *new_decoder_node(int first_leaf_index, int level) {
|
||||||
|
|
||||||
decoder_node_t *node=(decoder_node_t *)malloc(sizeof(decoder_node_t));
|
decoder_node_t *node=(decoder_node_t *)malloc(sizeof(decoder_node_t));
|
||||||
|
|
||||||
@@ -208,32 +175,34 @@ decoder_node_t *new_decoder_node(int first_leaf_index,int level) {
|
|||||||
node->beta = (int16_t*)malloc16(node->Nv*sizeof(int16_t));
|
node->beta = (int16_t*)malloc16(node->Nv*sizeof(int16_t));
|
||||||
memset((void*)node->beta,-1,node->Nv*sizeof(int16_t));
|
memset((void*)node->beta,-1,node->Nv*sizeof(int16_t));
|
||||||
|
|
||||||
|
|
||||||
return(node);
|
return(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder_node_t *add_nodes(int level,int first_leaf_index,t_nrPolar_params *pp) {
|
decoder_node_t *add_nodes(int level, int first_leaf_index, t_nrPolar_params *polarParams) {
|
||||||
|
|
||||||
int all_frozen_below=1;
|
int all_frozen_below = 1;
|
||||||
int Nv = 1<<level;
|
int Nv = 1<<level;
|
||||||
decoder_node_t *new_node = new_decoder_node(first_leaf_index,level);
|
decoder_node_t *new_node = new_decoder_node(first_leaf_index, level);
|
||||||
#ifdef DEBUG_NEW_IMPL
|
#ifdef DEBUG_NEW_IMPL
|
||||||
printf("New node %d order %d, level %d\n",pp->tree.num_nodes,Nv,level);
|
printf("New node %d order %d, level %d\n",polarParams->tree.num_nodes,Nv,level);
|
||||||
#endif
|
#endif
|
||||||
pp->tree.num_nodes++;
|
polarParams->tree.num_nodes++;
|
||||||
if (level==0) {
|
if (level==0) {
|
||||||
#ifdef DEBUG_NEW_IMPL
|
#ifdef DEBUG_NEW_IMPL
|
||||||
printf("leaf %d (%s)\n",first_leaf_index,pp->information_bit_pattern[first_leaf_index]==1 ? "information or crc" : "frozen");
|
printf("leaf %d (%s)\n", first_leaf_index, polarParams->information_bit_pattern[first_leaf_index]==1 ? "information or crc" : "frozen");
|
||||||
#endif
|
#endif
|
||||||
new_node->leaf=1;
|
new_node->leaf=1;
|
||||||
new_node->all_frozen = pp->information_bit_pattern[first_leaf_index]==0 ? 1 : 0;
|
new_node->all_frozen = polarParams->information_bit_pattern[first_leaf_index]==0 ? 1 : 0;
|
||||||
return new_node; // this is a leaf node
|
return new_node; // this is a leaf node
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<Nv;i++) {
|
for (int i=0;i<Nv;i++) {
|
||||||
if (pp->information_bit_pattern[i+first_leaf_index]>0) all_frozen_below=0;
|
if (polarParams->information_bit_pattern[i+first_leaf_index]>0)
|
||||||
|
all_frozen_below=0;
|
||||||
}
|
}
|
||||||
if (all_frozen_below==0) new_node->left=add_nodes(level-1,first_leaf_index,pp);
|
|
||||||
|
if (all_frozen_below==0)
|
||||||
|
new_node->left=add_nodes(level-1, first_leaf_index, polarParams);
|
||||||
else {
|
else {
|
||||||
#ifdef DEBUG_NEW_IMPL
|
#ifdef DEBUG_NEW_IMPL
|
||||||
printf("aggregating frozen bits %d ... %d at level %d (%s)\n",first_leaf_index,first_leaf_index+Nv-1,level,((first_leaf_index/Nv)&1)==0?"left":"right");
|
printf("aggregating frozen bits %d ... %d at level %d (%s)\n",first_leaf_index,first_leaf_index+Nv-1,level,((first_leaf_index/Nv)&1)==0?"left":"right");
|
||||||
@@ -241,21 +210,22 @@ decoder_node_t *add_nodes(int level,int first_leaf_index,t_nrPolar_params *pp) {
|
|||||||
new_node->leaf=1;
|
new_node->leaf=1;
|
||||||
new_node->all_frozen=1;
|
new_node->all_frozen=1;
|
||||||
}
|
}
|
||||||
if (all_frozen_below==0) new_node->right=add_nodes(level-1,first_leaf_index+(Nv/2),pp);
|
if (all_frozen_below==0)
|
||||||
|
new_node->right=add_nodes(level-1,first_leaf_index+(Nv/2),polarParams);
|
||||||
|
|
||||||
#ifdef DEBUG_NEW_IMPL
|
#ifdef DEBUG_NEW_IMPL
|
||||||
printf("new_node (%d): first_leaf_index %d, left %p, right %p\n",Nv,first_leaf_index,new_node->left,new_node->right);
|
printf("new_node (%d): first_leaf_index %d, left %p, right %p\n",Nv,first_leaf_index,new_node->left,new_node->right);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return(new_node);
|
return(new_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void build_decoder_tree(t_nrPolar_params *polarParams)
|
||||||
void build_decoder_tree(t_nrPolar_params *pp) {
|
{
|
||||||
|
polarParams->tree.num_nodes=0;
|
||||||
pp->tree.num_nodes=0;
|
polarParams->tree.root = add_nodes(polarParams->n,0,polarParams);
|
||||||
pp->tree.root = add_nodes(pp->n,0,pp);
|
|
||||||
#ifdef DEBUG_NEW_IMPL
|
#ifdef DEBUG_NEW_IMPL
|
||||||
printf("root : left %p, right %p\n",pp->tree.root->left,pp->tree.root->right);
|
printf("root : left %p, right %p\n",polarParams->tree.root->left,polarParams->tree.root->right);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +241,7 @@ void build_decoder_tree(t_nrPolar_params *pp) {
|
|||||||
#define _mm_subs_pi16(a,b) vsub_s16(a,b)
|
#define _mm_subs_pi16(a,b) vsub_s16(a,b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) {
|
void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node) {
|
||||||
int16_t *alpha_v=node->alpha;
|
int16_t *alpha_v=node->alpha;
|
||||||
int16_t *alpha_l=node->left->alpha;
|
int16_t *alpha_l=node->left->alpha;
|
||||||
int16_t *betal = node->left->beta;
|
int16_t *betal = node->left->beta;
|
||||||
@@ -368,18 +338,18 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) {
|
|||||||
|
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{ // equvalent scalar code to above, activated only on non x86/ARM architectures
|
{ // equivalent scalar code to above, activated only on non x86/ARM architectures
|
||||||
for (int i=0;i<node->Nv/2;i++) {
|
for (int i=0;i<node->Nv/2;i++) {
|
||||||
a=alpha_v[i];
|
a=alpha_v[i];
|
||||||
b=alpha_v[i+(node->Nv/2)];
|
b=alpha_v[i+(node->Nv/2)];
|
||||||
maska=a>>15;
|
maska=a>>15;
|
||||||
maskb=b>>15;
|
maskb=b>>15;
|
||||||
absa=(a+maska)^maska;
|
absa=(a+maska)^maska;
|
||||||
absb=(b+maskb)^maskb;
|
absb=(b+maskb)^maskb;
|
||||||
minabs = absa<absb ? absa : absb;
|
minabs = absa<absb ? absa : absb;
|
||||||
alpha_l[i] = (maska^maskb)==0 ? minabs : -minabs;
|
alpha_l[i] = (maska^maskb)==0 ? minabs : -minabs;
|
||||||
// printf("alphal[%d] %d (%d,%d)\n",i,alpha_l[i],a,b);
|
// printf("alphal[%d] %d (%d,%d)\n",i,alpha_l[i],a,b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node->Nv == 2) { // apply hard decision on left node
|
if (node->Nv == 2) { // apply hard decision on left node
|
||||||
betal[0] = (alpha_l[0]>0) ? -1 : 1;
|
betal[0] = (alpha_l[0]>0) ? -1 : 1;
|
||||||
@@ -394,7 +364,7 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) {
|
void applyGtoright(const t_nrPolar_params *pp,decoder_node_t *node) {
|
||||||
|
|
||||||
int16_t *alpha_v=node->alpha;
|
int16_t *alpha_v=node->alpha;
|
||||||
int16_t *alpha_r=node->right->alpha;
|
int16_t *alpha_r=node->right->alpha;
|
||||||
@@ -448,7 +418,7 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{// equvalent scalar code to above, activated only on non x86/ARM architectures or Nv=1,2
|
{// equivalent scalar code to above, activated only on non x86/ARM architectures or Nv=1,2
|
||||||
for (int i=0;i<node->Nv/2;i++) {
|
for (int i=0;i<node->Nv/2;i++) {
|
||||||
alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]);
|
alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]);
|
||||||
}
|
}
|
||||||
@@ -463,13 +433,9 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16_t all1[16] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
|
||||||
|
|
||||||
int16_t all1[16] = {1,1,1,1,
|
void computeBeta(const t_nrPolar_params *pp,decoder_node_t *node) {
|
||||||
1,1,1,1,
|
|
||||||
1,1,1,1,
|
|
||||||
1,1,1,1};
|
|
||||||
|
|
||||||
void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) {
|
|
||||||
|
|
||||||
int16_t *betav = node->beta;
|
int16_t *betav = node->beta;
|
||||||
int16_t *betal = node->left->beta;
|
int16_t *betal = node->left->beta;
|
||||||
@@ -504,38 +470,37 @@ void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) {
|
|||||||
int ssr4len = node->Nv/2/8;
|
int ssr4len = node->Nv/2/8;
|
||||||
register __m128i allones=*((__m128i*)all1);
|
register __m128i allones=*((__m128i*)all1);
|
||||||
for (int i=0;i<sse4len;i++) {
|
for (int i=0;i<sse4len;i++) {
|
||||||
((__m256i*)betav)[i] = _mm_or_si128(_mm_cmpeq_epi16(((__m128i*)betar)[i],
|
((__m256i*)betav)[i] = _mm_or_si128(_mm_cmpeq_epi16(((__m128i*)betar)[i], ((__m128i*)betal)[i]),allones));
|
||||||
((__m128i*)betal)[i]),allones));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sse4mod == 4) {
|
else if (sse4mod == 4) {
|
||||||
((__m64*)betav)[0] = _mm_or_si64(_mm_cmpeq_pi16(((__m64*)betar)[0],
|
((__m64*)betav)[0] = _mm_or_si64(_mm_cmpeq_pi16(((__m64*)betar)[0], ((__m64*)betal)[0]),*((__m64*)all1));
|
||||||
((__m64*)betal)[0]),*((__m64*)all1));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
for (int i=0;i<node->Nv/2;i++) {
|
for (int i=0;i<node->Nv/2;i++) {
|
||||||
betav[i] = (betal[i] != betar[i]) ? 1 : -1;
|
betav[i] = (betal[i] != betar[i]) ? 1 : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else memcpy((void*)&betav[0],betar,(node->Nv/2)*sizeof(int16_t));
|
else memcpy((void*)&betav[0],betar,(node->Nv/2)*sizeof(int16_t));
|
||||||
memcpy((void*)&betav[node->Nv/2],betar,(node->Nv/2)*sizeof(int16_t));
|
memcpy((void*)&betav[node->Nv/2],betar,(node->Nv/2)*sizeof(int16_t));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_polar_decoder(t_nrPolar_params *pp,decoder_node_t *node) {
|
void generic_polar_decoder(const t_nrPolar_params *pp,decoder_node_t *node) {
|
||||||
|
|
||||||
|
|
||||||
// Apply F to left
|
// Apply F to left
|
||||||
applyFtoleft(pp,node);
|
applyFtoleft(pp, node);
|
||||||
// if left is not a leaf recurse down to the left
|
// if left is not a leaf recurse down to the left
|
||||||
if (node->left->leaf==0) generic_polar_decoder(pp,node->left);
|
if (node->left->leaf==0)
|
||||||
|
generic_polar_decoder(pp, node->left);
|
||||||
|
|
||||||
applyGtoright(pp,node);
|
applyGtoright(pp, node);
|
||||||
if (node->right->leaf==0) generic_polar_decoder(pp,node->right);
|
if (node->right->leaf==0) generic_polar_decoder(pp, node->right);
|
||||||
|
|
||||||
computeBeta(pp,node);
|
computeBeta(pp, node);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,11 +21,11 @@
|
|||||||
|
|
||||||
/*!\file PHY/CODING/nrPolar_tools/nr_polar_defs.h
|
/*!\file PHY/CODING/nrPolar_tools/nr_polar_defs.h
|
||||||
* \brief
|
* \brief
|
||||||
* \author Turker Yilmaz
|
* \author Raymond Knopp, Turker Yilmaz
|
||||||
* \date 2018
|
* \date 2018
|
||||||
* \version 0.1
|
* \version 0.1
|
||||||
* \company EURECOM
|
* \company EURECOM
|
||||||
* \email turker.yilmaz@eurecom.fr
|
* \email raymond.knopp@eurecom.fr, turker.yilmaz@eurecom.fr
|
||||||
* \note
|
* \note
|
||||||
* \warning
|
* \warning
|
||||||
*/
|
*/
|
||||||
@@ -46,7 +46,6 @@
|
|||||||
//#include "SIMULATION/TOOLS/sim.h"
|
//#include "SIMULATION/TOOLS/sim.h"
|
||||||
|
|
||||||
#define NR_POLAR_DECODER_LISTSIZE 8 //uint8_t
|
#define NR_POLAR_DECODER_LISTSIZE 8 //uint8_t
|
||||||
#define NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION 0 //uint8_t; 0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12)
|
|
||||||
|
|
||||||
#define NR_POLAR_AGGREGATION_LEVEL_1_PRIME 149 //uint16_t
|
#define NR_POLAR_AGGREGATION_LEVEL_1_PRIME 149 //uint16_t
|
||||||
#define NR_POLAR_AGGREGATION_LEVEL_2_PRIME 151 //uint16_t
|
#define NR_POLAR_AGGREGATION_LEVEL_2_PRIME 151 //uint16_t
|
||||||
@@ -54,12 +53,13 @@
|
|||||||
#define NR_POLAR_AGGREGATION_LEVEL_8_PRIME 163 //uint16_t
|
#define NR_POLAR_AGGREGATION_LEVEL_8_PRIME 163 //uint16_t
|
||||||
#define NR_POLAR_AGGREGATION_LEVEL_16_PRIME 167 //uint16_t
|
#define NR_POLAR_AGGREGATION_LEVEL_16_PRIME 167 //uint16_t
|
||||||
|
|
||||||
static const uint8_t nr_polar_subblock_interleaver_pattern[32] = { 0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31 };
|
static const uint8_t nr_polar_subblock_interleaver_pattern[32] = {0,1,2,4,3,5,6,7,8,16,9,17,10,18,11,19,12,20,13,21,14,22,15,23,24,25,26,28,27,29,30,31};
|
||||||
|
|
||||||
|
|
||||||
#define Nmax 1024
|
#define Nmax 1024
|
||||||
#define nmax 10
|
#define nmax 10
|
||||||
|
|
||||||
|
#define uint128_t __uint128_t
|
||||||
|
|
||||||
typedef struct decoder_node_t_s {
|
typedef struct decoder_node_t_s {
|
||||||
struct decoder_node_t_s *left;
|
struct decoder_node_t_s *left;
|
||||||
struct decoder_node_t_s *right;
|
struct decoder_node_t_s *right;
|
||||||
@@ -106,18 +106,17 @@ struct nrPolar_params {
|
|||||||
int16_t *Q_PC_N;
|
int16_t *Q_PC_N;
|
||||||
uint8_t *information_bit_pattern;
|
uint8_t *information_bit_pattern;
|
||||||
uint16_t *channel_interleaver_pattern;
|
uint16_t *channel_interleaver_pattern;
|
||||||
uint32_t crc_polynomial;
|
//uint32_t crc_polynomial;
|
||||||
|
|
||||||
uint8_t **crc_generator_matrix; //G_P
|
uint8_t **crc_generator_matrix; //G_P
|
||||||
uint8_t **G_N;
|
uint8_t **G_N;
|
||||||
uint64_t **G_N_tab;
|
uint64_t **G_N_tab;
|
||||||
int groupsize;
|
int groupsize;
|
||||||
int *rm_tab;
|
int *rm_tab;
|
||||||
uint64_t cprime_tab0[32][256];
|
uint64_t cprime_tab0[32][256];
|
||||||
uint64_t cprime_tab1[32][256];
|
uint64_t cprime_tab1[32][256];
|
||||||
uint64_t B_tab0[32][256];
|
uint64_t B_tab0[32][256];
|
||||||
uint64_t B_tab1[32][256];
|
uint64_t B_tab1[32][256];
|
||||||
uint32_t *crc256Table;
|
|
||||||
uint8_t **extended_crc_generator_matrix;
|
uint8_t **extended_crc_generator_matrix;
|
||||||
//lowercase: bits, Uppercase: Bits stored in bytes
|
//lowercase: bits, Uppercase: Bits stored in bytes
|
||||||
//polar_encoder vectors
|
//polar_encoder vectors
|
||||||
@@ -152,40 +151,31 @@ void polar_encoder_fast(uint64_t *A,
|
|||||||
t_nrPolar_params *polarParams);
|
t_nrPolar_params *polarParams);
|
||||||
|
|
||||||
int8_t polar_decoder(double *input,
|
int8_t polar_decoder(double *input,
|
||||||
uint8_t *output,
|
uint32_t *output,
|
||||||
t_nrPolar_params *polarParams,
|
t_nrPolar_params *polarParams,
|
||||||
uint8_t listSize,
|
uint8_t listSize);
|
||||||
uint8_t pathMetricAppr);
|
|
||||||
|
|
||||||
uint32_t polar_decoder_int16(int16_t *input,
|
uint32_t polar_decoder_int16(int16_t *input,
|
||||||
uint64_t *out,
|
uint64_t *out,
|
||||||
const t_nrPolar_params *polarParams);
|
const t_nrPolar_params *polarParams);
|
||||||
|
|
||||||
int8_t polar_decoder_aPriori(double *input,
|
|
||||||
uint32_t *output,
|
|
||||||
t_nrPolar_params *polarParams,
|
|
||||||
uint8_t listSize,
|
|
||||||
uint8_t pathMetricAppr,
|
|
||||||
double *aPrioriPayload);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
int8_t polar_decoder_dci(double *input,
|
int8_t polar_decoder_dci(double *input,
|
||||||
uint32_t *out,
|
uint32_t *out,
|
||||||
t_nrPolar_params *polarParams,
|
t_nrPolar_params *polarParams,
|
||||||
uint8_t listSize,
|
uint8_t listSize,
|
||||||
uint8_t pathMetricAppr,
|
|
||||||
uint16_t n_RNTI);
|
uint16_t n_RNTI);
|
||||||
|
|
||||||
void generic_polar_decoder(t_nrPolar_params *,
|
void generic_polar_decoder(const t_nrPolar_params *pp,
|
||||||
decoder_node_t *);
|
decoder_node_t *node);
|
||||||
|
|
||||||
|
void applyFtoleft(const t_nrPolar_params *pp,
|
||||||
|
decoder_node_t *node);
|
||||||
|
|
||||||
|
void applyGtoright(const t_nrPolar_params *pp,
|
||||||
|
decoder_node_t *node);
|
||||||
|
|
||||||
|
void computeBeta(const t_nrPolar_params *pp,
|
||||||
|
decoder_node_t *node);
|
||||||
|
|
||||||
void build_decoder_tree(t_nrPolar_params *pp);
|
void build_decoder_tree(t_nrPolar_params *pp);
|
||||||
void build_polar_tables(t_nrPolar_params *polarParams);
|
void build_polar_tables(t_nrPolar_params *polarParams);
|
||||||
@@ -193,9 +183,9 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams);
|
|||||||
|
|
||||||
void nr_polar_print_polarParams(t_nrPolar_params *polarParams);
|
void nr_polar_print_polarParams(t_nrPolar_params *polarParams);
|
||||||
|
|
||||||
t_nrPolar_params *nr_polar_params ( int8_t messageType,
|
t_nrPolar_params *nr_polar_params (int8_t messageType,
|
||||||
uint16_t messageLength,
|
uint16_t messageLength,
|
||||||
uint8_t aggregation_level);
|
uint8_t aggregation_level);
|
||||||
|
|
||||||
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level);
|
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level);
|
||||||
|
|
||||||
@@ -256,17 +246,19 @@ void nr_polar_info_bit_extraction(uint8_t *input,
|
|||||||
uint8_t *pattern,
|
uint8_t *pattern,
|
||||||
uint16_t size);
|
uint16_t size);
|
||||||
|
|
||||||
void nr_bit2byte_uint32_8_t(uint32_t *in,
|
void nr_bit2byte_uint32_8(uint32_t *in,
|
||||||
uint16_t arraySize,
|
uint16_t arraySize,
|
||||||
uint8_t *out);
|
uint8_t *out);
|
||||||
|
|
||||||
void nr_byte2bit_uint8_32_t(uint8_t *in,
|
void nr_byte2bit_uint8_32(uint8_t *in,
|
||||||
uint16_t arraySize,
|
uint16_t arraySize,
|
||||||
uint32_t *out);
|
uint32_t *out);
|
||||||
|
|
||||||
void nr_crc_bit2bit_uint32_8_t(uint32_t *in,
|
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
|
||||||
uint16_t arraySize,
|
|
||||||
uint8_t *out);
|
uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits);
|
||||||
|
|
||||||
|
uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits);
|
||||||
|
|
||||||
void nr_polar_bit_insertion(uint8_t *input,
|
void nr_polar_bit_insertion(uint8_t *input,
|
||||||
uint8_t *output,
|
uint8_t *output,
|
||||||
@@ -320,7 +312,6 @@ void nr_sort_asc_int16_1D_array_ind(int32_t *matrix,
|
|||||||
|
|
||||||
void nr_free_double_2D_array(double **input, uint16_t xlen);
|
void nr_free_double_2D_array(double **input, uint16_t xlen);
|
||||||
|
|
||||||
|
|
||||||
void updateLLR(double ***llr,
|
void updateLLR(double ***llr,
|
||||||
uint8_t **llrU,
|
uint8_t **llrU,
|
||||||
uint8_t ***bit,
|
uint8_t ***bit,
|
||||||
@@ -329,8 +320,7 @@ void updateLLR(double ***llr,
|
|||||||
uint16_t row,
|
uint16_t row,
|
||||||
uint16_t col,
|
uint16_t col,
|
||||||
uint16_t xlen,
|
uint16_t xlen,
|
||||||
uint8_t ylen,
|
uint8_t ylen);
|
||||||
uint8_t approximation);
|
|
||||||
|
|
||||||
void updateBit(uint8_t ***bit,
|
void updateBit(uint8_t ***bit,
|
||||||
uint8_t **bitU,
|
uint8_t **bitU,
|
||||||
@@ -344,21 +334,18 @@ void updatePathMetric(double *pathMetric,
|
|||||||
double ***llr,
|
double ***llr,
|
||||||
uint8_t listSize,
|
uint8_t listSize,
|
||||||
uint8_t bitValue,
|
uint8_t bitValue,
|
||||||
uint16_t row,
|
uint16_t row);
|
||||||
uint8_t approximation);
|
|
||||||
|
|
||||||
void updatePathMetric2(double *pathMetric,
|
void updatePathMetric2(double *pathMetric,
|
||||||
double ***llr,
|
double ***llr,
|
||||||
uint8_t listSize,
|
uint8_t listSize,
|
||||||
uint16_t row,
|
uint16_t row);
|
||||||
uint8_t approximation);
|
|
||||||
|
|
||||||
void computeLLR(double ***llr,
|
void computeLLR(double ***llr,
|
||||||
uint16_t row,
|
uint16_t row,
|
||||||
uint16_t col,
|
uint16_t col,
|
||||||
uint8_t i,
|
uint8_t i,
|
||||||
uint16_t offset,
|
uint16_t offset);
|
||||||
uint8_t approximation);
|
|
||||||
|
|
||||||
void updateCrcChecksum(uint8_t **crcChecksum,
|
void updateCrcChecksum(uint8_t **crcChecksum,
|
||||||
uint8_t **crcGen,
|
uint8_t **crcGen,
|
||||||
@@ -372,12 +359,6 @@ void updateCrcChecksum2(uint8_t **crcChecksum,
|
|||||||
uint32_t i2,
|
uint32_t i2,
|
||||||
uint8_t len);
|
uint8_t len);
|
||||||
|
|
||||||
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
|
|
||||||
|
|
||||||
uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits);
|
|
||||||
|
|
||||||
uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits);
|
|
||||||
|
|
||||||
//Also nr_polar_rate_matcher
|
//Also nr_polar_rate_matcher
|
||||||
static inline void nr_polar_interleaver(uint8_t *input,
|
static inline void nr_polar_interleaver(uint8_t *input,
|
||||||
uint8_t *output,
|
uint8_t *output,
|
||||||
@@ -387,14 +368,10 @@ static inline void nr_polar_interleaver(uint8_t *input,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void nr_polar_deinterleaver(uint8_t *input,
|
static inline void nr_polar_deinterleaver(uint8_t *input,
|
||||||
uint8_t *output,
|
uint8_t *output,
|
||||||
uint16_t *pattern,
|
uint16_t *pattern,
|
||||||
uint16_t size) {
|
uint16_t size) {
|
||||||
for (int i=0; i<size; i++) {
|
for (int i=0; i<size; i++) output[pattern[i]]=input[i];
|
||||||
output[pattern[i]]=input[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void build_decoder_tree(t_nrPolar_params *pp);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,10 +32,11 @@
|
|||||||
|
|
||||||
//#define DEBUG_POLAR_ENCODER
|
//#define DEBUG_POLAR_ENCODER
|
||||||
//#define DEBUG_POLAR_ENCODER_DCI
|
//#define DEBUG_POLAR_ENCODER_DCI
|
||||||
//#define DEBUG_POLAR_ENCODER_TIMING
|
//#define DEBUG_POLAR_MATLAB
|
||||||
|
|
||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||||
#include "assertions.h"
|
#include "assertions.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
//input [a_31 a_30 ... a_0]
|
//input [a_31 a_30 ... a_0]
|
||||||
//output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ...
|
//output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ...
|
||||||
@@ -43,23 +44,23 @@
|
|||||||
void polar_encoder(uint32_t *in,
|
void polar_encoder(uint32_t *in,
|
||||||
uint32_t *out,
|
uint32_t *out,
|
||||||
t_nrPolar_params *polarParams) {
|
t_nrPolar_params *polarParams) {
|
||||||
if (polarParams->idx == 0) { //PBCH
|
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);
|
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);
|
printf("polar_B %llx (crc %x)\n",B,crc24c((uint8_t*)in,polarParams->payloadBits)>>8);
|
||||||
#endif
|
#endif
|
||||||
nr_bit2byte_uint32_8_t((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*/
|
nr_bit2byte_uint32_8_t((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*/
|
||||||
nr_bit2byte_uint32_8_t((uint32_t *)in, polarParams->payloadBits, polarParams->nr_polar_A);
|
nr_bit2byte_uint32_8(in, polarParams->payloadBits, polarParams->nr_polar_A);
|
||||||
/*
|
/*
|
||||||
* Bytewise operations
|
* Bytewise operations
|
||||||
*/
|
*/
|
||||||
//Calculate CRC.
|
//Calculate CRC.
|
||||||
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_A,
|
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_A,
|
||||||
polarParams->crc_generator_matrix,
|
polarParams->crc_generator_matrix,
|
||||||
polarParams->nr_polar_crc,
|
polarParams->nr_polar_crc,
|
||||||
polarParams->payloadBits,
|
polarParams->payloadBits,
|
||||||
polarParams->crcParityBits);
|
polarParams->crcParityBits);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < polarParams->crcParityBits; i++)
|
for (uint8_t i = 0; i < polarParams->crcParityBits; i++)
|
||||||
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
|
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
|
||||||
@@ -77,6 +78,8 @@ void polar_encoder(uint32_t *in,
|
|||||||
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);
|
printf("polar_B %llx\n",B2);
|
||||||
|
for (int i=0; i< polarParams->payloadBits; i++) printf("a[%d]=%d\n", i, polarParams->nr_polar_A[i]);
|
||||||
|
for (int i=0; i< polarParams->K; i++) printf("b[%d]=%d\n", i, polarParams->nr_polar_B[i]);
|
||||||
#endif
|
#endif
|
||||||
/* for (int j=0;j<polarParams->crcParityBits;j++) {
|
/* for (int j=0;j<polarParams->crcParityBits;j++) {
|
||||||
for (int i=0;i<polarParams->payloadBits;i++)
|
for (int i=0;i<polarParams->payloadBits;i++)
|
||||||
@@ -115,10 +118,10 @@ void polar_encoder(uint32_t *in,
|
|||||||
polarParams->nr_polar_U[247]=1;
|
polarParams->nr_polar_U[247]=1;
|
||||||
polarParams->nr_polar_U[253]=1;*/
|
polarParams->nr_polar_U[253]=1;*/
|
||||||
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
|
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
|
||||||
polarParams->G_N,
|
polarParams->G_N,
|
||||||
polarParams->nr_polar_D,
|
polarParams->nr_polar_D,
|
||||||
polarParams->N,
|
polarParams->N,
|
||||||
polarParams->N);
|
polarParams->N);
|
||||||
|
|
||||||
for (uint16_t i = 0; i < polarParams->N; i++)
|
for (uint16_t i = 0; i < polarParams->N; i++)
|
||||||
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
|
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
|
||||||
@@ -146,7 +149,7 @@ void polar_encoder(uint32_t *in,
|
|||||||
for (int i=0; i< polarParams->encoderLength; i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
|
for (int i=0; i< polarParams->encoderLength; i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
|
nr_byte2bit_uint8_32(polarParams->nr_polar_E, polarParams->encoderLength, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void polar_encoder_dci(uint32_t *in,
|
void polar_encoder_dci(uint32_t *in,
|
||||||
@@ -160,7 +163,7 @@ void polar_encoder_dci(uint32_t *in,
|
|||||||
* Bytewise operations
|
* Bytewise operations
|
||||||
*/
|
*/
|
||||||
//(a to a')
|
//(a to a')
|
||||||
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_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->crcParityBits; i++) polarParams->nr_polar_APrime[i]=1;
|
||||||
|
|
||||||
@@ -168,35 +171,29 @@ void polar_encoder_dci(uint32_t *in,
|
|||||||
|
|
||||||
#ifdef DEBUG_POLAR_ENCODER_DCI
|
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||||
printf("[polar_encoder_dci] A: ");
|
printf("[polar_encoder_dci] A: ");
|
||||||
|
|
||||||
for (int i=0; i<polarParams->payloadBits; i++) printf("%d-", polarParams->nr_polar_A[i]);
|
for (int i=0; i<polarParams->payloadBits; i++) printf("%d-", polarParams->nr_polar_A[i]);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("[polar_encoder_dci] APrime: ");
|
printf("[polar_encoder_dci] APrime: ");
|
||||||
|
|
||||||
for (int i=0; i<polarParams->K; i++) printf("%d-", polarParams->nr_polar_APrime[i]);
|
for (int i=0; i<polarParams->K; i++) printf("%d-", polarParams->nr_polar_APrime[i]);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("[polar_encoder_dci] GP: ");
|
printf("[polar_encoder_dci] GP: ");
|
||||||
|
|
||||||
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]);
|
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
//Calculate CRC.
|
//Calculate CRC.
|
||||||
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_APrime,
|
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_APrime,
|
||||||
polarParams->crc_generator_matrix,
|
polarParams->crc_generator_matrix,
|
||||||
polarParams->nr_polar_crc,
|
polarParams->nr_polar_crc,
|
||||||
polarParams->K,
|
polarParams->K,
|
||||||
polarParams->crcParityBits);
|
polarParams->crcParityBits);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
|
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
|
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||||
printf("[polar_encoder_dci] CRC: ");
|
printf("[polar_encoder_dci] CRC: ");
|
||||||
|
|
||||||
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]);
|
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -208,55 +205,16 @@ void polar_encoder_dci(uint32_t *in,
|
|||||||
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
|
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
|
||||||
|
|
||||||
//Scrambling (b to c)
|
//Scrambling (b to c)
|
||||||
for (int i=0; i<16; i++) {
|
for (int i=0; i<16; i++)
|
||||||
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
|
polarParams->nr_polar_B[polarParams->payloadBits+8+i]=( polarParams->nr_polar_B[polarParams->payloadBits+8+i] + ((n_RNTI>>(15-i))&1) ) % 2;
|
||||||
( polarParams->nr_polar_B[polarParams->payloadBits+8+i] + ((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
|
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||||
printf("[polar_encoder_dci] B: ");
|
printf("[polar_encoder_dci] B: ");
|
||||||
|
|
||||||
for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]);
|
for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
//Interleaving (c to c')
|
//Interleaving (c to c')
|
||||||
nr_polar_interleaver(polarParams->nr_polar_B,
|
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)
|
//Bit insertion (c' to u)
|
||||||
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
|
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
|
||||||
polarParams->nr_polar_U,
|
polarParams->nr_polar_U,
|
||||||
@@ -267,13 +225,11 @@ void polar_encoder_dci(uint32_t *in,
|
|||||||
polarParams->n_pc);
|
polarParams->n_pc);
|
||||||
//Encoding (u to d)
|
//Encoding (u to d)
|
||||||
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
|
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
|
||||||
polarParams->G_N,
|
polarParams->G_N,
|
||||||
polarParams->nr_polar_D,
|
polarParams->nr_polar_D,
|
||||||
polarParams->N,
|
polarParams->N,
|
||||||
polarParams->N);
|
polarParams->N);
|
||||||
|
for (uint16_t i = 0; i < polarParams->N; i++) polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
|
||||||
for (uint16_t i = 0; i < polarParams->N; i++)
|
|
||||||
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
|
|
||||||
|
|
||||||
//Rate matching
|
//Rate matching
|
||||||
//Sub-block interleaving (d to y) and Bit selection (y to e)
|
//Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||||
@@ -284,28 +240,54 @@ void polar_encoder_dci(uint32_t *in,
|
|||||||
/*
|
/*
|
||||||
* Return bits.
|
* Return bits.
|
||||||
*/
|
*/
|
||||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
|
nr_byte2bit_uint8_32(polarParams->nr_polar_E, polarParams->encoderLength, out);
|
||||||
#ifdef DEBUG_POLAR_ENCODER_DCI
|
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||||
printf("[polar_encoder_dci] E: ");
|
printf("[polar_encoder_dci] E: ");
|
||||||
|
|
||||||
for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]);
|
for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]);
|
||||||
|
|
||||||
uint8_t outputInd = ceil(polarParams->encoderLength / 32.0);
|
uint8_t outputInd = ceil(polarParams->encoderLength / 32.0);
|
||||||
printf("\n[polar_encoder_dci] out: ");
|
printf("\n[polar_encoder_dci] out: ");
|
||||||
|
for (int i = 0; i < outputInd; i++) printf("[%d]->0x%08x\t", i, out[i]);
|
||||||
for (int i = 0; i < outputInd; i++) {
|
|
||||||
printf("[%d]->0x%08x\t", i, out[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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_params *polarParams,void *in,void *out) __attribute__((always_inline));
|
||||||
|
|
||||||
static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,void *out) {
|
static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,void *out) {
|
||||||
if (polarParams->groupsize == 8)
|
|
||||||
|
// 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]];
|
for (int i=0; i<polarParams->encoderLength>>3; i++) ((uint8_t *)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]];
|
||||||
else
|
else // groupsize==16
|
||||||
for (int i=0; i<polarParams->encoderLength>>4; i++) {
|
for (int i=0; i<polarParams->encoderLength>>4; i++) {
|
||||||
((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
|
((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
|
||||||
}
|
}
|
||||||
@@ -342,7 +324,7 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
// 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
|
// 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 *));
|
||||||
@@ -371,14 +353,18 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
|
|||||||
int iplast=polarParams->rate_matching_pattern[0];
|
int iplast=polarParams->rate_matching_pattern[0];
|
||||||
int ccnt=0;
|
int ccnt=0;
|
||||||
int groupcnt=0;
|
int groupcnt=0;
|
||||||
|
#ifdef DEBUG_POLAR_ENCODER
|
||||||
int firstingroup_out=0;
|
int firstingroup_out=0;
|
||||||
int firstingroup_in=iplast;
|
int firstingroup_in=iplast;
|
||||||
|
#endif
|
||||||
int mingroupsize = 1024;
|
int mingroupsize = 1024;
|
||||||
|
|
||||||
// compute minimum group size of rate-matching pattern
|
// compute minimum group size of rate-matching pattern
|
||||||
for (int outpos=1; outpos<polarParams->encoderLength; outpos++) {
|
for (int outpos=1; outpos<polarParams->encoderLength; outpos++) {
|
||||||
ip=polarParams->rate_matching_pattern[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++;
|
if ((ip - iplast) == 1) ccnt++;
|
||||||
else {
|
else {
|
||||||
groupcnt++;
|
groupcnt++;
|
||||||
@@ -391,18 +377,27 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
|
|||||||
if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1;
|
if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1;
|
||||||
|
|
||||||
ccnt=0;
|
ccnt=0;
|
||||||
|
#ifdef DEBUG_POLAR_ENCODER
|
||||||
firstingroup_out=outpos;
|
firstingroup_out=outpos;
|
||||||
firstingroup_in=ip;
|
firstingroup_in=ip;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
iplast=ip;
|
iplast=ip;
|
||||||
}
|
}
|
||||||
|
groupcnt++;
|
||||||
AssertFatal(mingroupsize==8 || mingroupsize==16,"mingroupsize %d, needs to be handled\n",mingroupsize);
|
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;
|
polarParams->groupsize=mingroupsize;
|
||||||
int shift=3;
|
int shift=3;
|
||||||
|
|
||||||
if (mingroupsize == 16) shift=4;
|
if (mingroupsize == 16) shift=4;
|
||||||
|
else if (mingroupsize == 4) shift=2;
|
||||||
|
|
||||||
polarParams->rm_tab=(int *)malloc(sizeof(int)*polarParams->encoderLength/mingroupsize);
|
polarParams->rm_tab=(int *)malloc(sizeof(int)*polarParams->encoderLength/mingroupsize);
|
||||||
// rerun again to create groups
|
// rerun again to create groups
|
||||||
@@ -427,10 +422,11 @@ void polar_encoder_fast(uint64_t *A,
|
|||||||
//int bitlen0=bitlen;
|
//int bitlen0=bitlen;
|
||||||
uint64_t tcrc=0;
|
uint64_t tcrc=0;
|
||||||
|
|
||||||
// A bitstring should be stored as a_{N-1} a_{N-2} ... a_{N-A} 0 .... 0, where N=64,128,192,..., N is smallest multiple of 64 greater than or equal to A
|
// A bit string should be stored as 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1,
|
||||||
|
//???a'_{N-1} a'_{N-2} ... a'_{N-A} 0 .... 0, where N=64,128,192,..., N is smallest multiple of 64 greater than or equal to A
|
||||||
|
|
||||||
// First flip A bitstring byte endian for CRC routines (optimized for DLSCH/ULSCH, not PBCH/PDCCH)
|
// First flip A bitstring byte endian for CRC routines (optimized for DLSCH/ULSCH, not PBCH/PDCCH)
|
||||||
// CRC reads in each byte in bit positions 7 downto 0, for PBCH/PDCCH we need to read in a_{A-1} downto a_{0}, A = length of bit string (e.g. 32 for PBCH)
|
// 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) {
|
if (bitlen<=32) {
|
||||||
uint8_t A32_flip[4];
|
uint8_t A32_flip[4];
|
||||||
uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen));
|
uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen));
|
||||||
@@ -452,6 +448,19 @@ void polar_encoder_fast(uint64_t *A,
|
|||||||
A64_flip[7]=((uint8_t *)&Aprime)[0];
|
A64_flip[7]=((uint8_t *)&Aprime)[0];
|
||||||
tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8)));
|
tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8)));
|
||||||
}
|
}
|
||||||
|
else if (bitlen<=128) {
|
||||||
|
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 n;
|
||||||
// this is number of quadwords in the bit string
|
// this is number of quadwords in the bit string
|
||||||
@@ -459,11 +468,14 @@ void polar_encoder_fast(uint64_t *A,
|
|||||||
|
|
||||||
if ((polarParams->K&63) > 0) quadwlen++;
|
if ((polarParams->K&63) > 0) quadwlen++;
|
||||||
|
|
||||||
// Create the B bitstring as
|
// Create the B bit string as
|
||||||
// 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
|
// 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1, p_0, p_1, ..., p_{N_parity-1}
|
||||||
|
|
||||||
|
//??? 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] = (A[n] << polarParams->crcParityBits) | tcrc;
|
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));
|
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;
|
||||||
|
|
||||||
@@ -484,6 +496,11 @@ void polar_encoder_fast(uint64_t *A,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_POLAR_MATLAB
|
||||||
|
// Cprime = pbchCprime
|
||||||
|
for (int i = 0; i < quadwlen; i++) printf("[polar_encoder_fast]C'[%d]= 0x%llx\n", i, (unsigned long long)(Cprime[i]));
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_POLAR_ENCODER
|
#ifdef DEBUG_POLAR_ENCODER
|
||||||
|
|
||||||
if (polarParams->K<65)
|
if (polarParams->K<65)
|
||||||
@@ -536,45 +553,104 @@ void polar_encoder_fast(uint64_t *A,
|
|||||||
int off=0;
|
int off=0;
|
||||||
int len=polarParams->K;
|
int len=polarParams->K;
|
||||||
|
|
||||||
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
|
if (polarParams->N==512) {
|
||||||
for (int i=0; i<((len>63) ? 64 : len); i++) {
|
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
|
||||||
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
|
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",
|
#ifdef DEBUG_POLAR_ENCODER
|
||||||
Cprime_i,off+i,(Cprime[j]>>i) &1,
|
printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
|
||||||
polarParams->G_N_tab[off+i][0],
|
Cprime_i,off+i,(Cprime[j]>>i) &1,
|
||||||
polarParams->G_N_tab[off+i][1],
|
polarParams->G_N_tab[off+i][0],
|
||||||
polarParams->G_N_tab[off+i][2],
|
polarParams->G_N_tab[off+i][1],
|
||||||
polarParams->G_N_tab[off+i][3],
|
polarParams->G_N_tab[off+i][2],
|
||||||
polarParams->G_N_tab[off+i][4],
|
polarParams->G_N_tab[off+i][3],
|
||||||
polarParams->G_N_tab[off+i][5],
|
polarParams->G_N_tab[off+i][4],
|
||||||
polarParams->G_N_tab[off+i][6],
|
polarParams->G_N_tab[off+i][5],
|
||||||
polarParams->G_N_tab[off+i][7]);
|
polarParams->G_N_tab[off+i][6],
|
||||||
#endif
|
polarParams->G_N_tab[off+i][7]);
|
||||||
*/
|
#endif
|
||||||
uint64_t *Gi=polarParams->G_N_tab[off+i];
|
*/
|
||||||
D[0] ^= (Cprime_i & Gi[0]);
|
uint64_t *Gi=polarParams->G_N_tab[off+i];
|
||||||
D[1] ^= (Cprime_i & Gi[1]);
|
D[0] ^= (Cprime_i & Gi[0]);
|
||||||
D[2] ^= (Cprime_i & Gi[2]);
|
D[1] ^= (Cprime_i & Gi[1]);
|
||||||
D[3] ^= (Cprime_i & Gi[3]);
|
D[2] ^= (Cprime_i & Gi[2]);
|
||||||
D[4] ^= (Cprime_i & Gi[4]);
|
D[3] ^= (Cprime_i & Gi[3]);
|
||||||
D[5] ^= (Cprime_i & Gi[5]);
|
D[4] ^= (Cprime_i & Gi[4]);
|
||||||
D[6] ^= (Cprime_i & Gi[6]);
|
D[5] ^= (Cprime_i & Gi[5]);
|
||||||
D[7] ^= (Cprime_i & Gi[7]);
|
D[6] ^= (Cprime_i & Gi[6]);
|
||||||
}
|
D[7] ^= (Cprime_i & Gi[7]);
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_POLAR_ENCODER
|
#ifdef DEBUG_POLAR_ENCODER
|
||||||
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
|
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
|
||||||
D[0],
|
D[0],
|
||||||
D[1],
|
D[1],
|
||||||
D[2],
|
D[2],
|
||||||
D[3],
|
D[3],
|
||||||
D[4],
|
D[4],
|
||||||
D[5],
|
D[5],
|
||||||
D[6],
|
D[6],
|
||||||
D[7]);
|
D[7]);
|
||||||
#endif
|
#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\n",
|
||||||
|
D[0],
|
||||||
|
D[1],
|
||||||
|
D[2],
|
||||||
|
D[3]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
polar_rate_matching(polarParams,(void *)D,(void *)out);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
* \email turker.yilmaz@eurecom.fr
|
* \email turker.yilmaz@eurecom.fr
|
||||||
* \note
|
* \note
|
||||||
* \warning
|
* \warning
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||||
|
|
||||||
@@ -43,295 +43,305 @@ void nr_polar_bit_insertion(uint8_t *input,
|
|||||||
uint16_t k=0;
|
uint16_t k=0;
|
||||||
uint8_t flag;
|
uint8_t flag;
|
||||||
|
|
||||||
if (n_PC>0) {
|
if (n_PC>0) {
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
for (int n=0; n<=N-1; n++) {
|
for (int n=0; n<=N-1; n++) {
|
||||||
flag=0;
|
flag=0;
|
||||||
for (int m=0; m<=(K+n_PC)-1; m++) {
|
for (int m=0; m<=(K+n_PC)-1; m++) {
|
||||||
if ( n == Q_I_N[m]) {
|
if ( n == Q_I_N[m]) {
|
||||||
flag=1;
|
flag=1;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (flag) { // n ϵ Q_I_N
|
|
||||||
output[n]=input[k];
|
|
||||||
k++;
|
|
||||||
} else {
|
|
||||||
output[n] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (flag) { // n ϵ Q_I_N
|
||||||
|
output[n]=input[k];
|
||||||
|
k++;
|
||||||
|
} else {
|
||||||
|
output[n] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t nr_polar_output_length(uint16_t K,
|
uint32_t nr_polar_output_length(uint16_t K,
|
||||||
uint16_t E,
|
uint16_t E,
|
||||||
uint8_t n_max)
|
uint8_t n_max)
|
||||||
{
|
{
|
||||||
uint8_t n_1, n_2, n_min=5, n;
|
uint8_t n_1, n_2, n_min=5, n;
|
||||||
double R_min=1.0/8;
|
double R_min=1.0/8;
|
||||||
|
|
||||||
if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) {
|
if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) {
|
||||||
n_1 = ceil(log2(E))-1;
|
n_1 = ceil(log2(E))-1;
|
||||||
} else {
|
} else {
|
||||||
n_1 = ceil(log2(E));
|
n_1 = ceil(log2(E));
|
||||||
}
|
}
|
||||||
|
|
||||||
n_2 = ceil(log2(K/R_min));
|
n_2 = ceil(log2(K/R_min));
|
||||||
|
|
||||||
n=n_max;
|
n=n_max;
|
||||||
if (n>n_1) n=n_1;
|
if (n>n_1) n=n_1;
|
||||||
if (n>n_2) n=n_2;
|
if (n>n_2) n=n_2;
|
||||||
if (n<n_min) n=n_min;
|
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,
|
void nr_polar_channel_interleaver_pattern(uint16_t *cip,
|
||||||
uint8_t I_BIL,
|
uint8_t I_BIL,
|
||||||
uint16_t E)
|
uint16_t E)
|
||||||
{
|
{
|
||||||
if (I_BIL == 1) {
|
if (I_BIL == 1) {
|
||||||
uint16_t T=0, k;
|
uint16_t T=0, k;
|
||||||
while( ((T/2)*(T+1)) < E ) T++;
|
while( ((T/2)*(T+1)) < E ) T++;
|
||||||
|
|
||||||
int16_t **v = malloc(T * sizeof(*v));
|
int16_t **v = malloc(T * sizeof(*v));
|
||||||
for (int i = 0; i <= T-1; i++) v[i] = malloc((T-i) * sizeof(*(v[i])));
|
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);
|
|
||||||
|
|
||||||
|
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 {
|
} 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,
|
void nr_polar_info_bit_pattern(uint8_t *ibp,
|
||||||
int16_t *Q_I_N,
|
int16_t *Q_I_N,
|
||||||
int16_t *Q_F_N,
|
int16_t *Q_F_N,
|
||||||
uint16_t *J,
|
uint16_t *J,
|
||||||
const uint16_t *Q_0_Nminus1,
|
const uint16_t *Q_0_Nminus1,
|
||||||
uint16_t K,
|
uint16_t K,
|
||||||
uint16_t N,
|
uint16_t N,
|
||||||
uint16_t E,
|
uint16_t E,
|
||||||
uint8_t n_PC)
|
uint8_t n_PC)
|
||||||
{
|
{
|
||||||
int16_t *Q_Ftmp_N = malloc(sizeof(int16_t) * (N + 1)); // Last element shows the final
|
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_Itmp_N = malloc(sizeof(int16_t) * (N + 1)); // array index assigned a value.
|
||||||
|
|
||||||
for (int i = 0; i <= N; i++) {
|
for (int i = 0; i <= N; i++) {
|
||||||
Q_Ftmp_N[i] = -1; // Empty array.
|
Q_Ftmp_N[i] = -1; // Empty array.
|
||||||
Q_Itmp_N[i] = -1;
|
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;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
uint8_t flag;
|
limit = ceil((double) (9 * N - 4 * E) / 16);
|
||||||
uint16_t limit, ind;
|
for (int n = 0; n <= limit - 1; n++) {
|
||||||
|
ind = Q_Ftmp_N[N] + 1;
|
||||||
if (E < N) {
|
Q_Ftmp_N[ind] = n;
|
||||||
if ((K / (double) E) <= (7.0 / 16)) { //puncturing
|
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
|
||||||
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 { //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
|
//Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
|
||||||
for (int n = 0; n <= N - 1; n++) {
|
for (int n = 0; n <= N - 1; n++) {
|
||||||
flag = 1;
|
flag = 1;
|
||||||
for (int m = 0; m <= Q_Ftmp_N[N]; m++) {
|
for (int m = 0; m <= Q_Ftmp_N[N]; m++) {
|
||||||
if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) {
|
if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) {
|
||||||
flag = 0;
|
flag = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flag) {
|
if (flag) {
|
||||||
Q_Itmp_N[Q_Itmp_N[N] + 1] = Q_0_Nminus1[n];
|
Q_Itmp_N[Q_Itmp_N[N] + 1] = Q_0_Nminus1[n];
|
||||||
Q_Itmp_N[N]++;
|
Q_Itmp_N[N]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_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++) {
|
for (int n = 0; n <= (K + n_PC) - 1; n++) {
|
||||||
ind = Q_Itmp_N[N] + n - ((K + n_PC) - 1);
|
ind = Q_Itmp_N[N] + n - ((K + n_PC) - 1);
|
||||||
Q_I_N[n] = Q_Itmp_N[ind];
|
Q_I_N[n] = Q_Itmp_N[ind];
|
||||||
}
|
}
|
||||||
|
|
||||||
//Q_F_N = Q_0_N-1 \ Q_I_N
|
//Q_F_N = Q_0_N-1 \ Q_I_N
|
||||||
for (int n = 0; n <= N - 1; n++) {
|
for (int n = 0; n <= N - 1; n++) {
|
||||||
flag = 1;
|
flag = 1;
|
||||||
for (int m = 0; m <= (K + n_PC) - 1; m++) {
|
for (int m = 0; m <= (K + n_PC) - 1; m++) {
|
||||||
if (Q_0_Nminus1[n] == Q_I_N[m]) {
|
if (Q_0_Nminus1[n] == Q_I_N[m]) {
|
||||||
flag = 0;
|
flag = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flag) {
|
if (flag) {
|
||||||
Q_F_N[Q_F_N[N] + 1] = Q_0_Nminus1[n];
|
Q_F_N[Q_F_N[N] + 1] = Q_0_Nminus1[n];
|
||||||
Q_F_N[N]++;
|
Q_F_N[N]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Information Bit Pattern
|
//Information Bit Pattern
|
||||||
for (int n = 0; n <= N - 1; n++) {
|
for (int n = 0; n <= N - 1; n++) {
|
||||||
ibp[n] = 0;
|
ibp[n] = 0;
|
||||||
|
|
||||||
for (int m = 0; m <= (K + n_PC) - 1; m++) {
|
for (int m = 0; m <= (K + n_PC) - 1; m++) {
|
||||||
if (n == Q_I_N[m]) {
|
if (n == Q_I_N[m]) {
|
||||||
ibp[n] = 1;
|
ibp[n] = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(Q_Ftmp_N);
|
free(Q_Ftmp_N);
|
||||||
free(Q_Itmp_N);
|
free(Q_Itmp_N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void nr_polar_info_bit_extraction(uint8_t *input,
|
void nr_polar_info_bit_extraction(uint8_t *input,
|
||||||
uint8_t *output,
|
uint8_t *output,
|
||||||
uint8_t *pattern,
|
uint8_t *pattern,
|
||||||
uint16_t size)
|
uint16_t size)
|
||||||
{
|
{
|
||||||
uint16_t j = 0;
|
uint16_t j = 0;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
if (pattern[i] > 0) {
|
if (pattern[i] > 0) {
|
||||||
output[j] = input[i];
|
output[j] = input[i];
|
||||||
j++;
|
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){
|
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)
|
||||||
|
{
|
||||||
|
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;
|
for (int m=0; m<=N-1; m++) d[m]=m;
|
||||||
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++){
|
||||||
|
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++){
|
if (E>=N) { //repetition
|
||||||
i=floor((32*m)/N);
|
for (int k=0; k<=E-1; k++) {
|
||||||
J[m] = (P_i_[i]*(N/32)) + (m%(N/32));
|
ind = (k%N);
|
||||||
y[m] = d[J[m]];
|
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
|
free(d);
|
||||||
for (int k=0; k<=E-1; k++) {
|
free(y);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E){
|
void nr_polar_rate_matching(double *input,
|
||||||
|
double *output,
|
||||||
if (E>=N) { //repetition
|
uint16_t *rmp,
|
||||||
for (int i=0; i<=N-1; i++) output[i]=0;
|
uint16_t K,
|
||||||
for (int i=0; i<=E-1; i++){
|
uint16_t N,
|
||||||
output[rmp[i]]+=input[i];
|
uint16_t E)
|
||||||
}
|
{
|
||||||
} else {
|
if (E>=N) { //repetition
|
||||||
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
|
for (int i=0; i<=N-1; i++) output[i]=0;
|
||||||
for (int i=0; i<=N-1; i++) output[i]=0;
|
for (int i=0; i<=E-1; i++){
|
||||||
} else { //shortening
|
output[rmp[i]]+=input[i];
|
||||||
for (int i=0; i<=N-1; i++) output[i]=INFINITY;
|
}
|
||||||
}
|
} else {
|
||||||
|
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
|
||||||
for (int i=0; i<=E-1; i++){
|
for (int i=0; i<=N-1; i++) output[i]=0;
|
||||||
output[rmp[i]]=input[i];
|
} 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];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_polar_rate_matching_int16(int16_t *input, int16_t *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)
|
||||||
|
{
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
|
||||||
if (E>=N) { //repetition
|
for (int i=0; i<=E-1; i++) output[rmp[i]]=input[i];
|
||||||
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]
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<=E-1; i++){
|
|
||||||
output[rmp[i]]=input[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!\file PHY/CODING/nrSmallBlock/decodeSmallBlock.c
|
||||||
|
* \brief
|
||||||
|
* \author Turker Yilmaz
|
||||||
|
* \date 2019
|
||||||
|
* \version 0.1
|
||||||
|
* \company EURECOM
|
||||||
|
* \email turker.yilmaz@eurecom.fr
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
|
||||||
|
#include "assertions.h"
|
||||||
|
#include "PHY/sse_intrin.h"
|
||||||
|
|
||||||
|
//#define DEBUG_DECODESMALLBLOCK
|
||||||
|
|
||||||
|
//input = [d̂_0] [d̂_1] [d̂_2] ... [d̂_31]
|
||||||
|
//output = [? ... ? ĉ_K-1 ... ĉ_2 ĉ_1 ĉ_0]
|
||||||
|
|
||||||
|
uint16_t decodeSmallBlock(int8_t *in, uint8_t len){
|
||||||
|
uint16_t out = 0;
|
||||||
|
|
||||||
|
AssertFatal(len >= 3 && len <= 11, "[decodeSmallBlock] Message Length = %d (Small Block Coding is only defined for input lengths 3 to 11)", len);
|
||||||
|
|
||||||
|
if(len<7) {
|
||||||
|
int16_t Rhat[NR_SMALL_BLOCK_CODED_BITS] = {0}, Rhatabs[NR_SMALL_BLOCK_CODED_BITS] = {0};
|
||||||
|
uint16_t maxVal;
|
||||||
|
uint8_t maxInd = 0;
|
||||||
|
uint8_t 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];
|
||||||
|
|
||||||
|
#if defined(__AVX2__)
|
||||||
|
for (int i = 0; i < NR_SMALL_BLOCK_CODED_BITS; i += 16) {
|
||||||
|
__m256i a15_a0 = _mm256_loadu_si256((__m256i*)&Rhat[i]);
|
||||||
|
a15_a0 = _mm256_abs_epi16(a15_a0);
|
||||||
|
_mm256_storeu_si256((__m256i*)(&Rhatabs[i]), a15_a0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (int i = 0; i < NR_SMALL_BLOCK_CODED_BITS; i += 8) {
|
||||||
|
__m128i a7_a0 = _mm_loadu_si128((__m128i*)&Rhat[i]);
|
||||||
|
a7_a0 = _mm_abs_epi16(a7_a0);
|
||||||
|
_mm_storeu_si128((__m128i*)(&Rhatabs[i]), a7_a0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
maxVal = Rhatabs[0];
|
||||||
|
for (int k = 1; k < jmax; ++k){
|
||||||
|
if (Rhatabs[k] > maxVal){
|
||||||
|
maxVal = Rhatabs[k];
|
||||||
|
maxInd = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out = properOrderedBasis[maxInd] | ( (Rhat[maxInd] > 0) ? (uint16_t)0 : (uint16_t)1 );
|
||||||
|
|
||||||
|
#ifdef DEBUG_DECODESMALLBLOCK
|
||||||
|
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
|
||||||
|
|
||||||
|
} else {
|
||||||
|
uint8_t maxRow = 0, maxCol = 0;
|
||||||
|
|
||||||
|
#if defined(__AVX2__)
|
||||||
|
int16_t maxVal = 0;
|
||||||
|
int DmatrixElementVal = 0;
|
||||||
|
int8_t DmatrixElement[NR_SMALL_BLOCK_CODED_BITS] = {0};
|
||||||
|
__m256i _in_256 = _mm256_loadu_si256 ((__m256i*)&in[0]);
|
||||||
|
__m256i _maskD_256, _Dmatrixj_256, _maskH_256, _DmatrixElement_256;
|
||||||
|
for (int j = 0; j < ( 1<<(len-6) ); ++j) {
|
||||||
|
_maskD_256 = _mm256_loadu_si256 ((__m256i*)(&maskD[j][0]));
|
||||||
|
_Dmatrixj_256 = _mm256_sign_epi8 (_in_256, _maskD_256);
|
||||||
|
for (int k = 0; k < NR_SMALL_BLOCK_CODED_BITS; ++k) {
|
||||||
|
_maskH_256 = _mm256_loadu_si256 ((__m256i*)(&hadamard32InterleavedTransposed[k][0]));
|
||||||
|
_DmatrixElement_256 = _mm256_sign_epi8 (_Dmatrixj_256, _maskH_256);
|
||||||
|
#if defined(__AVX512F__)
|
||||||
|
DmatrixElementVal = _mm512_reduce_add_epi32 (
|
||||||
|
_mm512_add_epi32(
|
||||||
|
_mm512_cvtepi8_epi32 (_mm256_extracti128_si256 (_DmatrixElement_256, 1)),
|
||||||
|
_mm512_cvtepi8_epi32 (_mm256_castsi256_si128 (_DmatrixElement_256))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
_mm256_storeu_si256((__m256i*)(&DmatrixElement[0]), _DmatrixElement_256);
|
||||||
|
for (int i = 0; i < NR_SMALL_BLOCK_CODED_BITS; ++i)
|
||||||
|
DmatrixElementVal += DmatrixElement[i];
|
||||||
|
#endif
|
||||||
|
if (abs(DmatrixElementVal) > abs(maxVal)){
|
||||||
|
maxVal = DmatrixElementVal;
|
||||||
|
maxRow = j;
|
||||||
|
maxCol = k;
|
||||||
|
}
|
||||||
|
DmatrixElementVal=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out = properOrderedBasisExtended[maxRow] | properOrderedBasis[maxCol] | ( (maxVal > 0) ? (uint16_t)0 : (uint16_t)1 );
|
||||||
|
#else
|
||||||
|
int8_t Dmatrix[NR_SMALL_BLOCK_CODED_BITS][NR_SMALL_BLOCK_CODED_BITS] = {0};
|
||||||
|
int16_t DmatrixFHT[NR_SMALL_BLOCK_CODED_BITS][NR_SMALL_BLOCK_CODED_BITS] = {0};
|
||||||
|
uint16_t maxVal;
|
||||||
|
uint8_t rowLimit = 1<<(len-6);
|
||||||
|
|
||||||
|
for (int j = 0; j < ( rowLimit ); ++j)
|
||||||
|
for (int k = 0; k < NR_SMALL_BLOCK_CODED_BITS; ++k)
|
||||||
|
Dmatrix[j][k] = in[k] * maskD[j][k];
|
||||||
|
|
||||||
|
for (int i = 0; i < ( rowLimit ); ++i)
|
||||||
|
for (int j = 0; j < NR_SMALL_BLOCK_CODED_BITS; ++j)
|
||||||
|
for (int k = 0; k < NR_SMALL_BLOCK_CODED_BITS; ++k)
|
||||||
|
DmatrixFHT[i][j] += Dmatrix[i][k] * hadamard32InterleavedTransposed[j][k];
|
||||||
|
|
||||||
|
maxVal = abs(DmatrixFHT[0][0]);
|
||||||
|
for (int i = 0; i < ( rowLimit ); ++i)
|
||||||
|
for (int j = 0; j < NR_SMALL_BLOCK_CODED_BITS; ++j)
|
||||||
|
if (abs(DmatrixFHT[i][j]) > maxVal){
|
||||||
|
maxVal = abs(DmatrixFHT[i][j]);
|
||||||
|
maxRow = i;
|
||||||
|
maxCol = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
out = properOrderedBasisExtended[maxRow] | properOrderedBasis[maxCol] | ( (DmatrixFHT[maxRow][maxCol] > 0) ? (uint16_t)0 : (uint16_t)1 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_DECODESMALLBLOCK
|
||||||
|
for (int k = 0; k < NR_SMALL_BLOCK_CODED_BITS; ++k)
|
||||||
|
printf("[decodeSmallBlock]maxRow = %d maxCol = %d out[%d]=%d\n", maxRow, maxCol, k, ((uint32_t)out>>k)&1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!\file PHY/CODING/nrSmallBlock/encodeSmallBlock.c
|
||||||
|
* \brief
|
||||||
|
* \author Turker Yilmaz
|
||||||
|
* \date 2019
|
||||||
|
* \version 0.1
|
||||||
|
* \company EURECOM
|
||||||
|
* \email turker.yilmaz@eurecom.fr
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
|
||||||
|
|
||||||
|
//input = [0 ... 0 c_K-1 ... c_2 c_1 c_0]
|
||||||
|
//output = [d_31 d_30 ... d_2 d_1 d_0]
|
||||||
|
uint32_t encodeSmallBlock(uint16_t *in, uint8_t len){
|
||||||
|
uint32_t out = 0;
|
||||||
|
for (uint16_t i=0; i<len; i++)
|
||||||
|
if ((*in & (1<<i)) > 0)
|
||||||
|
out^=nrSmallBlockBasis[i];
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!\file PHY/CODING/nrSmallBlock/nr_small_block_defs.h
|
||||||
|
* \brief
|
||||||
|
* \author Turker Yilmaz
|
||||||
|
* \date 2019
|
||||||
|
* \version 0.1
|
||||||
|
* \company EURECOM
|
||||||
|
* \email turker.yilmaz@eurecom.fr
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NR_SMALL_BLOCK_DEFS__H__
|
||||||
|
#define __NR_SMALL_BLOCK_DEFS__H__
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define NR_SMALL_BLOCK_CODED_BITS 32
|
||||||
|
|
||||||
|
#define L1d_CLS 64
|
||||||
|
|
||||||
|
uint32_t encodeSmallBlock(uint16_t *in, uint8_t len);
|
||||||
|
|
||||||
|
uint16_t decodeSmallBlock(int8_t *in, uint8_t len);
|
||||||
|
|
||||||
|
static const uint32_t nrSmallBlockBasis[11] = {0xFFFFFFFF, 0x4BA5A933, 0x7D910E5A, 0x6D26339C, 0x71C7C3E0,
|
||||||
|
0x7E0FFC00, 0x731D8E64, 0x6B44F5B0, 0x7DC218EC, 0x4DA1B746, 0x42F0FFFF};
|
||||||
|
|
||||||
|
static const uint16_t properOrderedBasis[32] = {0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000A, 0x000C, 0x000E, 0x0010, 0x0012,
|
||||||
|
0x0014, 0x0016, 0x0018, 0x001A, 0x001C, 0x001E, 0x0020, 0x0022, 0x0024, 0x0026,
|
||||||
|
0x0028, 0x002A, 0x002C, 0x002E, 0x0030, 0x0032, 0x0034, 0x0036, 0x0038, 0x003A, 0x003C, 0x003E};
|
||||||
|
|
||||||
|
static const uint16_t properOrderedBasisExtended[32] = {0x0000, 0x0040, 0x0080, 0x00C0, 0x0100, 0x0140, 0x0180, 0x01C0, 0x0200, 0x0240,
|
||||||
|
0x0280, 0x02C0, 0x0300, 0x0340, 0x0380, 0x03C0, 0x0400, 0x0440, 0x0480, 0x04C0,
|
||||||
|
0x0500, 0x0540, 0x0580, 0x05C0, 0x0600, 0x0640, 0x0680, 0x06C0, 0x0700, 0x0740, 0x0780, 0x07C0};
|
||||||
|
|
||||||
|
static const int8_t hadamard32InterleavedTransposed[32][32] __attribute__ ((aligned(32))) = {
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{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},
|
||||||
|
{-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}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int8_t maskD[32][32] __attribute__ ((aligned(32))) = {
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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},
|
||||||
|
{-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,},
|
||||||
|
{-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}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -21,19 +21,16 @@
|
|||||||
|
|
||||||
/*!\file PHY/CODING/nr_polar_init.h
|
/*!\file PHY/CODING/nr_polar_init.h
|
||||||
* \brief
|
* \brief
|
||||||
* \author Turker Yilmaz
|
* \author Turker Yilmaz, Raymond Knopp
|
||||||
* \date 2018
|
* \date 2018
|
||||||
* \version 0.1
|
* \version 0.1
|
||||||
* \company EURECOM
|
* \company EURECOM
|
||||||
* \email turker.yilmaz@eurecom.fr
|
* \email turker.yilmaz@eurecom.fr, raymond.knopp@eurecom.fr
|
||||||
* \note
|
* \note
|
||||||
* \warning
|
* \warning
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nrPolar_tools/nr_polar_defs.h"
|
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h"
|
|
||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
|
|
||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
|
||||||
#include "PHY/NR_TRANSPORT/nr_dci.h"
|
#include "PHY/NR_TRANSPORT/nr_dci.h"
|
||||||
|
|
||||||
static int intcmp(const void *p1,const void *p2) {
|
static int intcmp(const void *p1,const void *p2) {
|
||||||
@@ -56,7 +53,7 @@ static void nr_polar_init(t_nrPolar_params * *polarParams,
|
|||||||
|
|
||||||
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
|
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
|
||||||
//Else, initialize and add node to the end of the linked list.
|
//Else, initialize and add node to the end of the linked list.
|
||||||
t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params));
|
t_nrPolar_params *newPolarInitNode = calloc(sizeof(t_nrPolar_params),1);
|
||||||
|
|
||||||
if (newPolarInitNode != NULL) {
|
if (newPolarInitNode != NULL) {
|
||||||
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
|
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
|
||||||
@@ -95,7 +92,9 @@ static void nr_polar_init(t_nrPolar_params * *polarParams,
|
|||||||
}
|
}
|
||||||
|
|
||||||
newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode.
|
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 = nr_polar_output_length(newPolarInitNode->K,
|
||||||
|
newPolarInitNode->encoderLength,
|
||||||
|
newPolarInitNode->n_max);
|
||||||
newPolarInitNode->n = log2(newPolarInitNode->N);
|
newPolarInitNode->n = log2(newPolarInitNode->N);
|
||||||
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
|
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
|
||||||
//polar_encoder vectors:
|
//polar_encoder vectors:
|
||||||
@@ -182,9 +181,9 @@ void nr_polar_print_polarParams(t_nrPolar_params *polarParams) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_nrPolar_params *nr_polar_params ( int8_t messageType,
|
t_nrPolar_params *nr_polar_params (int8_t messageType,
|
||||||
uint16_t messageLength,
|
uint16_t messageLength,
|
||||||
uint8_t aggregation_level) {
|
uint8_t aggregation_level) {
|
||||||
static t_nrPolar_params *polarList = NULL;
|
static t_nrPolar_params *polarList = NULL;
|
||||||
nr_polar_init(&polarList, messageType,messageLength,aggregation_level);
|
nr_polar_init(&polarList, messageType,messageLength,aggregation_level);
|
||||||
t_nrPolar_params *polarParams=polarList;
|
t_nrPolar_params *polarParams=polarList;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "PHY/defs_gNB.h"
|
#include "PHY/defs_gNB.h"
|
||||||
#include "PHY/defs_nr_UE.h"
|
#include "PHY/defs_nr_UE.h"
|
||||||
|
#include "PHY/CODING/coding_defs.h"
|
||||||
|
|
||||||
//#define RM_DEBUG 1
|
//#define RM_DEBUG 1
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ int32_t nr_segmentation(unsigned char *input_buffer,
|
|||||||
unsigned int B,
|
unsigned int B,
|
||||||
unsigned int *C,
|
unsigned int *C,
|
||||||
unsigned int *K,
|
unsigned int *K,
|
||||||
unsigned int *Zout,
|
unsigned int *Zout, // [hna] Zout is Zc
|
||||||
unsigned int *F)
|
unsigned int *F)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -355,7 +355,9 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,
|
void phy_config_harq_ue(module_id_t Mod_id,
|
||||||
|
int CC_id,
|
||||||
|
uint8_t eNB_id,
|
||||||
uint16_t max_harq_tx )
|
uint16_t max_harq_tx )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
+52
-31
@@ -33,12 +33,14 @@
|
|||||||
#include "assertions.h"
|
#include "assertions.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
||||||
#include "SCHED_NR/fapi_nr_l1.h"
|
#include "SCHED_NR/fapi_nr_l1.h"
|
||||||
|
|
||||||
extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
|
extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
|
||||||
extern int32_t get_uldl_offset(int nr_bandP);
|
extern int32_t get_uldl_offset(int nr_bandP);
|
||||||
|
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||||
|
|
||||||
int l1_north_init_gNB() {
|
int l1_north_init_gNB() {
|
||||||
int i,j;
|
int i,j;
|
||||||
@@ -77,12 +79,14 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
unsigned char abstraction_flag) {
|
unsigned char abstraction_flag) {
|
||||||
// shortcuts
|
// shortcuts
|
||||||
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
|
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
|
||||||
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
|
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
|
||||||
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
|
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
|
||||||
LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
|
LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
|
||||||
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
|
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
|
||||||
LTE_eNB_PRACH *const prach_vars = &gNB->prach_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__);
|
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_dlsch_bitrate = 0;
|
||||||
gNB->total_transmitted_bits = 0;
|
gNB->total_transmitted_bits = 0;
|
||||||
@@ -110,7 +114,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
init_dfts();
|
init_dfts();
|
||||||
// PBCH DMRS gold sequences generation
|
// PBCH DMRS gold sequences generation
|
||||||
nr_init_pbch_dmrs(gNB);
|
nr_init_pbch_dmrs(gNB);
|
||||||
// Polar encoder init for PBCH
|
|
||||||
//PDCCH DMRS init
|
//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;
|
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
|
||||||
@@ -148,6 +151,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
/// Transport init necessary for NR synchro
|
||||||
init_nr_transport(gNB);
|
init_nr_transport(gNB);
|
||||||
|
|
||||||
@@ -167,14 +171,15 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
gNB->first_run_I0_measurements =
|
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.
|
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->rxdata = (int32_t **)NULL;
|
||||||
common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t *));
|
common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*));
|
||||||
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t *));
|
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*));
|
||||||
|
|
||||||
for (i=0; i<15; i++) {
|
for (i=0;i<15;i++){
|
||||||
common_vars->txdataF[i] = (int32_t *)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) );
|
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],
|
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
|
||||||
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
|
// Channel estimates for SRS
|
||||||
@@ -357,7 +362,9 @@ void install_schedule_handlers(IF_Module_t *if_inst)
|
|||||||
|
|
||||||
/// this function is a temporary addition for NR configuration
|
/// 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;
|
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||||
nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config;
|
nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config;
|
||||||
//overwrite for new NR parameters
|
//overwrite for new NR parameters
|
||||||
@@ -372,15 +379,17 @@ 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.n_ssb_crb.value = (N_RB_DL-20);
|
||||||
gNB_config->sch_config.ssb_subcarrier_offset.value = 0;
|
gNB_config->sch_config.ssb_subcarrier_offset.value = 0;
|
||||||
gNB_config->sch_config.physical_cell_id.value=Nid_cell;
|
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_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED;
|
||||||
|
|
||||||
gNB->mac_enabled = 1;
|
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->dl_CarrierFreq = 3500000000;//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->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
|
||||||
fp->threequarter_fs = 0;
|
fp->threequarter_fs = 0;
|
||||||
nr_init_frame_parms(gNB_config, fp);
|
nr_init_frame_parms(gNB_config, fp);
|
||||||
gNB->configured = 1;
|
gNB->configured = 1;
|
||||||
LOG_I(PHY,"gNB configured\n");
|
LOG_I(PHY,"gNB configured\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -398,6 +407,7 @@ 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.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.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.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) {
|
if (phy_config->cfg->subframe_config.duplex_mode.value == 0) {
|
||||||
gNB_config->subframe_config.duplex_mode.value = TDD;
|
gNB_config->subframe_config.duplex_mode.value = TDD;
|
||||||
@@ -408,7 +418,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
|
|||||||
RC.gNB[Mod_id][CC_id]->mac_enabled = 1;
|
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->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->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
|
||||||
fp->threequarter_fs = 0;
|
fp->threequarter_fs = openair0_cfg[0].threequarter_fs;
|
||||||
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",
|
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,
|
Mod_id,
|
||||||
CC_id,
|
CC_id,
|
||||||
@@ -417,6 +427,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
|
|||||||
gNB_config->rf_config.ul_carrier_bandwidth.value,
|
gNB_config->rf_config.ul_carrier_bandwidth.value,
|
||||||
gNB_config->sch_config.physical_cell_id.value,
|
gNB_config->sch_config.physical_cell_id.value,
|
||||||
fp->dl_CarrierFreq );
|
fp->dl_CarrierFreq );
|
||||||
|
|
||||||
nr_init_frame_parms(gNB_config, fp);
|
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) {
|
||||||
@@ -436,6 +447,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
|
|||||||
LOG_I(PHY, "Initialise nr transport\n");
|
LOG_I(PHY, "Initialise nr transport\n");
|
||||||
|
|
||||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||||
|
|
||||||
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
|
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
|
||||||
|
|
||||||
for (j=0; j<2; j++) {
|
for (j=0; j<2; j++) {
|
||||||
@@ -445,29 +457,38 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
|
|||||||
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
|
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}/* else {
|
}/* else {
|
||||||
|
gNB->dlsch[i][j]->rnti=0;
|
||||||
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);
|
||||||
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 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
|
// 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;
|
//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);
|
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);
|
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);
|
gNB->dlsch_ra = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
|
||||||
|
|||||||
@@ -357,12 +357,19 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,
|
void phy_config_harq_ue(module_id_t Mod_id,
|
||||||
uint16_t max_harq_tx )
|
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_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[num_of_threads][eNB_id][num_of_code_words]->Mlimit = max_harq_tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uint16_t beta_cqi[16];
|
extern uint16_t beta_cqi[16];
|
||||||
@@ -592,7 +599,8 @@ void phy_init_nr_ue__PDSCH( NR_UE_PDSCH* const pdsch, const NR_DL_FRAME_PARMS* c
|
|||||||
AssertFatal( pdsch, "pdsch==0" );
|
AssertFatal( pdsch, "pdsch==0" );
|
||||||
|
|
||||||
pdsch->pmi_ext = (uint8_t*)malloc16_clear( fp->N_RB_DL );
|
pdsch->pmi_ext = (uint8_t*)malloc16_clear( fp->N_RB_DL );
|
||||||
pdsch->llr[0] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
|
pdsch->llr[0] = (int16_t*)malloc16_clear( (8*(3*8*6144))*sizeof(int16_t) );
|
||||||
|
pdsch->layer_llr[0] = (int16_t*)malloc16_clear( (8*(3*8*6144))*sizeof(int16_t) );
|
||||||
pdsch->llr128 = (int16_t**)malloc16_clear( sizeof(int16_t*) );
|
pdsch->llr128 = (int16_t**)malloc16_clear( sizeof(int16_t*) );
|
||||||
// FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV
|
// FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV
|
||||||
// FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there
|
// FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there
|
||||||
@@ -602,6 +610,7 @@ void phy_init_nr_ue__PDSCH( NR_UE_PDSCH* const pdsch, const NR_DL_FRAME_PARMS* c
|
|||||||
pdsch->rxdataF_uespec_pilots = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
pdsch->rxdataF_uespec_pilots = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
pdsch->rxdataF_comp0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
pdsch->rxdataF_comp0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
pdsch->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
|
pdsch->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
|
||||||
|
pdsch->dl_ch_estimates = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
pdsch->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
pdsch->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
pdsch->dl_bf_ch_estimates = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
pdsch->dl_bf_ch_estimates = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
pdsch->dl_bf_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
pdsch->dl_bf_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
@@ -623,6 +632,7 @@ void phy_init_nr_ue__PDSCH( NR_UE_PDSCH* const pdsch, const NR_DL_FRAME_PARMS* c
|
|||||||
pdsch->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
pdsch->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
||||||
pdsch->rxdataF_uespec_pilots[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12);
|
pdsch->rxdataF_uespec_pilots[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12);
|
||||||
pdsch->rxdataF_comp0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
pdsch->rxdataF_comp0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
||||||
|
pdsch->dl_ch_estimates[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
|
||||||
pdsch->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
pdsch->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
||||||
pdsch->dl_bf_ch_estimates[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
|
pdsch->dl_bf_ch_estimates[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
|
||||||
pdsch->dl_bf_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
pdsch->dl_bf_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
||||||
@@ -719,22 +729,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Channel estimates
|
|
||||||
for (eNB_id=0; eNB_id<7; eNB_id++) {
|
|
||||||
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
|
||||||
common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
|
|
||||||
common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<fp->nb_antennas_rx; i++)
|
|
||||||
for (j=0; j<4; j++) {
|
|
||||||
int idx = (j<<1) + i;
|
|
||||||
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
|
||||||
common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
|
|
||||||
common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DLSCH
|
// DLSCH
|
||||||
for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) {
|
for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) {
|
||||||
@@ -761,7 +755,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
|
|||||||
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
||||||
(*pdsch_vars_th)[th_id][eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
|
(*pdsch_vars_th)[th_id][eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
|
||||||
(*pdsch_vars_th)[th_id][eNB_id]->llr_shifts_p = (*pdsch_vars_th)[0][eNB_id]->llr_shifts;
|
(*pdsch_vars_th)[th_id][eNB_id]->llr_shifts_p = (*pdsch_vars_th)[0][eNB_id]->llr_shifts;
|
||||||
(*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*8448)+12))*sizeof(int16_t) );
|
(*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
|
||||||
|
(*pdsch_vars_th)[th_id][eNB_id]->layer_llr[1] = (int16_t*)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
|
||||||
(*pdsch_vars_th)[th_id][eNB_id]->llr128_2ndstream = (int16_t**)malloc16_clear( sizeof(int16_t*) );
|
(*pdsch_vars_th)[th_id][eNB_id]->llr128_2ndstream = (int16_t**)malloc16_clear( sizeof(int16_t*) );
|
||||||
(*pdsch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
|
(*pdsch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
|
||||||
}
|
}
|
||||||
@@ -827,30 +822,32 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
|
|||||||
(*pdcch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
|
(*pdcch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
|
||||||
(*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
(*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<fp->nb_antennas_rx; i++) {
|
// Channel estimates
|
||||||
//ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) );
|
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
|
||||||
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_time = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
|
||||||
|
|
||||||
|
for (i=0; i<fp->nb_antennas_rx; i++) {
|
||||||
(*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) );
|
(*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) );
|
||||||
}
|
for (j=0; j<4; j++) {
|
||||||
|
int idx = (j<<1) + i;
|
||||||
|
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
|
||||||
|
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_time[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
|
||||||
|
|
||||||
for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++)
|
// size_t num = 7*2*fp->N_RB_DL*12;
|
||||||
int idx = (j<<1)+i;
|
size_t num = 4*273*12; // 4 symbols, 100 PRBs, 12 REs per PRB
|
||||||
// size_t num = 7*2*fp->N_RB_DL*12;
|
|
||||||
size_t num = 4*100*12; // 4 symbols, 100 PRBs, 12 REs per PRB
|
|
||||||
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
|
||||||
(*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
(*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
||||||
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
||||||
(*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
(*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
||||||
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBCH
|
// PBCH
|
||||||
pbch_vars[eNB_id]->rxdataF_ext = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
|
pbch_vars[eNB_id]->rxdataF_ext = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
|
||||||
pbch_vars[eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
pbch_vars[eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
|
pbch_vars[eNB_id]->dl_ch_estimates = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||||
pbch_vars[eNB_id]->llr = (int16_t*)malloc16_clear( 1920 );//
|
pbch_vars[eNB_id]->llr = (int16_t*)malloc16_clear( 1920 );//
|
||||||
prach_vars[eNB_id]->prachF = (int16_t*)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
|
prach_vars[eNB_id]->prachF = (int16_t*)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
|
||||||
@@ -862,6 +859,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
|
|||||||
for (j=0; j<4; j++) {//fp->nb_antennas_tx;j++) {
|
for (j=0; j<4; j++) {//fp->nb_antennas_tx;j++) {
|
||||||
int idx = (j<<1)+i;
|
int idx = (j<<1)+i;
|
||||||
pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*20*12*4 );
|
pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*20*12*4 );
|
||||||
|
pbch_vars[eNB_id]->dl_ch_estimates[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) );
|
||||||
pbch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*20*12*4 );
|
pbch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*20*12*4 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -882,7 +880,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
|
|||||||
if (abstraction_flag == 0) {
|
if (abstraction_flag == 0) {
|
||||||
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
||||||
//phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp );
|
//phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp );
|
||||||
(*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*8448)+12))*sizeof(int16_t) );
|
(*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
|
||||||
|
(*pdsch_vars_th)[th_id][eNB_id]->layer_llr[1] = (int16_t*)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { //abstraction == 1
|
} else { //abstraction == 1
|
||||||
@@ -920,14 +919,14 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) {
|
|||||||
for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
|
for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
|
||||||
for (j=0; j<2; j++) {
|
for (j=0; j<2; j++) {
|
||||||
for (k=0; k<RX_NB_TH_MAX; k++) {
|
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");
|
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[k][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_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);
|
ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
|
||||||
|
|
||||||
|
|||||||
@@ -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};
|
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 nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
|
||||||
int mu,
|
int mu,
|
||||||
int Ncp,
|
int Ncp,
|
||||||
@@ -52,12 +105,23 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
|
|||||||
case NR_MU_0: //15kHz scs
|
case NR_MU_0: //15kHz scs
|
||||||
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0];
|
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0];
|
||||||
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_0];
|
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_0];
|
||||||
|
fp->ssb_type = nr_ssb_type_A;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NR_MU_1: //30kHz scs
|
case NR_MU_1: //30kHz scs
|
||||||
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1];
|
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1];
|
||||||
fp->slots_per_subframe = nr_slots_per_subframe[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){
|
switch(N_RB_DL){
|
||||||
case 11:
|
case 11:
|
||||||
case 24:
|
case 24:
|
||||||
@@ -144,11 +208,13 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
|
|||||||
case NR_MU_3:
|
case NR_MU_3:
|
||||||
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
|
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
|
||||||
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
|
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
|
||||||
|
fp->ssb_type = nr_ssb_type_D;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NR_MU_4:
|
case NR_MU_4:
|
||||||
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4];
|
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4];
|
||||||
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_4];
|
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_4];
|
||||||
|
fp->ssb_type = nr_ssb_type_E;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -169,13 +235,16 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
|
|||||||
fp->samples_per_frame = 10 * fp->samples_per_subframe;
|
fp->samples_per_frame = 10 * fp->samples_per_subframe;
|
||||||
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
|
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
|
||||||
|
|
||||||
// Initial bandwidth part configuration -- full carrier bandwidth
|
// definition of Lmax according to ts 38.213 section 4.1
|
||||||
fp->initial_bwp_dl.bwp_id = 0;
|
if (fp->dl_CarrierFreq < 6e9){
|
||||||
fp->initial_bwp_dl.scs = fp->subcarrier_spacing;
|
if(fp->frame_type && (fp->ssb_type==2))
|
||||||
fp->initial_bwp_dl.location = 0;
|
fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8;
|
||||||
fp->initial_bwp_dl.N_RB = fp->N_RB_DL;
|
else
|
||||||
fp->initial_bwp_dl.cyclic_prefix = fp->Ncp;
|
fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8;
|
||||||
fp->initial_bwp_dl.ofdm_symbol_size = fp->ofdm_symbol_size;
|
}
|
||||||
|
else
|
||||||
|
fp->Lmax = 64;
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -184,7 +253,9 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
|
|||||||
NR_DL_FRAME_PARMS *fp)
|
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,
|
return nr_init_frame_parms0(fp,
|
||||||
config->subframe_config.numerology_index_mu.value,
|
config->subframe_config.numerology_index_mu.value,
|
||||||
config->subframe_config.dl_cyclic_prefix_type.value,
|
config->subframe_config.dl_cyclic_prefix_type.value,
|
||||||
@@ -215,10 +286,7 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
|
|||||||
LOG_I(PHY,"fp->samples_per_frame_wCP=%d\n",fp->samples_per_frame_wCP);
|
LOG_I(PHY,"fp->samples_per_frame_wCP=%d\n",fp->samples_per_frame_wCP);
|
||||||
LOG_I(PHY,"fp->samples_per_subframe=%d\n",fp->samples_per_subframe);
|
LOG_I(PHY,"fp->samples_per_subframe=%d\n",fp->samples_per_subframe);
|
||||||
LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame);
|
LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame);
|
||||||
LOG_I(PHY,"fp->initial_bwp_dl.bwp_id=%d\n",fp->initial_bwp_dl.bwp_id);
|
|
||||||
LOG_I(PHY,"fp->initial_bwp_dl.scs=%d\n",fp->initial_bwp_dl.scs);
|
|
||||||
LOG_I(PHY,"fp->initial_bwp_dl.N_RB=%d\n",fp->initial_bwp_dl.N_RB);
|
|
||||||
LOG_I(PHY,"fp->initial_bwp_dl.cyclic_prefix=%d\n",fp->initial_bwp_dl.cyclic_prefix);
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
|
||||||
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
|
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(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 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);
|
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);
|
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);
|
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(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);
|
void phy_free_nr_gNB(PHY_VARS_gNB *gNB);
|
||||||
int l1_north_init_gNB(void);
|
int l1_north_init_gNB(void);
|
||||||
void init_nr_transport(PHY_VARS_gNB *gNB);
|
void init_nr_transport(PHY_VARS_gNB *gNB);
|
||||||
|
|
||||||
void init_dfts(void);
|
void init_dfts(void);
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,6 @@
|
|||||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||||
#include "common/utils/LOG/log.h"
|
#include "common/utils/LOG/log.h"
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
#include "targets/RT/USER/rt_wrapper.h"
|
|
||||||
|
|
||||||
//#define DEBUG_DLSCH_CODING
|
//#define DEBUG_DLSCH_CODING
|
||||||
//#define DEBUG_DLSCH_FREE 1
|
//#define DEBUG_DLSCH_FREE 1
|
||||||
@@ -337,14 +336,6 @@ int dlsch_encoding_2threads0(te_params *tep) {
|
|||||||
|
|
||||||
extern int oai_exit;
|
extern int oai_exit;
|
||||||
void *te_thread(void *param) {
|
void *te_thread(void *param) {
|
||||||
cpu_set_t cpuset;
|
|
||||||
CPU_ZERO(&cpuset);
|
|
||||||
|
|
||||||
thread_top_init("te_thread",1,200000,250000,500000);
|
|
||||||
pthread_setname_np( pthread_self(),"te processing");
|
|
||||||
LOG_I(PHY,"thread te created id=%ld\n", syscall(__NR_gettid));
|
|
||||||
|
|
||||||
|
|
||||||
te_params *tep = (te_params *)param;
|
te_params *tep = (te_params *)param;
|
||||||
|
|
||||||
//wait_sync("te_thread");
|
//wait_sync("te_thread");
|
||||||
|
|||||||
@@ -42,7 +42,6 @@
|
|||||||
|
|
||||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||||
//#define DEBUG_ULSCH_DECODING
|
//#define DEBUG_ULSCH_DECODING
|
||||||
#include "targets/RT/USER/rt_wrapper.h"
|
|
||||||
#include "transport_proto.h"
|
#include "transport_proto.h"
|
||||||
|
|
||||||
extern WORKER_CONF_t get_thread_worker_conf(void);
|
extern WORKER_CONF_t get_thread_worker_conf(void);
|
||||||
@@ -383,10 +382,7 @@ extern int oai_exit;
|
|||||||
void *td_thread(void *param) {
|
void *td_thread(void *param) {
|
||||||
PHY_VARS_eNB *eNB = ((td_params*)param)->eNB;
|
PHY_VARS_eNB *eNB = ((td_params*)param)->eNB;
|
||||||
eNB_proc_t *proc = &eNB->proc;
|
eNB_proc_t *proc = &eNB->proc;
|
||||||
cpu_set_t cpuset;
|
|
||||||
CPU_ZERO(&cpuset);
|
|
||||||
|
|
||||||
thread_top_init("td_thread",1,200000,250000,500000);
|
|
||||||
pthread_setname_np( pthread_self(),"td processing");
|
pthread_setname_np( pthread_self(),"td processing");
|
||||||
LOG_I(PHY,"thread td created id=%ld\n", syscall(__NR_gettid));
|
LOG_I(PHY,"thread td created id=%ld\n", syscall(__NR_gettid));
|
||||||
//wait_sync("td_thread");
|
//wait_sync("td_thread");
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ typedef struct {
|
|||||||
/// allocated CBA RNTI
|
/// 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
|
/// UL max-harq-retransmission
|
||||||
uint8_t Mlimit;
|
uint16_t Mlimit;
|
||||||
} LTE_UE_ULSCH_t;
|
} LTE_UE_ULSCH_t;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,9 +52,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
unsigned char l,
|
unsigned char l,
|
||||||
unsigned char Ns,
|
unsigned char Ns,
|
||||||
int sample_offset,
|
int sample_offset,
|
||||||
int no_prefix,
|
int no_prefix);
|
||||||
int reset_freq_est,
|
|
||||||
NR_CHANNEL_EST_t channel);
|
|
||||||
|
|
||||||
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
|
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
|
||||||
unsigned char l,
|
unsigned char l,
|
||||||
|
|||||||
@@ -35,38 +35,30 @@
|
|||||||
#endif*/
|
#endif*/
|
||||||
|
|
||||||
int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||||
unsigned char l,
|
unsigned char symbol,
|
||||||
unsigned char Ns,
|
unsigned char Ns,
|
||||||
int sample_offset,
|
int sample_offset,
|
||||||
int no_prefix,
|
int no_prefix)
|
||||||
int reset_freq_est,
|
|
||||||
NR_CHANNEL_EST_t channel)
|
|
||||||
{
|
{
|
||||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||||
NR_UE_COMMON *common_vars = &ue->common_vars;
|
NR_UE_COMMON *common_vars = &ue->common_vars;
|
||||||
uint8_t eNB_id = 0;//ue_common_vars->eNb_id;
|
|
||||||
unsigned char aa;
|
unsigned char aa;
|
||||||
unsigned char symbol = l;//+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
|
unsigned int nb_prefix_samples;
|
||||||
unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
unsigned int nb_prefix_samples0;
|
||||||
unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->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 subframe_offset;//,subframe_offset_F;
|
||||||
unsigned int slot_offset;
|
unsigned int slot_offset;
|
||||||
//int i;
|
//int i;
|
||||||
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
|
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
|
||||||
unsigned int rx_offset;
|
unsigned int rx_offset;
|
||||||
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 = 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);
|
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
|
int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
|
||||||
@@ -140,7 +132,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
|||||||
nb_prefix_samples,nb_prefix_samples0,slot_offset,sample_offset,rx_offset,frame_length_samples);
|
nb_prefix_samples,nb_prefix_samples0,slot_offset,sample_offset,rx_offset,frame_length_samples);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (l==0) {
|
if (symbol==0) {
|
||||||
|
|
||||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||||
memcpy((short *)&common_vars->rxdata[aa][frame_length_samples],
|
memcpy((short *)&common_vars->rxdata[aa][frame_length_samples],
|
||||||
@@ -165,7 +157,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// +
|
rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*symbol;// +
|
||||||
// (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
|
// (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
|
||||||
|
|
||||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||||
@@ -200,107 +192,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ue->perfect_ce == 0) {
|
|
||||||
|
|
||||||
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);
|
|
||||||
#endif
|
|
||||||
#if UE_TIMING_TRACE
|
|
||||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
|
||||||
#endif
|
|
||||||
nr_pdcch_channel_estimation(ue,eNB_id,0,
|
|
||||||
Ns,
|
|
||||||
l,
|
|
||||||
symbol,
|
|
||||||
coreset_start_subcarrier,
|
|
||||||
nb_rb_coreset);
|
|
||||||
#if UE_TIMING_TRACE
|
|
||||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NR_PDSCH_EST:
|
|
||||||
#ifdef DEBUG_FEP
|
|
||||||
printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l);
|
|
||||||
#endif
|
|
||||||
#if UE_TIMING_TRACE
|
|
||||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ue->frame_parms.nushift = (p>>1)&1;;
|
|
||||||
|
|
||||||
if (symbol ==l0)
|
|
||||||
nr_pdsch_channel_estimation(ue,eNB_id,0,
|
|
||||||
Ns,
|
|
||||||
p,
|
|
||||||
l,
|
|
||||||
symbol,
|
|
||||||
bwp_start_subcarrier,
|
|
||||||
nb_rb_pdsch);
|
|
||||||
|
|
||||||
#if UE_TIMING_TRACE
|
|
||||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NR_SSS_EST:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
LOG_E(PHY,"[UE][FATAL] Unknown channel format %d\n",channel);
|
|
||||||
return(-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_FEP
|
#ifdef DEBUG_FEP
|
||||||
printf("slot_fep: done\n");
|
printf("slot_fep: done\n");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB)
|
|||||||
|
|
||||||
Nid = cfg->sch_config.physical_cell_id.value;
|
Nid = cfg->sch_config.physical_cell_id.value;
|
||||||
|
|
||||||
Lmax = (fp->dl_CarrierFreq < 3e9)? 4:8;
|
Lmax = fp->Lmax;
|
||||||
N_hf = (Lmax == 4)? 2:1;
|
N_hf = (Lmax == 4)? 2:1;
|
||||||
|
|
||||||
for (n_hf = 0; n_hf < N_hf; n_hf++) {
|
for (n_hf = 0; n_hf < N_hf; n_hf++) {
|
||||||
for (l = 0; l < Lmax ; l++) {
|
for (l = 0; l < Lmax ; l++) {
|
||||||
i_ssb = l & (Lmax-1);
|
i_ssb = l & (Lmax-1);
|
||||||
i_ssb2 = (i_ssb<<2) + n_hf;
|
i_ssb2 = i_ssb + (n_hf<<2);
|
||||||
|
|
||||||
reset = 1;
|
reset = 1;
|
||||||
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
|
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
|
||||||
|
|||||||
@@ -29,15 +29,14 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue)
|
|||||||
unsigned char Lmax, l, n_hf, N_hf;
|
unsigned char Lmax, l, n_hf, N_hf;
|
||||||
|
|
||||||
Nid = ue->frame_parms.Nid_cell;
|
Nid = ue->frame_parms.Nid_cell;
|
||||||
|
Lmax = ue->frame_parms.Lmax;
|
||||||
Lmax = 8; //(fp->dl_CarrierFreq < 3e9)? 4:8;
|
|
||||||
N_hf = (Lmax == 4)? 2:1;
|
N_hf = (Lmax == 4)? 2:1;
|
||||||
|
|
||||||
for (n_hf = 0; n_hf < N_hf; n_hf++) {
|
for (n_hf = 0; n_hf < N_hf; n_hf++) {
|
||||||
|
|
||||||
for (l = 0; l < Lmax ; l++) {
|
for (l = 0; l < Lmax ; l++) {
|
||||||
i_ssb = l & (Lmax-1);
|
i_ssb = l & (Lmax-1);
|
||||||
i_ssb2 = (i_ssb<<2) + n_hf;
|
i_ssb2 = i_ssb + (n_hf<<2);
|
||||||
|
|
||||||
x1 = 1 + (1<<31);
|
x1 = 1 + (1<<31);
|
||||||
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
|
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nr_dci.h"
|
#include "nr_dci.h"
|
||||||
|
#include "nr_dlsch.h"
|
||||||
|
|
||||||
//#define DEBUG_PDCCH_DMRS
|
//#define DEBUG_PDCCH_DMRS
|
||||||
//#define DEBUG_DCI
|
//#define DEBUG_DCI
|
||||||
|
|||||||
@@ -25,8 +25,6 @@
|
|||||||
#include "PHY/defs_gNB.h"
|
#include "PHY/defs_gNB.h"
|
||||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||||
|
|
||||||
typedef unsigned __int128 uint128_t;
|
|
||||||
|
|
||||||
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
|
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
|
||||||
nfapi_nr_rnti_type_e rnti_type,
|
nfapi_nr_rnti_type_e rnti_type,
|
||||||
uint16_t N_RB,
|
uint16_t N_RB,
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m
|
|||||||
uint8_t bsize = pdcch_params->reg_bundle_size;
|
uint8_t bsize = pdcch_params->reg_bundle_size;
|
||||||
uint8_t R = pdcch_params->interleaver_size;
|
uint8_t R = pdcch_params->interleaver_size;
|
||||||
uint16_t N_reg = pdcch_params->n_rb * pdcch_params->n_symb;
|
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 Y, N_cce, M_s_max, n_CI=0, tmp, C=0;
|
||||||
uint16_t n_RNTI = (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params->rnti:0;
|
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};
|
uint32_t A[3]={39827,39829,39839};
|
||||||
|
|
||||||
@@ -64,9 +64,9 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
|
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",
|
uint16_t assertFatalCond = (N_reg%(bsize*R));
|
||||||
N_reg, bsize, R);
|
AssertFatal(assertFatalCond == 0,"CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",N_reg, bsize, R);
|
||||||
C = N_reg/(bsize*R);
|
C = N_reg/(bsize*R);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = L * (( Y + (m*N_cce)/(L*M_s_max) + n_CI ) % CEILIDIV(N_cce,L));
|
tmp = L * (( Y + (m*N_cce)/(L*M_s_max) + n_CI ) % CEILIDIV(N_cce,L));
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch,
|
|||||||
nr_dlsch_encoding(harq->pdu, slot, &dlsch, &frame_parms);
|
nr_dlsch_encoding(harq->pdu, slot, &dlsch, &frame_parms);
|
||||||
#ifdef DEBUG_DLSCH
|
#ifdef DEBUG_DLSCH
|
||||||
printf("PDSCH encoding:\nPayload:\n");
|
printf("PDSCH encoding:\nPayload:\n");
|
||||||
for (int i=0; i<TBS>>7; i++) {
|
for (int i=0; i<harq->B>>7; i++) {
|
||||||
for (int j=0; j<16; j++)
|
for (int j=0; j<16; j++)
|
||||||
printf("0x%02x\t", harq->pdu[(i<<4)+j]);
|
printf("0x%02x\t", harq->pdu[(i<<4)+j]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@@ -233,7 +233,7 @@ printf("\n");
|
|||||||
for (int q=0; q<rel15->nb_codewords; q++)
|
for (int q=0; q<rel15->nb_codewords; q++)
|
||||||
memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t));
|
memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t));
|
||||||
uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \
|
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;
|
((pdcch_params.scrambling_id==0)?pdcch_params.rnti:0) : 0;
|
||||||
uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \
|
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;
|
pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value;
|
||||||
for (int q=0; q<rel15->nb_codewords; q++)
|
for (int q=0; q<rel15->nb_codewords; q++)
|
||||||
@@ -308,16 +308,13 @@ for (int i=0; i<n_dmrs>>4; i++) {
|
|||||||
|
|
||||||
|
|
||||||
// Non interleaved VRB to PRB mapping
|
// Non interleaved VRB to PRB mapping
|
||||||
uint16_t start_sc = frame_parms.first_carrier_offset + frame_parms.ssb_start_subcarrier;
|
uint16_t start_sc = frame_parms.first_carrier_offset + rel15->start_prb*NR_NB_SC_PER_RB;
|
||||||
if (start_sc >= frame_parms.ofdm_symbol_size)
|
if (start_sc >= frame_parms.ofdm_symbol_size)
|
||||||
start_sc -= frame_parms.ofdm_symbol_size;
|
start_sc -= frame_parms.ofdm_symbol_size;
|
||||||
/*rel15->start_prb*NR_NB_SC_PER_RB +
|
|
||||||
((pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON) && (pdcch_params.dci_format == NFAPI_NR_DL_DCI_FORMAT_1_0))?\
|
|
||||||
((frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB + pdcch_params.rb_offset)*NR_NB_SC_PER_RB) : 0;*/
|
|
||||||
|
|
||||||
#ifdef DEBUG_DLSCH_MAPPING
|
#ifdef DEBUG_DLSCH_MAPPING
|
||||||
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n",
|
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n",
|
||||||
start_sc, rel15->start_symbol, rel15->n_prb, rel15->nb_symbols);
|
start_sc, rel15->start_symbol, rel15->n_prb, rel15->nb_symbols);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int ap=0; ap<rel15->nb_layers; ap++) {
|
for (int ap=0; ap<rel15->nb_layers; ap++) {
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ void nr_pdsch_codeword_scrambling(uint8_t *in,
|
|||||||
uint32_t n_RNTI,
|
uint32_t n_RNTI,
|
||||||
uint32_t* out);
|
uint32_t* out);
|
||||||
|
|
||||||
|
void nr_modulation(uint32_t *in,
|
||||||
|
uint16_t length,
|
||||||
|
nr_mod_t modulation_type,
|
||||||
|
int16_t *out);
|
||||||
|
|
||||||
void nr_pdsch_codeword_modulation(uint32_t *in,
|
void nr_pdsch_codeword_modulation(uint32_t *in,
|
||||||
uint8_t Qm,
|
uint8_t Qm,
|
||||||
uint32_t length,
|
uint32_t length,
|
||||||
@@ -96,6 +101,8 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
|
|||||||
|
|
||||||
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
|
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
|
||||||
|
|
||||||
|
void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
|
||||||
|
|
||||||
int nr_dlsch_encoding(unsigned char *a,
|
int nr_dlsch_encoding(unsigned char *a,
|
||||||
uint8_t subframe,
|
uint8_t subframe,
|
||||||
NR_gNB_DLSCH_t *dlsch,
|
NR_gNB_DLSCH_t *dlsch,
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dlsch->harq_processes[i]->b) {
|
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;
|
dlsch->harq_processes[i]->b = NULL;
|
||||||
#ifdef DEBUG_DLSCH_FREE
|
#ifdef DEBUG_DLSCH_FREE
|
||||||
printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
|
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) {
|
if (abstraction_flag==0) {
|
||||||
for (r=0; r<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling; r++) {
|
for (r=0; r<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling; r++) {
|
||||||
// account for filler in first segment and CRCs for multiple segment case
|
// 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]->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]) {
|
if (dlsch->harq_processes[i]->c[r]) {
|
||||||
bzero(dlsch->harq_processes[i]->c[r],8448);
|
bzero(dlsch->harq_processes[i]->c[r],8448);
|
||||||
} else {
|
} else {
|
||||||
@@ -272,7 +275,6 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
|
|
||||||
unsigned int G;
|
unsigned int G;
|
||||||
unsigned int crc=1;
|
unsigned int crc=1;
|
||||||
|
|
||||||
uint8_t harq_pid = dlsch->harq_ids[slot];
|
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;
|
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;
|
uint16_t nb_rb = rel15.n_prb;
|
||||||
@@ -280,8 +282,8 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
uint32_t A, Z, F=0;
|
uint32_t A, Z, F=0;
|
||||||
uint32_t *pz = &Z;
|
uint32_t *pz = &Z;
|
||||||
uint8_t mod_order = rel15.modulation_order;
|
uint8_t mod_order = rel15.modulation_order;
|
||||||
uint16_t Kr=0,r,r_offset=0,Kr_bytes;
|
uint16_t Kr=0,r,r_offset=0;
|
||||||
uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
|
//uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
|
||||||
uint8_t BG=1;
|
uint8_t BG=1;
|
||||||
uint32_t E;
|
uint32_t E;
|
||||||
uint8_t Ilbrm = 0;
|
uint8_t Ilbrm = 0;
|
||||||
@@ -302,8 +304,10 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
A = rel15.transport_block_size;
|
A = rel15.transport_block_size;
|
||||||
|
|
||||||
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15.nb_layers);
|
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);
|
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);
|
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, rel15.nb_layers);
|
||||||
|
|
||||||
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
|
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
|
||||||
@@ -328,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+24;
|
||||||
// dlsch->harq_processes[harq_pid]->b = a;
|
// dlsch->harq_processes[harq_pid]->b = a;
|
||||||
|
|
||||||
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
|
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
|
||||||
|
|
||||||
nr_segmentation(dlsch->harq_processes[harq_pid]->b,
|
nr_segmentation(dlsch->harq_processes[harq_pid]->b,
|
||||||
@@ -335,7 +340,7 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
dlsch->harq_processes[harq_pid]->B,
|
dlsch->harq_processes[harq_pid]->B,
|
||||||
&dlsch->harq_processes[harq_pid]->C,
|
&dlsch->harq_processes[harq_pid]->C,
|
||||||
&dlsch->harq_processes[harq_pid]->K,
|
&dlsch->harq_processes[harq_pid]->K,
|
||||||
pz,
|
pz, // [hna] pz is Zc
|
||||||
&dlsch->harq_processes[harq_pid]->F);
|
&dlsch->harq_processes[harq_pid]->F);
|
||||||
|
|
||||||
F = dlsch->harq_processes[harq_pid]->F;
|
F = dlsch->harq_processes[harq_pid]->F;
|
||||||
@@ -349,13 +354,16 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Kr = dlsch->harq_processes[harq_pid]->K;
|
Kr = dlsch->harq_processes[harq_pid]->K;
|
||||||
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
|
uint16_t Kr_bytes;
|
||||||
Kr_bytes = Kr>>3;
|
Kr_bytes = Kr>>3;
|
||||||
|
#endif
|
||||||
|
|
||||||
//printf("segment Z %d k %d Kr %d BG %d\n", *pz,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);
|
//start_meas(te_stats);
|
||||||
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
|
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
|
||||||
d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][0];
|
//d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][0];
|
||||||
//channel_input[r] = &dlsch->harq_processes[harq_pid]->d[r][0];
|
//channel_input[r] = &dlsch->harq_processes[harq_pid]->d[r][0];
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
printf("Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F);
|
printf("Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F);
|
||||||
@@ -429,6 +437,7 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
rel15.redundancy_version,
|
rel15.redundancy_version,
|
||||||
E);
|
E);
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
for (int i =0; i<16; i++)
|
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);
|
printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset);
|
||||||
@@ -442,6 +451,7 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
dlsch->harq_processes[harq_pid]->f+r_offset);
|
dlsch->harq_processes[harq_pid]->f+r_offset);
|
||||||
//stop_meas(i_stats);
|
//stop_meas(i_stats);
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
for (int i =0; i<16; i++)
|
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);
|
printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset);
|
||||||
@@ -455,5 +465,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);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
|
||||||
|
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -425,9 +425,11 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
|
|||||||
m++;
|
m++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (k >= frame_parms->ofdm_symbol_size)
|
if (k >= frame_parms->ofdm_symbol_size)
|
||||||
k-=frame_parms->ofdm_symbol_size;
|
k-=frame_parms->ofdm_symbol_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ int nr_generate_pss( int16_t *d_pss,
|
|||||||
/// Resource mapping
|
/// Resource mapping
|
||||||
a = amp;
|
a = amp;
|
||||||
|
|
||||||
|
|
||||||
// PSS occupies a predefined position (subcarriers 56-182, symbol 0) within the SSB block starting from
|
// 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
|
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;
|
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
|
||||||
|
|||||||
@@ -112,12 +112,9 @@ void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
|
|||||||
nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15;
|
nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15;
|
||||||
nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &dlsch_pdu->dlsch_pdu_rel15;
|
nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &dlsch_pdu->dlsch_pdu_rel15;
|
||||||
uint8_t rnti_type = params_rel15.rnti_type;
|
uint8_t rnti_type = params_rel15.rnti_type;
|
||||||
uint8_t dci_format = params_rel15.dci_format;
|
|
||||||
uint8_t ss_type = params_rel15.search_space_type;
|
|
||||||
uint8_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \
|
uint8_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \
|
||||||
(config.pdsch_config.x_overhead.value);
|
(config.pdsch_config.x_overhead.value);
|
||||||
uint8_t N_PRB_DMRS = (config.pdsch_config.dmrs_type.value == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000
|
uint8_t N_PRB_DMRS = (config.pdsch_config.dmrs_type.value == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000
|
||||||
uint8_t mcs_table = config.pdsch_config.mcs_table.value;
|
|
||||||
uint8_t N_sh_symb = dlsch_rel15->nb_symbols;
|
uint8_t N_sh_symb = dlsch_rel15->nb_symbols;
|
||||||
uint8_t Imcs = dlsch_rel15->mcs_idx;
|
uint8_t Imcs = dlsch_rel15->mcs_idx;
|
||||||
uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh;
|
uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh;
|
||||||
@@ -126,7 +123,11 @@ void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
|
|||||||
uint16_t N_RE, Ninfo, Ninfo_prime, C, TBS=0, R;
|
uint16_t N_RE, Ninfo, Ninfo_prime, C, TBS=0, R;
|
||||||
uint8_t table_idx, Qm, n, scale;
|
uint8_t table_idx, Qm, n, scale;
|
||||||
|
|
||||||
table_idx = get_table_idx(mcs_table, dci_format, rnti_type, ss_type);
|
/*uint8_t mcs_table = config.pdsch_config.mcs_table.value;
|
||||||
|
uint8_t ss_type = params_rel15.search_space_type;
|
||||||
|
uint8_t dci_format = params_rel15.dci_format;
|
||||||
|
get_table_idx(mcs_table, dci_format, rnti_type, ss_type);*/
|
||||||
|
table_idx = 1;
|
||||||
scale = ((table_idx==2)&&((Imcs==20)||(Imcs==26)))?11:10;
|
scale = ((table_idx==2)&&((Imcs==20)||(Imcs==26)))?11:10;
|
||||||
|
|
||||||
N_RE = min(156, N_RE_prime)*dlsch_rel15->n_prb;
|
N_RE = min(156, N_RE_prime)*dlsch_rel15->n_prb;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS
|
#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_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_CHANNEL_BITS (14*273*12*6) // 14 symbols, 273 RB
|
||||||
#define MAX_NUM_NR_RE (14*273*12)
|
#define MAX_NUM_NR_RE (14*273*12)
|
||||||
|
|||||||
@@ -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,709 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
|
||||||
|
{
|
||||||
|
unsigned char i, j;
|
||||||
|
|
||||||
|
if (ulsch) {
|
||||||
|
ulsch->harq_mask = 0;
|
||||||
|
ulsch->bundling = 0;
|
||||||
|
ulsch->beta_offset_cqi_times8 = 0;
|
||||||
|
ulsch->beta_offset_ri_times8 = 0;
|
||||||
|
ulsch->beta_offset_harqack_times8 = 0;
|
||||||
|
ulsch->Msg3_active = 0;
|
||||||
|
ulsch->Msg3_flag = 0;
|
||||||
|
ulsch->Msg3_subframe = 0;
|
||||||
|
ulsch->Msg3_frame = 0;
|
||||||
|
ulsch->rnti = 0;
|
||||||
|
ulsch->rnti_type = 0;
|
||||||
|
ulsch->cyclicShift = 0;
|
||||||
|
ulsch->cooperation_flag = 0;
|
||||||
|
ulsch->Mlimit = 0;
|
||||||
|
ulsch->max_ldpc_iterations = 0;
|
||||||
|
ulsch->last_iteration_cnt = 0;
|
||||||
|
ulsch->num_active_cba_groups = 0;
|
||||||
|
for (i=0;i<NUM_MAX_CBA_GROUP;i++) ulsch->cba_rnti[i] = 0;
|
||||||
|
for (i=0;i<NR_MAX_SLOTS_PER_FRAME;i++) ulsch->harq_process_id[i] = 0;
|
||||||
|
|
||||||
|
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
|
||||||
|
if (ulsch->harq_processes[i]){
|
||||||
|
/// Nfapi ULSCH PDU
|
||||||
|
//nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
|
||||||
|
ulsch->harq_processes[i]->frame=0;
|
||||||
|
ulsch->harq_processes[i]->subframe=0;
|
||||||
|
ulsch->harq_processes[i]->round=0;
|
||||||
|
ulsch->harq_processes[i]->TPC=0;
|
||||||
|
ulsch->harq_processes[i]->mimo_mode=0;
|
||||||
|
ulsch->harq_processes[i]->dci_alloc=0;
|
||||||
|
ulsch->harq_processes[i]->rar_alloc=0;
|
||||||
|
ulsch->harq_processes[i]->status=0;
|
||||||
|
ulsch->harq_processes[i]->subframe_scheduling_flag=0;
|
||||||
|
ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0;
|
||||||
|
ulsch->harq_processes[i]->phich_active=0;
|
||||||
|
ulsch->harq_processes[i]->phich_ACK=0;
|
||||||
|
ulsch->harq_processes[i]->previous_first_rb=0;
|
||||||
|
ulsch->harq_processes[i]->handled=0;
|
||||||
|
ulsch->harq_processes[i]->delta_TF=0;
|
||||||
|
|
||||||
|
ulsch->harq_processes[i]->TBS=0;
|
||||||
|
/// Pointer to the payload (38.212 V15.4.0 section 5.1)
|
||||||
|
//uint8_t *b;
|
||||||
|
ulsch->harq_processes[i]->B=0;
|
||||||
|
/// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
|
||||||
|
//uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS];
|
||||||
|
ulsch->harq_processes[i]->K=0;
|
||||||
|
ulsch->harq_processes[i]->F=0;
|
||||||
|
ulsch->harq_processes[i]->C=0;
|
||||||
|
/// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
|
||||||
|
//int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
|
||||||
|
/// LDPC processing buffer
|
||||||
|
//t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS];
|
||||||
|
ulsch->harq_processes[i]->Z=0;
|
||||||
|
/// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
|
||||||
|
//int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
|
||||||
|
ulsch->harq_processes[i]->E=0;
|
||||||
|
ulsch->harq_processes[i]->G=0;
|
||||||
|
|
||||||
|
|
||||||
|
ulsch->harq_processes[i]->n_DMRS=0;
|
||||||
|
ulsch->harq_processes[i]->n_DMRS2=0;
|
||||||
|
ulsch->harq_processes[i]->previous_n_DMRS=0;
|
||||||
|
|
||||||
|
|
||||||
|
ulsch->harq_processes[i]->cqi_crc_status=0;
|
||||||
|
for (j=0;j<MAX_CQI_BYTES;j++) ulsch->harq_processes[i]->o[j]=0;
|
||||||
|
ulsch->harq_processes[i]->uci_format=0;
|
||||||
|
ulsch->harq_processes[i]->Or1=0;
|
||||||
|
ulsch->harq_processes[i]->Or2=0;
|
||||||
|
ulsch->harq_processes[i]->o_RI[0]=0; ulsch->harq_processes[i]->o_RI[1]=0;
|
||||||
|
ulsch->harq_processes[i]->O_RI=0;
|
||||||
|
ulsch->harq_processes[i]->o_ACK[0]=0; ulsch->harq_processes[i]->o_ACK[1]=0;
|
||||||
|
ulsch->harq_processes[i]->o_ACK[2]=0; ulsch->harq_processes[i]->o_ACK[3]=0;
|
||||||
|
ulsch->harq_processes[i]->O_ACK=0;
|
||||||
|
ulsch->harq_processes[i]->V_UL_DAI=0;
|
||||||
|
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
|
||||||
|
//int8_t q[MAX_CQI_PAYLOAD];
|
||||||
|
ulsch->harq_processes[i]->o_RCC=0;
|
||||||
|
/// coded and interleaved CQI bits
|
||||||
|
//int8_t o_w[(MAX_CQI_BITS+8)*3];
|
||||||
|
/// coded CQI bits
|
||||||
|
//int8_t o_d[96+((MAX_CQI_BITS+8)*3)];
|
||||||
|
for (j=0;j<MAX_ACK_PAYLOAD;j++) ulsch->harq_processes[i]->q_ACK[j]=0;
|
||||||
|
for (j=0;j<MAX_RI_PAYLOAD;j++) ulsch->harq_processes[i]->q_RI[j]=0;
|
||||||
|
/// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
|
||||||
|
//uint8_t h[MAX_NUM_CHANNEL_BITS];
|
||||||
|
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||||
|
//int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
ncoef = 32767 - coef;
|
||||||
|
|
||||||
//#ifdef DEBUG_PHY
|
LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset);
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
// we only use channel estimates from tx antenna 0 here
|
// we only use channel estimates from tx antenna 0 here
|
||||||
@@ -62,8 +60,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
temp = 0;
|
temp = 0;
|
||||||
|
|
||||||
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||||
Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<1)];
|
Re = ((int16_t*)ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
|
||||||
Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<1)];
|
Im = ((int16_t*)ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
|
||||||
temp += (Re*Re/2) + (Im*Im/2);
|
temp += (Re*Re/2) + (Im*Im/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,8 +120,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_PHY
|
#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",
|
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",
|
||||||
ue->proc.proc_rxtx[ue->current_thread_id[subframe]].frame_rx,
|
|
||||||
subframe,
|
subframe,
|
||||||
ue->current_thread_id[subframe],
|
ue->current_thread_id[subframe],
|
||||||
diff,
|
diff,
|
||||||
|
|||||||
@@ -22,55 +22,42 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
//#include "defs.h"
|
#include "nr_estimation.h"
|
||||||
//#include "SCHED/defs.h"
|
|
||||||
#include "PHY/defs_nr_UE.h"
|
|
||||||
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
|
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
|
||||||
#include "filt16a_32.h"
|
#include "filt16a_32.h"
|
||||||
#include "T.h"
|
|
||||||
//#define DEBUG_PDSCH
|
//#define DEBUG_PDSCH
|
||||||
//#define DEBUG_PDCCH
|
//#define DEBUG_PDCCH
|
||||||
|
|
||||||
|
|
||||||
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
|
||||||
uint8_t eNB_id,
|
|
||||||
uint8_t eNB_offset,
|
uint8_t eNB_offset,
|
||||||
unsigned char Ns,
|
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)));
|
int pilot[200] __attribute__((aligned(16)));
|
||||||
unsigned char aarx;
|
unsigned char aarx;
|
||||||
unsigned short k;
|
unsigned short k;
|
||||||
unsigned int pilot_cnt;
|
unsigned int pilot_cnt;
|
||||||
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
|
int16_t ch[2],*pil,*rxF;
|
||||||
int ch_offset,symbol_offset;
|
int symbol_offset;
|
||||||
int dmrss;
|
|
||||||
|
|
||||||
//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;
|
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];
|
uint8_t ssb_index=current_ssb->i_ssb;
|
||||||
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
|
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;
|
nushift = ue->frame_parms.Nid_cell%4;
|
||||||
ue->frame_parms.nushift = nushift;
|
ue->frame_parms.nushift = nushift;
|
||||||
|
|
||||||
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
|
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 (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
|
||||||
|
|
||||||
if (ue->is_synchronized ==0 ) dmrss = symbol-1;
|
AssertFatal(dmrss >= 0 && dmrss < 3,
|
||||||
else dmrss = symbol-5;
|
"symbol %d is illegal for PBCH DM-RS \n",
|
||||||
|
dmrss);
|
||||||
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);
|
|
||||||
|
|
||||||
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
|
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
|
||||||
|
|
||||||
@@ -78,8 +65,175 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
k = nushift;
|
k = nushift;
|
||||||
|
|
||||||
#ifdef DEBUG_CH
|
#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,
|
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,l,Ns,k, symbol);
|
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->pbch_vars[eNB_offset]->dl_ch_estimates;
|
||||||
|
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
|
#endif
|
||||||
|
|
||||||
switch (k) {
|
switch (k) {
|
||||||
@@ -139,6 +293,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
// Treat first 2 pilots specially (left edge)
|
// 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[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);
|
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||||
|
|
||||||
#ifdef DEBUG_CH
|
#ifdef DEBUG_CH
|
||||||
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
|
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
|
||||||
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
|
printf("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]);
|
||||||
@@ -156,6 +311,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[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);
|
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_CH
|
#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]);
|
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
|
#endif
|
||||||
@@ -167,9 +324,6 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
|
re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
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
|
#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]);
|
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
|
#endif
|
||||||
@@ -197,6 +351,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[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);
|
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||||
|
|
||||||
#ifdef DEBUG_CH
|
#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]);
|
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
|
#endif
|
||||||
@@ -215,6 +370,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[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);
|
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||||
|
|
||||||
#ifdef DEBUG_CH
|
#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]);
|
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
|
#endif
|
||||||
@@ -249,15 +405,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||||
uint8_t eNB_id,
|
|
||||||
uint8_t eNB_offset,
|
uint8_t eNB_offset,
|
||||||
unsigned char Ns,
|
unsigned char Ns,
|
||||||
unsigned char l,
|
|
||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
unsigned short coreset_start_subcarrier,
|
unsigned short coreset_start_subcarrier,
|
||||||
unsigned short nb_rb_coreset)
|
unsigned short nb_rb_coreset)
|
||||||
@@ -272,7 +425,7 @@ 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];
|
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
|
||||||
|
|
||||||
uint8_t nushift;
|
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 **dl_ch_estimates =ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates;
|
||||||
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
|
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
|
||||||
|
|
||||||
nushift = 1;
|
nushift = 1;
|
||||||
@@ -460,16 +613,16 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (Ns== 1) && (l == 0))
|
if( (Ns== 1) && (symbol == 0))
|
||||||
{
|
{
|
||||||
// do ifft of channel estimate
|
// do ifft of channel estimate
|
||||||
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
|
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
|
||||||
for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
|
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]].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
|
if (ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx])
|
||||||
{
|
{
|
||||||
LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], l);
|
LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], symbol);
|
||||||
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],
|
idft((int16_t*) &ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(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);
|
(int16_t*) ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -478,14 +631,12 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int nr_pdsch_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,
|
||||||
uint8_t eNB_offset,
|
unsigned char Ns,
|
||||||
unsigned char Ns,
|
unsigned short p,
|
||||||
unsigned short p,
|
unsigned char symbol,
|
||||||
unsigned char l,
|
unsigned short bwp_start_subcarrier,
|
||||||
unsigned char symbol,
|
unsigned short nb_rb_pdsch)
|
||||||
unsigned short bwp_start_subcarrier,
|
|
||||||
unsigned short nb_rb_pdsch)
|
|
||||||
{
|
{
|
||||||
int pilot[1320] __attribute__((aligned(16)));
|
int pilot[1320] __attribute__((aligned(16)));
|
||||||
unsigned char aarx;
|
unsigned char aarx;
|
||||||
@@ -497,7 +648,7 @@ 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];
|
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
|
||||||
|
|
||||||
uint8_t nushift;
|
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 **dl_ch_estimates =ue->pdsch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates;
|
||||||
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
|
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
|
||||||
|
|
||||||
nushift = (p>>1)&1;
|
nushift = (p>>1)&1;
|
||||||
|
|||||||
@@ -43,30 +43,35 @@
|
|||||||
\param symbol symbol within frame
|
\param symbol symbol within frame
|
||||||
*/
|
*/
|
||||||
int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||||
uint8_t eNB_id,
|
|
||||||
uint8_t eNB_offset,
|
uint8_t eNB_offset,
|
||||||
unsigned char Ns,
|
unsigned char Ns,
|
||||||
unsigned char l,
|
|
||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
unsigned short coreset_start_subcarrier,
|
unsigned short coreset_start_subcarrier,
|
||||||
unsigned short nb_rb_coreset);
|
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,
|
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||||
uint8_t eNB_id,
|
uint8_t eNB_offset,
|
||||||
uint8_t eNB_offset,
|
unsigned char Ns,
|
||||||
unsigned char Ns,
|
unsigned char symbol,
|
||||||
unsigned char l,
|
int dmrss,
|
||||||
unsigned char symbol);
|
uint8_t ssb_index,
|
||||||
|
uint8_t n_hf);
|
||||||
|
|
||||||
int nr_pdsch_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,
|
uint8_t eNB_offset,
|
||||||
unsigned char Ns,
|
unsigned char Ns,
|
||||||
unsigned short p,
|
unsigned short p,
|
||||||
unsigned char l,
|
|
||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
unsigned short bwp_start_subcarrier,
|
unsigned short bwp_start_subcarrier,
|
||||||
unsigned short nb_rb_pdsch);
|
unsigned short nb_rb_pdsch);
|
||||||
|
|
||||||
|
|
||||||
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
||||||
PHY_VARS_NR_UE *ue,
|
PHY_VARS_NR_UE *ue,
|
||||||
|
|||||||
@@ -332,7 +332,9 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
|||||||
//uint8_t rb_count_bit;
|
//uint8_t rb_count_bit;
|
||||||
uint8_t i, j, aarx, bitcnt_coreset_freq_dom=0;
|
uint8_t i, j, aarx, bitcnt_coreset_freq_dom=0;
|
||||||
int32_t *dl_ch0, *dl_ch0_ext, *rxF, *rxF_ext;
|
int32_t *dl_ch0, *dl_ch0_ext, *rxF, *rxF_ext;
|
||||||
|
#ifdef NR_PDCCH_DCI_DEBUG
|
||||||
int nushiftmod3 = frame_parms->nushift % 3;
|
int nushiftmod3 = frame_parms->nushift % 3;
|
||||||
|
#endif
|
||||||
uint8_t symbol_mod;
|
uint8_t symbol_mod;
|
||||||
symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol;
|
symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol;
|
||||||
c_rb = n_BWP_start; // c_rb is the common resource block: RB within the BWP
|
c_rb = n_BWP_start; // c_rb is the common resource block: RB within the BWP
|
||||||
@@ -809,8 +811,6 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
|||||||
// indicates the number of active CORESETs for the current BWP to decode PDCCH: max is 3 (this variable is not useful here, to be removed)
|
// indicates the number of active CORESETs for the current BWP to decode PDCCH: max is 3 (this variable is not useful here, to be removed)
|
||||||
//uint8_t coreset_nbr_act;
|
//uint8_t coreset_nbr_act;
|
||||||
// indicates the number of REG contained in the PDCCH (number of RBs * number of symbols, in CORESET)
|
// indicates the number of REG contained in the PDCCH (number of RBs * number of symbols, in CORESET)
|
||||||
uint8_t coreset_nbr_reg;
|
|
||||||
uint32_t coreset_C;
|
|
||||||
uint32_t coreset_nbr_rb = 0;
|
uint32_t coreset_nbr_rb = 0;
|
||||||
// for (int j=0; j < coreset_nbr_act; j++) {
|
// for (int j=0; j < coreset_nbr_act; j++) {
|
||||||
// for each active CORESET (max number of active CORESETs in a BWP is 3),
|
// for each active CORESET (max number of active CORESETs in a BWP is 3),
|
||||||
@@ -829,9 +829,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
|||||||
#ifdef NR_PDCCH_DCI_DEBUG
|
#ifdef NR_PDCCH_DCI_DEBUG
|
||||||
printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld,%lx), coreset_nbr_rb=%d\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb);
|
printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld,%lx), coreset_nbr_rb=%d\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb);
|
||||||
#endif
|
#endif
|
||||||
coreset_nbr_reg = coreset_time_dur * coreset_nbr_rb;
|
|
||||||
coreset_C = (uint32_t)(coreset_nbr_reg / (reg_bundle_size_L * coreset_interleaver_size_R));
|
|
||||||
#ifdef NR_PDCCH_DCI_DEBUG
|
#ifdef NR_PDCCH_DCI_DEBUG
|
||||||
|
uint8_t coreset_nbr_reg = coreset_time_dur * coreset_nbr_rb;
|
||||||
|
uint32_t coreset_C = (uint32_t)(coreset_nbr_reg / (reg_bundle_size_L * coreset_interleaver_size_R));
|
||||||
printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_nbr_rb=%d, coreset_nbr_reg=%d, coreset_C=(%d/(%d*%d))=%d\n",
|
printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_nbr_rb=%d, coreset_nbr_reg=%d, coreset_C=(%d/(%d*%d))=%d\n",
|
||||||
coreset_nbr_rb, coreset_nbr_reg, coreset_nbr_reg, reg_bundle_size_L,coreset_interleaver_size_R, coreset_C);
|
coreset_nbr_rb, coreset_nbr_reg, coreset_nbr_reg, reg_bundle_size_L,coreset_interleaver_size_R, coreset_C);
|
||||||
#endif
|
#endif
|
||||||
@@ -843,7 +843,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
|||||||
printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n");
|
printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n");
|
||||||
#endif
|
#endif
|
||||||
nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF,
|
nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF,
|
||||||
common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id],
|
pdcch_vars[eNB_id]->dl_ch_estimates,
|
||||||
pdcch_vars[eNB_id]->rxdataF_ext,
|
pdcch_vars[eNB_id]->rxdataF_ext,
|
||||||
pdcch_vars[eNB_id]->dl_ch_estimates_ext,
|
pdcch_vars[eNB_id]->dl_ch_estimates_ext,
|
||||||
s,
|
s,
|
||||||
@@ -1418,27 +1418,25 @@ void nr_dci_decoding_procedure0(int s,
|
|||||||
*format_found=_format_2_3_found;
|
*format_found=_format_2_3_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#ifdef NR_PDCCH_DCI_DEBUG
|
|
||||||
|
#ifdef NR_PDCCH_DCI_DEBUG
|
||||||
printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found=%d\n",*format_found);
|
printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found=%d\n",*format_found);
|
||||||
printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> crc_scrambled=%d\n",*crc_scrambled);
|
printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> crc_scrambled=%d\n",*crc_scrambled);
|
||||||
|
#endif
|
||||||
|
|
||||||
//#endif
|
|
||||||
if (*format_found!=255) {
|
if (*format_found!=255) {
|
||||||
dci_alloc[*dci_cnt].dci_length = sizeof_bits;
|
dci_alloc[*dci_cnt].dci_length = sizeof_bits;
|
||||||
dci_alloc[*dci_cnt].rnti = crc;
|
dci_alloc[*dci_cnt].rnti = crc;
|
||||||
dci_alloc[*dci_cnt].L = L;
|
dci_alloc[*dci_cnt].L = L;
|
||||||
dci_alloc[*dci_cnt].firstCCE = CCEind;
|
dci_alloc[*dci_cnt].firstCCE = CCEind;
|
||||||
dci_alloc[*dci_cnt].dci_pdu[0] = dci_estimation[0];
|
memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_estimation,8);
|
||||||
dci_alloc[*dci_cnt].dci_pdu[1] = dci_estimation[1];
|
|
||||||
dci_alloc[*dci_cnt].dci_pdu[2] = dci_estimation[2];
|
#ifdef NR_PDCCH_DCI_DEBUG
|
||||||
dci_alloc[*dci_cnt].dci_pdu[3] = dci_estimation[3];
|
|
||||||
//#ifdef NR_PDCCH_DCI_DEBUG
|
|
||||||
printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> rnti matches -> DCI FOUND !!! crc =>0x%x, sizeof_bits %d, sizeof_bytes %d \n",
|
printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> rnti matches -> DCI FOUND !!! crc =>0x%x, sizeof_bits %d, sizeof_bytes %d \n",
|
||||||
dci_alloc[*dci_cnt].rnti, dci_alloc[*dci_cnt].dci_length, sizeof_bytes);
|
dci_alloc[*dci_cnt].rnti, dci_alloc[*dci_cnt].dci_length, sizeof_bytes);
|
||||||
printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> dci_cnt %d (format_css %d crc_scrambled %d) L %d, firstCCE %d pdu[0] 0x%lx pdu[1] 0x%lx \n",
|
printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> dci_cnt %d (format_css %d crc_scrambled %d) L %d, firstCCE %d pdu[0] 0x%lx pdu[1] 0x%lx \n",
|
||||||
*dci_cnt, format_css,*crc_scrambled,dci_alloc[*dci_cnt].L, dci_alloc[*dci_cnt].firstCCE,dci_alloc[*dci_cnt].dci_pdu[0],dci_alloc[*dci_cnt].dci_pdu[1]);
|
*dci_cnt, format_css,*crc_scrambled,dci_alloc[*dci_cnt].L, dci_alloc[*dci_cnt].firstCCE,dci_alloc[*dci_cnt].dci_pdu[0],dci_alloc[*dci_cnt].dci_pdu[1]);
|
||||||
|
#endif
|
||||||
//#endif
|
|
||||||
if ((format_css == cformat0_0_and_1_0) || (format_uss == uformat0_0_and_1_0)) {
|
if ((format_css == cformat0_0_and_1_0) || (format_uss == uformat0_0_and_1_0)) {
|
||||||
if ((*crc_scrambled == _p_rnti) || (*crc_scrambled == _si_rnti) || (*crc_scrambled == _ra_rnti)) {
|
if ((*crc_scrambled == _p_rnti) || (*crc_scrambled == _si_rnti) || (*crc_scrambled == _ra_rnti)) {
|
||||||
dci_alloc[*dci_cnt].format = format1_0;
|
dci_alloc[*dci_cnt].format = format1_0;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
//#define DEBUG_DCI
|
//#define DEBUG_DCI
|
||||||
#define NR_PDCCH_DCI_TOOLS
|
#define NR_PDCCH_DCI_TOOLS
|
||||||
#define NR_PDCCH_DCI_TOOLS_DEBUG
|
//#define NR_PDCCH_DCI_TOOLS_DEBUG
|
||||||
|
|
||||||
typedef unsigned __int128 uint128_t;
|
typedef unsigned __int128 uint128_t;
|
||||||
|
|
||||||
@@ -95,11 +95,8 @@ int nr_extract_dci_info(PHY_VARS_NR_UE *ue,
|
|||||||
uint8_t dci_length,
|
uint8_t dci_length,
|
||||||
uint16_t rnti,
|
uint16_t rnti,
|
||||||
uint64_t dci_pdu[2],
|
uint64_t dci_pdu[2],
|
||||||
NR_DCI_INFO_EXTRACTED_t *nr_pdci_info_extracted,
|
fapi_nr_dci_pdu_rel15_t *nr_pdci_info_extracted,
|
||||||
uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS],
|
uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS],
|
||||||
NR_DL_UE_HARQ_t *pdlsch0_harq,
|
|
||||||
NR_UE_DLSCH_t *pdlsch0,
|
|
||||||
NR_UE_ULSCH_t *ulsch0,
|
|
||||||
NR_DCI_format_t dci_format,
|
NR_DCI_format_t dci_format,
|
||||||
uint8_t nr_tti_rx,
|
uint8_t nr_tti_rx,
|
||||||
uint16_t n_RB_ULBWP,
|
uint16_t n_RB_ULBWP,
|
||||||
@@ -631,7 +628,7 @@ int nr_extract_dci_info(PHY_VARS_NR_UE *ue,
|
|||||||
case TB1_MCS: // 18 TB1_MCS: (field defined for -,-,-,format1_1,-,-,-,-)
|
case TB1_MCS: // 18 TB1_MCS: (field defined for -,-,-,format1_1,-,-,-,-)
|
||||||
nr_pdci_info_extracted->tb1_mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field);
|
nr_pdci_info_extracted->tb1_mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field);
|
||||||
//(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format]));
|
//(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format]));
|
||||||
if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs = nr_pdci_info_extracted->tb1_mcs;
|
//if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs = nr_pdci_info_extracted->tb1_mcs;
|
||||||
#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
|
#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
|
||||||
printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_mcs=%x\n",nr_pdci_info_extracted->tb1_mcs);
|
printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_mcs=%x\n",nr_pdci_info_extracted->tb1_mcs);
|
||||||
#endif
|
#endif
|
||||||
@@ -1025,98 +1022,50 @@ int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue,
|
|||||||
uint16_t rnti,
|
uint16_t rnti,
|
||||||
uint8_t dci_length,
|
uint8_t dci_length,
|
||||||
NR_DCI_format_t dci_format,
|
NR_DCI_format_t dci_format,
|
||||||
NR_UE_PDCCH *pdcch_vars,
|
|
||||||
NR_UE_PDSCH *pdsch_vars,
|
|
||||||
NR_UE_DLSCH_t **dlsch,
|
|
||||||
NR_UE_ULSCH_t *ulsch,
|
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
||||||
uint8_t beamforming_mode,
|
|
||||||
uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS],
|
uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS],
|
||||||
uint16_t n_RB_ULBWP,
|
uint16_t n_RB_ULBWP,
|
||||||
uint16_t n_RB_DLBWP,
|
uint16_t n_RB_DLBWP,
|
||||||
uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES],
|
uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES],
|
||||||
NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted)
|
fapi_nr_dci_pdu_rel15_t *nr_dci_info_extracted)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Note only format0_0 and format1_0 are implemented
|
* Note only format0_0 and format1_0 are implemented
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//uint8_t harq_pid=0;
|
|
||||||
uint8_t frame_type=frame_parms->frame_type;
|
uint8_t frame_type=frame_parms->frame_type;
|
||||||
//uint8_t tpmi=0;
|
|
||||||
NR_UE_DLSCH_t *dlsch0=NULL;//*dlsch1=NULL;
|
|
||||||
NR_DL_UE_HARQ_t *dlsch0_harq=NULL;//*dlsch1_harq=NULL;
|
|
||||||
NR_UE_ULSCH_t *ulsch0=NULL;//*ulsch1=NULL;
|
|
||||||
|
|
||||||
|
|
||||||
NR_DCI_INFO_EXTRACTED_t *ptr_nr_dci_info_extracted = nr_dci_info_extracted;
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t status=0;
|
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]=0x%lx, dci_pdu[1]=0x%lx\n",
|
|
||||||
dci_format,rnti,dci_length,dci_pdu[0],dci_pdu[1]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
LOG_D(PHY,"\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]);
|
||||||
|
|
||||||
|
memset(nr_dci_info_extracted,0,sizeof(*nr_dci_info_extracted));
|
||||||
|
|
||||||
// uint8_t dci_fields_sizes_format[NBR_NR_DCI_FIELDS] ={0};
|
LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Entering function nr_extract_dci_info(dci_format=%d) \n",dci_format);
|
||||||
// for (int m=0; m<NBR_NR_DCI_FIELDS; m++) dci_fields_sizes_format[m]=dci_fields_sizes[m][dci_format];
|
|
||||||
/*
|
|
||||||
dlsch0 = dlsch[0];
|
|
||||||
dlsch0->active = 0;
|
|
||||||
if (dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format] != 0) { // 27 HARQ_PROCESS_NUMBER (27 is the position in dci_fields_sizes array for field HARQ_PROCESS_NUMBER)
|
|
||||||
//for (int i=0; i<=HARQ_PROCESS_NUMBER; i++) left_shift = left_shift + dci_fields_sizes[i][dci_format];
|
|
||||||
nr_dci_info_extracted->harq_process_number = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,HARQ_PROCESS_NUMBER);
|
|
||||||
//(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format]));
|
|
||||||
//left_shift = 0;
|
|
||||||
#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
|
|
||||||
printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> nr_dci_info_extracted->harq_process_number=%x\n",nr_dci_info_extracted->harq_process_number);
|
|
||||||
for (int i=0; i<1000; i++) printf("%d",i);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dlsch0_harq = dlsch[0]->harq_processes[nr_dci_info_extracted->harq_process_number];
|
|
||||||
ulsch0 = ulsch;
|
|
||||||
//printf("nr_dci_info_extracted.harq_process_number = %d\n",nr_dci_info_extracted.harq_process_number);
|
|
||||||
//printf("dlsch0 = %d\n",dlsch0);
|
|
||||||
//printf("dlsch0_harq = %d\n",dlsch0_harq);
|
|
||||||
|
|
||||||
if (!dlsch[0]) return -1;
|
|
||||||
if (!ulsch) return -1;
|
|
||||||
*/
|
|
||||||
memset(&nr_dci_info_extracted,0,sizeof(nr_dci_info_extracted));
|
|
||||||
// printf("we reach this point\n");
|
|
||||||
#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
|
|
||||||
printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Entering function nr_extract_dci_info(dci_format=%d) \n",dci_format);
|
|
||||||
#endif
|
|
||||||
status = nr_extract_dci_info(ue,
|
status = nr_extract_dci_info(ue,
|
||||||
eNB_id,
|
eNB_id,
|
||||||
frame_type,
|
frame_type,
|
||||||
dci_length,
|
dci_length,
|
||||||
rnti,
|
rnti,
|
||||||
dci_pdu,
|
dci_pdu,
|
||||||
ptr_nr_dci_info_extracted,//&nr_dci_info_extracted,
|
nr_dci_info_extracted,//&nr_dci_info_extracted,
|
||||||
dci_fields_sizes,
|
dci_fields_sizes,
|
||||||
dlsch0_harq,
|
|
||||||
dlsch0,
|
|
||||||
ulsch0,
|
|
||||||
dci_format,
|
dci_format,
|
||||||
nr_tti_rx,
|
nr_tti_rx,
|
||||||
n_RB_ULBWP,
|
n_RB_ULBWP,
|
||||||
n_RB_DLBWP,
|
n_RB_DLBWP,
|
||||||
crc_scrambled_values);
|
crc_scrambled_values);
|
||||||
//printf("\n>>> inside nr_generate_ue_ul_dlsch_params_from_dci after nr_extract_dci_info: mcs=%d\n",nr_dci_info_extracted->mcs);
|
|
||||||
#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
|
if(status == 0) {
|
||||||
if(status == 0) {
|
LOG_W(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> bad DCI %d !!! \n",dci_format);
|
||||||
printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> bad DCI %d !!! \n",dci_format);
|
return(-1);
|
||||||
return(-1);
|
}
|
||||||
}
|
|
||||||
//printf("\n>>> inside nr_generate_ue_ul_dlsch_params_from_dci after nr_extract_dci_info: modified mcs=%d \n",nr_dci_info_extracted->mcs);
|
LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Ending function nr_extract_dci_info()\n");
|
||||||
printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Ending function nr_extract_dci_info()\n");
|
|
||||||
#endif
|
//fill
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -632,6 +632,7 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int32_t **rxdataF_comp,
|
int32_t **rxdataF_comp,
|
||||||
int16_t *dlsch_llr,
|
int16_t *dlsch_llr,
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
|
uint32_t len,
|
||||||
uint8_t first_symbol_flag,
|
uint8_t first_symbol_flag,
|
||||||
uint16_t nb_rb,
|
uint16_t nb_rb,
|
||||||
uint8_t beamforming_mode)
|
uint8_t beamforming_mode)
|
||||||
@@ -639,7 +640,7 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
|
|
||||||
uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*nb_rb*12)];
|
uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*nb_rb*12)];
|
||||||
uint32_t *llr32;
|
uint32_t *llr32;
|
||||||
int i,len;
|
int i;
|
||||||
|
|
||||||
llr32 = (uint32_t*)dlsch_llr;
|
llr32 = (uint32_t*)dlsch_llr;
|
||||||
if (!llr32) {
|
if (!llr32) {
|
||||||
@@ -647,10 +648,6 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol ==2) //to update from config
|
|
||||||
len = nb_rb*6;
|
|
||||||
else
|
|
||||||
len = nb_rb*12;
|
|
||||||
/*
|
/*
|
||||||
LOG_I(PHY,"dlsch_qpsk_llr: [symb %d / Length %d]: @LLR Buff %x, @LLR Buff(symb) %x \n",
|
LOG_I(PHY,"dlsch_qpsk_llr: [symb %d / Length %d]: @LLR Buff %x, @LLR Buff(symb) %x \n",
|
||||||
symbol,
|
symbol,
|
||||||
@@ -677,6 +674,7 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int16_t *dlsch_llr,
|
int16_t *dlsch_llr,
|
||||||
int32_t **dl_ch_mag,
|
int32_t **dl_ch_mag,
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
|
uint32_t len,
|
||||||
uint8_t first_symbol_flag,
|
uint8_t first_symbol_flag,
|
||||||
uint16_t nb_rb,
|
uint16_t nb_rb,
|
||||||
int16_t **llr32p,
|
int16_t **llr32p,
|
||||||
@@ -696,7 +694,7 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int i,len;
|
int i;
|
||||||
unsigned char len_mod4=0;
|
unsigned char len_mod4=0;
|
||||||
|
|
||||||
|
|
||||||
@@ -720,11 +718,6 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
|
ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (symbol ==2) //to update from config
|
|
||||||
len = nb_rb*6;
|
|
||||||
else
|
|
||||||
len = nb_rb*12;
|
|
||||||
|
|
||||||
// update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE)
|
// update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE)
|
||||||
if (first_symbol_flag == 1)
|
if (first_symbol_flag == 1)
|
||||||
*llr32p = dlsch_llr + (len<<2);
|
*llr32p = dlsch_llr + (len<<2);
|
||||||
@@ -798,6 +791,7 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int32_t **dl_ch_mag,
|
int32_t **dl_ch_mag,
|
||||||
int32_t **dl_ch_magb,
|
int32_t **dl_ch_magb,
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
|
uint32_t len,
|
||||||
uint8_t first_symbol_flag,
|
uint8_t first_symbol_flag,
|
||||||
uint16_t nb_rb,
|
uint16_t nb_rb,
|
||||||
uint32_t llr_offset,
|
uint32_t llr_offset,
|
||||||
@@ -810,7 +804,7 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
|
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
|
||||||
int16x8_t *ch_mag,*ch_magb,xmm1,xmm2;
|
int16x8_t *ch_mag,*ch_magb,xmm1,xmm2;
|
||||||
#endif
|
#endif
|
||||||
int i,len,len2;
|
int i,len2;
|
||||||
unsigned char len_mod4;
|
unsigned char len_mod4;
|
||||||
short *llr;
|
short *llr;
|
||||||
int16_t *llr2;
|
int16_t *llr2;
|
||||||
@@ -828,18 +822,13 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
pllr_symbol += llr_offset;
|
pllr_symbol += llr_offset;
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
|
ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)];
|
||||||
ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)];
|
ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*nb_rb*12)];
|
||||||
#elif defined(__arm__)
|
#elif defined(__arm__)
|
||||||
ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
|
ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
|
||||||
ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)];
|
ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*nb_rb*12)];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (symbol ==2) //to update from config
|
|
||||||
len = nb_rb*6;
|
|
||||||
else
|
|
||||||
len = nb_rb*12;
|
|
||||||
|
|
||||||
// printf("nr_dlsch_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
|
// printf("nr_dlsch_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
|
||||||
|
|
||||||
/* LOG_I(PHY,"nr_dlsch_64qam_llr [symb %d / FirstSym %d / Length %d]: @LLR Buff %x \n",
|
/* LOG_I(PHY,"nr_dlsch_64qam_llr [symb %d / FirstSym %d / Length %d]: @LLR Buff %x \n",
|
||||||
@@ -1131,18 +1120,17 @@ int nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int **rho_i,
|
int **rho_i,
|
||||||
short *dlsch_llr,
|
short *dlsch_llr,
|
||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
|
uint32_t len,
|
||||||
unsigned char first_symbol_flag,
|
unsigned char first_symbol_flag,
|
||||||
unsigned short nb_rb,
|
unsigned short nb_rb,
|
||||||
uint16_t pbch_pss_sss_adjust,
|
uint16_t pbch_pss_sss_adjust,
|
||||||
short **llr16p)
|
short **llr16p)
|
||||||
{
|
{
|
||||||
|
|
||||||
int16_t *rxF=(int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *rxF=(int16_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
|
||||||
int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(symbol*nb_rb*12)];
|
||||||
int16_t *rho=(int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *rho=(int16_t*)&rho_i[0][(symbol*nb_rb*12)];
|
||||||
int16_t *llr16;
|
int16_t *llr16;
|
||||||
int len;
|
|
||||||
uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
|
|
||||||
|
|
||||||
if (first_symbol_flag == 1) {
|
if (first_symbol_flag == 1) {
|
||||||
llr16 = (int16_t*)dlsch_llr;
|
llr16 = (int16_t*)dlsch_llr;
|
||||||
@@ -1152,19 +1140,6 @@ int nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
|
|
||||||
AssertFatal(llr16!=NULL,"nr_dlsch_qpsk_qpsk_llr: llr is null, symbol %d\n",symbol);
|
AssertFatal(llr16!=NULL,"nr_dlsch_qpsk_qpsk_llr: llr is null, symbol %d\n",symbol);
|
||||||
|
|
||||||
if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
|
|
||||||
// if symbol has pilots
|
|
||||||
if (frame_parms->nb_antenna_ports_eNB!=1)
|
|
||||||
// in 2 antenna ports we have 8 REs per symbol per RB
|
|
||||||
len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
|
|
||||||
else
|
|
||||||
// for 1 antenna port we have 10 REs per symbol per RB
|
|
||||||
len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
|
|
||||||
} else {
|
|
||||||
// symbol has no pilots
|
|
||||||
len = (nb_rb*12) - pbch_pss_sss_adjust;
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("nr_dlsch_qpsk_qpsk_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
|
// printf("nr_dlsch_qpsk_qpsk_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
|
||||||
// printf("qpsk_qpsk: len %d, llr16 %p\n",len,llr16);
|
// printf("qpsk_qpsk: len %d, llr16 %p\n",len,llr16);
|
||||||
qpsk_qpsk((short *)rxF,
|
qpsk_qpsk((short *)rxF,
|
||||||
@@ -2980,20 +2955,19 @@ int nr_dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int32_t **rho_i,
|
int32_t **rho_i,
|
||||||
int16_t *dlsch_llr,
|
int16_t *dlsch_llr,
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
|
uint32_t len,
|
||||||
uint8_t first_symbol_flag,
|
uint8_t first_symbol_flag,
|
||||||
uint16_t nb_rb,
|
uint16_t nb_rb,
|
||||||
uint16_t pbch_pss_sss_adjust,
|
uint16_t pbch_pss_sss_adjust,
|
||||||
int16_t **llr16p)
|
int16_t **llr16p)
|
||||||
{
|
{
|
||||||
|
|
||||||
int16_t *rxF = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *rxF = (int16_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
|
||||||
int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(symbol*nb_rb*12)];
|
||||||
int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
|
||||||
int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*nb_rb*12)];
|
||||||
int16_t *rho = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *rho = (int16_t*)&rho_i[0][(symbol*nb_rb*12)];
|
||||||
int16_t *llr16;
|
int16_t *llr16;
|
||||||
int len;
|
|
||||||
uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
|
|
||||||
|
|
||||||
// first symbol has different structure due to more pilots
|
// first symbol has different structure due to more pilots
|
||||||
if (first_symbol_flag == 1) {
|
if (first_symbol_flag == 1) {
|
||||||
@@ -3005,19 +2979,6 @@ int nr_dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
|
|
||||||
AssertFatal(llr16!=NULL,"nr_dlsch_16qam_16qam_llr: llr is null, symbol %d\n",symbol);
|
AssertFatal(llr16!=NULL,"nr_dlsch_16qam_16qam_llr: llr is null, symbol %d\n",symbol);
|
||||||
|
|
||||||
if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
|
|
||||||
// if symbol has pilots
|
|
||||||
if (frame_parms->nb_antenna_ports_eNB!=1)
|
|
||||||
// in 2 antenna ports we have 8 REs per symbol per RB
|
|
||||||
len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
|
|
||||||
else
|
|
||||||
// for 1 antenna port we have 10 REs per symbol per RB
|
|
||||||
len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
|
|
||||||
} else {
|
|
||||||
// symbol has no pilots
|
|
||||||
len = (nb_rb*12) - pbch_pss_sss_adjust;
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("symbol %d: qam16_llr, len %d (llr16 %p)\n",symbol,len,llr16);
|
// printf("symbol %d: qam16_llr, len %d (llr16 %p)\n",symbol,len,llr16);
|
||||||
|
|
||||||
qam16_qam16((short *)rxF,
|
qam16_qam16((short *)rxF,
|
||||||
@@ -8530,6 +8491,7 @@ int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int32_t **rho_i,
|
int32_t **rho_i,
|
||||||
int16_t *dlsch_llr,
|
int16_t *dlsch_llr,
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
|
uint32_t len,
|
||||||
uint8_t first_symbol_flag,
|
uint8_t first_symbol_flag,
|
||||||
uint16_t nb_rb,
|
uint16_t nb_rb,
|
||||||
uint16_t pbch_pss_sss_adjust,
|
uint16_t pbch_pss_sss_adjust,
|
||||||
@@ -8537,15 +8499,13 @@ int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
uint32_t llr_offset)
|
uint32_t llr_offset)
|
||||||
{
|
{
|
||||||
|
|
||||||
int16_t *rxF = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *rxF = (int16_t*)&rxdataF_comp[0][(symbol*nb_rb*12)];
|
||||||
int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(symbol*nb_rb*12)];
|
||||||
int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(symbol*nb_rb*12)];
|
||||||
int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*nb_rb*12)];
|
||||||
int16_t *rho = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
|
int16_t *rho = (int16_t*)&rho_i[0][(symbol*nb_rb*12)];
|
||||||
int16_t *llr16;
|
int16_t *llr16;
|
||||||
int8_t *pllr_symbol; // pointer where llrs should filled for this ofdm symbol
|
int8_t *pllr_symbol; // pointer where llrs should filled for this ofdm symbol
|
||||||
int len;
|
|
||||||
uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
|
|
||||||
|
|
||||||
//first symbol has different structure due to more pilots
|
//first symbol has different structure due to more pilots
|
||||||
/*if (first_symbol_flag == 1) {
|
/*if (first_symbol_flag == 1) {
|
||||||
@@ -8559,19 +8519,6 @@ int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
AssertFatal(llr16!=NULL,"nr_dlsch_16qam_64qam_llr:llr is null, symbol %d\n",symbol);
|
AssertFatal(llr16!=NULL,"nr_dlsch_16qam_64qam_llr:llr is null, symbol %d\n",symbol);
|
||||||
|
|
||||||
|
|
||||||
if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
|
|
||||||
// if symbol has pilots
|
|
||||||
if (frame_parms->nb_antenna_ports_eNB!=1)
|
|
||||||
// in 2 antenna ports we have 8 REs per symbol per RB
|
|
||||||
len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
|
|
||||||
else
|
|
||||||
// for 1 antenna port we have 10 REs per symbol per RB
|
|
||||||
len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
|
|
||||||
} else {
|
|
||||||
// symbol has no pilots
|
|
||||||
len = (nb_rb*12) - pbch_pss_sss_adjust;
|
|
||||||
}
|
|
||||||
|
|
||||||
pllr_symbol = (int8_t*)dlsch_llr;
|
pllr_symbol = (int8_t*)dlsch_llr;
|
||||||
pllr_symbol += llr_offset;
|
pllr_symbol += llr_offset;
|
||||||
//printf("nr_dlsch_64qam_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
|
//printf("nr_dlsch_64qam_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "PHY/INIT/phy_init.h"
|
#include "PHY/INIT/phy_init.h"
|
||||||
#include "PHY/MODULATION/modulation_UE.h"
|
#include "PHY/MODULATION/modulation_UE.h"
|
||||||
#include "nr_transport_proto_ue.h"
|
#include "nr_transport_proto_ue.h"
|
||||||
|
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
|
||||||
//#include "SCHED/defs.h"
|
//#include "SCHED/defs.h"
|
||||||
//#include "SCHED/extern.h"
|
//#include "SCHED/extern.h"
|
||||||
|
|
||||||
@@ -52,60 +53,125 @@ int cnt=0;
|
|||||||
|
|
||||||
#define DEBUG_INITIAL_SYNCH
|
#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(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, runmode_t mode)
|
||||||
{
|
{
|
||||||
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
|
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
|
||||||
int ret =-1;
|
int ret =-1;
|
||||||
|
|
||||||
|
NR_UE_SSB *best_ssb = NULL;
|
||||||
|
NR_UE_SSB *current_ssb;
|
||||||
|
|
||||||
#ifdef DEBUG_INITIAL_SYNCH
|
#ifdef DEBUG_INITIAL_SYNCH
|
||||||
LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
|
LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
|
||||||
ue->rx_offset);
|
ue->rx_offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// save the nb_prefix_samples0 since we are not synchronized to subframes yet and the SSB has all symbols with nb_prefix_samples
|
uint8_t N_L = (frame_parms->Lmax == 4)? 4:8;
|
||||||
int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
|
uint8_t N_hf = (frame_parms->Lmax == 4)? 2:1;
|
||||||
frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples;
|
|
||||||
|
|
||||||
|
// 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 1
|
// initialization of structure
|
||||||
nr_slot_fep(ue,
|
current_ssb = create_ssb_node(l,hf);
|
||||||
1,
|
|
||||||
0,
|
|
||||||
ue->ssb_offset,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
NR_PBCH_EST);
|
|
||||||
|
|
||||||
//symbol 2
|
#if UE_TIMING_TRACE
|
||||||
nr_slot_fep(ue,
|
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||||
2,
|
#endif
|
||||||
0,
|
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
|
||||||
ue->ssb_offset,
|
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
|
||||||
0,
|
nr_pbch_dmrs_correlation(ue,0,0,i,i-pbch_initial_symbol,current_ssb);
|
||||||
1,
|
#if UE_TIMING_TRACE
|
||||||
NR_PBCH_EST);
|
stop_meas(&ue->dlsch_channel_estimation_stats);
|
||||||
|
#endif
|
||||||
|
|
||||||
//symbol 3
|
current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im+current_ssb->c_re;
|
||||||
nr_slot_fep(ue,
|
|
||||||
3,
|
|
||||||
0,
|
|
||||||
ue->ssb_offset,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
NR_PBCH_EST);
|
|
||||||
|
|
||||||
//put back nb_prefix_samples0
|
// generate a list of SSB structures
|
||||||
frame_parms->nb_prefix_samples0 = nb_prefix_samples0;
|
if (best_ssb == NULL)
|
||||||
|
best_ssb = current_ssb;
|
||||||
|
else
|
||||||
|
best_ssb = insert_into_list(best_ssb,current_ssb);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = nr_rx_pbch(ue,
|
NR_UE_SSB *temp_ptr=best_ssb;
|
||||||
&ue->proc.proc_rxtx[0],
|
while (ret!=0 && temp_ptr != NULL) {
|
||||||
ue->pbch_vars[0],
|
|
||||||
frame_parms,
|
#if UE_TIMING_TRACE
|
||||||
0,
|
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||||
SISO,
|
#endif
|
||||||
ue->high_speed_flag);
|
// 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,
|
||||||
|
proc,
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
if (ret==0) {
|
if (ret==0) {
|
||||||
@@ -122,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[0] = ue->pbch_vars[0]->decoded_output[2];
|
||||||
// ue->pbch_vars[0]->decoded_output[2] = dummy;
|
// 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
|
#ifdef DEBUG_INITIAL_SYNCH
|
||||||
LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id);
|
LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id);
|
||||||
#endif
|
#endif
|
||||||
@@ -140,10 +201,10 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode)
|
|||||||
char duplex_string[2][4] = {"FDD","TDD"};
|
char duplex_string[2][4] = {"FDD","TDD"};
|
||||||
char prefix_string[2][9] = {"NORMAL","EXTENDED"};
|
char prefix_string[2][9] = {"NORMAL","EXTENDED"};
|
||||||
|
|
||||||
int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
int nr_initial_sync(UE_nr_rxtx_proc_t *proc, 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;
|
int32_t metric_tdd_ncp=0;
|
||||||
uint8_t phase_tdd_ncp;
|
uint8_t phase_tdd_ncp;
|
||||||
double im, re;
|
double im, re;
|
||||||
@@ -186,20 +247,17 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
|||||||
/* process pss search on received buffer */
|
/* process pss search on received buffer */
|
||||||
sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE);
|
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;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
//write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1);
|
//write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1);
|
||||||
|
|
||||||
#ifdef DEBUG_INITIAL_SYNCH
|
#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,"[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
|
#endif
|
||||||
|
|
||||||
// digital compensation of FFO for SSB symbols
|
// digital compensation of FFO for SSB symbols
|
||||||
@@ -224,6 +282,22 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
|||||||
/* check that SSS/PBCH block is continuous inside the received buffer */
|
/* 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))) {
|
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);
|
||||||
|
|
||||||
#ifdef DEBUG_INITIAL_SYNCH
|
#ifdef DEBUG_INITIAL_SYNCH
|
||||||
LOG_I(PHY,"Calling sss detection (normal CP)\n");
|
LOG_I(PHY,"Calling sss detection (normal CP)\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -234,15 +308,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_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0);
|
||||||
|
|
||||||
nr_gold_pbch(ue);
|
nr_gold_pbch(ue);
|
||||||
ret = nr_pbch_detection(ue,mode);
|
ret = nr_pbch_detection(proc, 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);
|
nr_gold_pdcch(ue,0, 2);
|
||||||
/*
|
/*
|
||||||
int nb_prefix_samples0 = fp->nb_prefix_samples0;
|
int nb_prefix_samples0 = fp->nb_prefix_samples0;
|
||||||
fp->nb_prefix_samples0 = fp->nb_prefix_samples;
|
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,0, 0, ue->ssb_offset, 0, NR_PDCCH_EST);
|
||||||
nr_slot_fep(ue,1, 0, ue->ssb_offset, 0, 1, NR_PDCCH_EST);
|
nr_slot_fep(ue,1, 0, ue->ssb_offset, 0, NR_PDCCH_EST);
|
||||||
fp->nb_prefix_samples0 = nb_prefix_samples0;
|
fp->nb_prefix_samples0 = nb_prefix_samples0;
|
||||||
|
|
||||||
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 : frame = %d, rx_offset %d, freq_offset %d \n",
|
||||||
@@ -259,7 +340,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef DEBUG_INITIAL_SYNCH
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,9 +373,8 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
|||||||
if (ue->UE_scan_carrier == 0) {
|
if (ue->UE_scan_carrier == 0) {
|
||||||
|
|
||||||
#if UE_AUTOTEST_TRACE
|
#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->Mod_id,
|
||||||
ue->proc.proc_rxtx[0].frame_rx,
|
|
||||||
ue->rx_offset,
|
ue->rx_offset,
|
||||||
ue->common_vars.freq_offset );
|
ue->common_vars.freq_offset );
|
||||||
#endif
|
#endif
|
||||||
@@ -305,30 +385,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DISABLE_LOG_X
|
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,
|
||||||
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,
|
|
||||||
10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
|
10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
|
||||||
10*log10(ue->measurements.rssi),
|
10*log10(ue->measurements.rssi),
|
||||||
ue->rx_total_gain_dB,
|
ue->rx_total_gain_dB,
|
||||||
@@ -346,22 +403,12 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
|||||||
fp->phich_config_common.phich_duration,
|
fp->phich_config_common.phich_duration,
|
||||||
phich_string[fp->phich_config_common.phich_resource],
|
phich_string[fp->phich_config_common.phich_resource],
|
||||||
fp->nb_antenna_ports_eNB);*/
|
fp->nb_antenna_ports_eNB);*/
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
|
#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
|
||||||
# if DISABLE_LOG_X
|
LOG_I(PHY, "[UE %d] Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
|
||||||
printf("[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
|
|
||||||
ue->Mod_id,
|
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);
|
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
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_INITIAL_SYNC
|
#ifdef DEBUG_INITIAL_SYNC
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include "PHY/phy_extern_nr_ue.h"
|
#include "PHY/phy_extern_nr_ue.h"
|
||||||
#include "PHY/sse_intrin.h"
|
#include "PHY/sse_intrin.h"
|
||||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
||||||
|
#include "PHY/INIT/phy_init.h"
|
||||||
|
|
||||||
//#define DEBUG_PBCH 1
|
//#define DEBUG_PBCH 1
|
||||||
//#define DEBUG_PBCH_ENCODING
|
//#define DEBUG_PBCH_ENCODING
|
||||||
@@ -413,6 +414,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
NR_UE_PBCH *nr_ue_pbch_vars,
|
NR_UE_PBCH *nr_ue_pbch_vars,
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
uint8_t eNB_id,
|
uint8_t eNB_id,
|
||||||
|
uint8_t i_ssb,
|
||||||
MIMO_mode_t mimo_mode,
|
MIMO_mode_t mimo_mode,
|
||||||
uint32_t high_speed_flag) {
|
uint32_t high_speed_flag) {
|
||||||
NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
|
NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
|
||||||
@@ -423,10 +425,9 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
//uint32_t pbch_a_prime;
|
//uint32_t pbch_a_prime;
|
||||||
int16_t *pbch_e_rx;
|
int16_t *pbch_e_rx;
|
||||||
uint8_t *decoded_output = nr_ue_pbch_vars->decoded_output;
|
uint8_t *decoded_output = nr_ue_pbch_vars->decoded_output;
|
||||||
uint8_t nushift;
|
uint8_t nushift,n_hf,ssb_index;
|
||||||
uint16_t M;
|
uint16_t M;
|
||||||
uint8_t Lmax=8; //to update
|
uint8_t Lmax=frame_parms->Lmax;
|
||||||
uint8_t ssb_index=0;
|
|
||||||
//uint16_t crc;
|
//uint16_t crc;
|
||||||
//unsigned short idx_demod =0;
|
//unsigned short idx_demod =0;
|
||||||
uint32_t decoderState=0;
|
uint32_t decoderState=0;
|
||||||
@@ -435,27 +436,27 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
//time_stats_t path_metric,sorting,update_LLR;
|
//time_stats_t path_metric,sorting,update_LLR;
|
||||||
memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS);
|
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);
|
//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];
|
pbch_e_rx = &nr_ue_pbch_vars->llr[0];
|
||||||
// clear LLR buffer
|
// clear LLR buffer
|
||||||
memset(nr_ue_pbch_vars->llr,0,NR_POLAR_PBCH_E);
|
memset(nr_ue_pbch_vars->llr,0,NR_POLAR_PBCH_E);
|
||||||
int symbol_offset=1;
|
int symbol_offset=1;
|
||||||
|
|
||||||
if (ue->is_synchronized > 0)
|
if (ue->is_synchronized > 0)
|
||||||
symbol_offset=4;
|
symbol_offset=ue->symbol_offset;
|
||||||
else
|
else
|
||||||
symbol_offset=0;
|
symbol_offset=0;
|
||||||
|
|
||||||
#ifdef DEBUG_PBCH
|
#ifdef DEBUG_PBCH
|
||||||
//printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF);
|
//printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[proc->subframe_rx]].rxdataF);
|
||||||
write_output("rxdataF0_pbch.m","rxF0pbch",
|
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);
|
&nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[proc->subframe_rx]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1);
|
||||||
#endif
|
#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++) {
|
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_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[proc->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->dl_ch_estimates,
|
||||||
nr_ue_pbch_vars->rxdataF_ext,
|
nr_ue_pbch_vars->rxdataF_ext,
|
||||||
nr_ue_pbch_vars->dl_ch_estimates_ext,
|
nr_ue_pbch_vars->dl_ch_estimates_ext,
|
||||||
symbol,
|
symbol,
|
||||||
@@ -526,7 +527,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
#endif
|
#endif
|
||||||
//un-scrambling
|
//un-scrambling
|
||||||
M = NR_POLAR_PBCH_E;
|
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;
|
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);
|
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0,0);
|
||||||
//polar decoding de-rate matching
|
//polar decoding de-rate matching
|
||||||
@@ -570,6 +571,16 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
for (int i=0; i<3; i++)
|
for (int i=0; i<3; i++)
|
||||||
decoded_output[i] = (uint8_t)((payload>>((3-i)<<3))&0xff);
|
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
|
#ifdef DEBUG_PBCH
|
||||||
printf("xtra_byte %x payload %x\n", xtra_byte, payload);
|
printf("xtra_byte %x payload %x\n", xtra_byte, payload);
|
||||||
|
|
||||||
@@ -577,14 +588,15 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
// printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]);
|
// printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]);
|
||||||
printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]);
|
printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ue->dl_indication.rx_ind = &ue->rx_ind; // hang on rx_ind instance
|
ue->dl_indication.rx_ind = &ue->rx_ind; // hang on rx_ind instance
|
||||||
|
ue->dl_indication.proc=proc;
|
||||||
//ue->rx_ind.sfn_slot = 0; //should be set by higher-1-layer, i.e. clean_and_set_if_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].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.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.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_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.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.rx_indication_body[0].mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL
|
||||||
ue->rx_ind.number_pdus = 1;
|
ue->rx_ind.number_pdus = 1;
|
||||||
|
|||||||
@@ -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);
|
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);
|
void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
|
||||||
|
|
||||||
@@ -113,6 +113,7 @@ int32_t nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int32_t **rho_i,
|
int32_t **rho_i,
|
||||||
int16_t *dlsch_llr,
|
int16_t *dlsch_llr,
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
|
uint32_t len,
|
||||||
uint8_t first_symbol_flag,
|
uint8_t first_symbol_flag,
|
||||||
uint16_t nb_rb,
|
uint16_t nb_rb,
|
||||||
uint16_t pbch_pss_sss_adj,
|
uint16_t pbch_pss_sss_adj,
|
||||||
@@ -268,6 +269,7 @@ int nr_dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int **rho_i,
|
int **rho_i,
|
||||||
short *dlsch_llr,
|
short *dlsch_llr,
|
||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
|
uint32_t len,
|
||||||
unsigned char first_symbol_flag,
|
unsigned char first_symbol_flag,
|
||||||
unsigned short nb_rb,
|
unsigned short nb_rb,
|
||||||
uint16_t pbch_pss_sss_adjust,
|
uint16_t pbch_pss_sss_adjust,
|
||||||
@@ -464,6 +466,7 @@ int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int **rho_i,
|
int **rho_i,
|
||||||
short *dlsch_llr,
|
short *dlsch_llr,
|
||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
|
uint32_t len,
|
||||||
unsigned char first_symbol_flag,
|
unsigned char first_symbol_flag,
|
||||||
unsigned short nb_rb,
|
unsigned short nb_rb,
|
||||||
uint16_t pbch_pss_sss_adjust,
|
uint16_t pbch_pss_sss_adjust,
|
||||||
@@ -486,6 +489,7 @@ int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int32_t **rxdataF_comp,
|
int32_t **rxdataF_comp,
|
||||||
int16_t *dlsch_llr,
|
int16_t *dlsch_llr,
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
|
uint32_t len,
|
||||||
uint8_t first_symbol_flag,
|
uint8_t first_symbol_flag,
|
||||||
uint16_t nb_rb,
|
uint16_t nb_rb,
|
||||||
uint8_t beamforming_mode);
|
uint8_t beamforming_mode);
|
||||||
@@ -520,6 +524,7 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int16_t *dlsch_llr,
|
int16_t *dlsch_llr,
|
||||||
int32_t **dl_ch_mag,
|
int32_t **dl_ch_mag,
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
|
uint32_t len,
|
||||||
uint8_t first_symbol_flag,
|
uint8_t first_symbol_flag,
|
||||||
uint16_t nb_rb,
|
uint16_t nb_rb,
|
||||||
int16_t **llr32p,
|
int16_t **llr32p,
|
||||||
@@ -568,6 +573,7 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
int32_t **dl_ch_mag,
|
int32_t **dl_ch_mag,
|
||||||
int32_t **dl_ch_magb,
|
int32_t **dl_ch_magb,
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
|
uint32_t len,
|
||||||
uint8_t first_symbol_flag,
|
uint8_t first_symbol_flag,
|
||||||
uint16_t nb_rb,
|
uint16_t nb_rb,
|
||||||
uint32_t llr_offset,
|
uint32_t llr_offset,
|
||||||
@@ -722,8 +728,8 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
|||||||
int **dl_ch_estimates_ext,
|
int **dl_ch_estimates_ext,
|
||||||
unsigned short pmi,
|
unsigned short pmi,
|
||||||
unsigned char *pmi_ext,
|
unsigned char *pmi_ext,
|
||||||
unsigned int *rb_alloc,
|
|
||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
|
uint8_t pilots,
|
||||||
unsigned short start_rb,
|
unsigned short start_rb,
|
||||||
unsigned short nb_pdsch_rb,
|
unsigned short nb_pdsch_rb,
|
||||||
unsigned char nr_tti_rx,
|
unsigned char nr_tti_rx,
|
||||||
@@ -753,18 +759,20 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
|||||||
@param high_speed_flag
|
@param high_speed_flag
|
||||||
@param frame_parms Pointer to frame descriptor
|
@param frame_parms Pointer to frame descriptor
|
||||||
*/
|
*/
|
||||||
uint16_t dlsch_extract_rbs_dual(int32_t **rxdataF,
|
unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF,
|
||||||
int32_t **dl_ch_estimates,
|
int **dl_ch_estimates,
|
||||||
int32_t **rxdataF_ext,
|
int **rxdataF_ext,
|
||||||
int32_t **dl_ch_estimates_ext,
|
int **dl_ch_estimates_ext,
|
||||||
uint16_t pmi,
|
unsigned short pmi,
|
||||||
uint8_t *pmi_ext,
|
unsigned char *pmi_ext,
|
||||||
uint32_t *rb_alloc,
|
unsigned char symbol,
|
||||||
uint8_t symbol,
|
uint8_t pilots,
|
||||||
uint8_t subframe,
|
unsigned short start_rb,
|
||||||
uint32_t high_speed_flag,
|
unsigned short nb_rb_pdsch,
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
unsigned char nr_tti_rx,
|
||||||
MIMO_mode_t mimo_mode);
|
uint32_t high_speed_flag,
|
||||||
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
|
MIMO_mode_t mimo_mode);
|
||||||
|
|
||||||
/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
|
/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
|
||||||
int32_t **dl_bf_ch_estimates,
|
int32_t **dl_bf_ch_estimates,
|
||||||
@@ -820,13 +828,28 @@ void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
|
|||||||
int32_t **rho,
|
int32_t **rho,
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
uint8_t symbol,
|
uint8_t symbol,
|
||||||
|
uint8_t start_symbol,
|
||||||
uint8_t first_symbol_flag,
|
uint8_t first_symbol_flag,
|
||||||
uint8_t mod_order,
|
uint8_t mod_order,
|
||||||
uint16_t nb_rb,
|
uint16_t nb_rb,
|
||||||
uint8_t output_shift,
|
uint8_t output_shift,
|
||||||
PHY_NR_MEASUREMENTS *phy_measurements);
|
PHY_NR_MEASUREMENTS *phy_measurements);
|
||||||
|
|
||||||
|
void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
|
||||||
|
int **dl_ch_estimates_ext,
|
||||||
|
int **dl_ch_mag,
|
||||||
|
int **dl_ch_magb,
|
||||||
|
int **rxdataF_comp,
|
||||||
|
int **rho,
|
||||||
|
unsigned char n_tx,
|
||||||
|
unsigned char n_rx,
|
||||||
|
unsigned char mod_order,
|
||||||
|
unsigned char output_shift,
|
||||||
|
int length,
|
||||||
|
int start_point);
|
||||||
|
|
||||||
void nr_dlsch_deinterleaving(uint8_t symbol,
|
void nr_dlsch_deinterleaving(uint8_t symbol,
|
||||||
|
uint8_t start_symbol,
|
||||||
uint16_t L,
|
uint16_t L,
|
||||||
uint16_t *llr,
|
uint16_t *llr,
|
||||||
uint16_t *llr_deint,
|
uint16_t *llr_deint,
|
||||||
@@ -881,6 +904,26 @@ void dlsch_channel_level_TM34_meas(int *ch00,
|
|||||||
int *avg_1,
|
int *avg_1,
|
||||||
unsigned short nb_rb);
|
unsigned short nb_rb);
|
||||||
|
|
||||||
|
void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
|
||||||
|
int32_t *median,
|
||||||
|
int n_tx,
|
||||||
|
int n_rx,
|
||||||
|
int length,
|
||||||
|
int start_point);
|
||||||
|
|
||||||
|
void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
|
||||||
|
int **rxdataF_comp_i,
|
||||||
|
int **rho,
|
||||||
|
int **rho_i,
|
||||||
|
int **dl_ch_mag,
|
||||||
|
int **dl_ch_magb,
|
||||||
|
int **dl_ch_mag_i,
|
||||||
|
int **dl_ch_magb_i,
|
||||||
|
unsigned char n_tx,
|
||||||
|
unsigned char n_rx,
|
||||||
|
int length,
|
||||||
|
int start_point);
|
||||||
|
|
||||||
void det_HhH(int32_t *after_mf_00,
|
void det_HhH(int32_t *after_mf_00,
|
||||||
int32_t *after_mf_01,
|
int32_t *after_mf_01,
|
||||||
int32_t *after_mf_10,
|
int32_t *after_mf_10,
|
||||||
@@ -939,11 +982,12 @@ void dlsch_channel_compensation_TM34(NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
@param pilots_flag Flag to indicate pilots in symbol
|
@param pilots_flag Flag to indicate pilots in symbol
|
||||||
@param nb_rb Number of allocated RBs
|
@param nb_rb Number of allocated RBs
|
||||||
*/
|
*/
|
||||||
void nr_dlsch_channel_level(int32_t **dl_ch_estimates_ext,
|
void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
int32_t *avg,
|
int32_t *avg,
|
||||||
uint8_t pilots_flag,
|
uint8_t symbol,
|
||||||
uint16_t nb_rb);
|
uint32_t len,
|
||||||
|
unsigned short nb_rb);
|
||||||
|
|
||||||
|
|
||||||
void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
|
void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
|
||||||
@@ -972,7 +1016,8 @@ void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext,
|
|||||||
void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
|
void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
NR_UE_DLSCH_t **dlsch_ue,
|
NR_UE_DLSCH_t **dlsch_ue,
|
||||||
uint8_t symbol_mod,
|
uint8_t symbol,
|
||||||
|
uint8_t start_symbol,
|
||||||
uint16_t nb_rb);
|
uint16_t nb_rb);
|
||||||
|
|
||||||
/** \brief This is the top-level entry point for DLSCH decoding in UE. It should be replicated on several
|
/** \brief This is the top-level entry point for DLSCH decoding in UE. It should be replicated on several
|
||||||
@@ -1006,6 +1051,25 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
uint8_t is_crnti,
|
uint8_t is_crnti,
|
||||||
uint8_t llr8_flag);
|
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,
|
uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||||
UE_nr_rxtx_proc_t *proc,
|
UE_nr_rxtx_proc_t *proc,
|
||||||
int eNB_id,
|
int eNB_id,
|
||||||
@@ -1122,9 +1186,15 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
NR_UE_PBCH *nr_ue_pbch_vars,
|
NR_UE_PBCH *nr_ue_pbch_vars,
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
uint8_t eNB_id,
|
uint8_t eNB_id,
|
||||||
|
uint8_t i_ssb,
|
||||||
MIMO_mode_t mimo_mode,
|
MIMO_mode_t mimo_mode,
|
||||||
uint32_t high_speed_flag);
|
uint32_t high_speed_flag);
|
||||||
|
|
||||||
|
int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
|
||||||
|
PHY_VARS_NR_UE *ue,
|
||||||
|
int pbch_initial_symbol,
|
||||||
|
runmode_t mode);
|
||||||
|
|
||||||
uint16_t rx_pbch_emul(PHY_VARS_NR_UE *phy_vars_ue,
|
uint16_t rx_pbch_emul(PHY_VARS_NR_UE *phy_vars_ue,
|
||||||
uint8_t eNB_id,
|
uint8_t eNB_id,
|
||||||
uint8_t pbch_phase);
|
uint8_t pbch_phase);
|
||||||
@@ -1409,7 +1479,8 @@ void generate_RIV_tables(void);
|
|||||||
@param phy_vars_ue Pointer to UE variables
|
@param phy_vars_ue Pointer to UE variables
|
||||||
@param mode current running mode
|
@param mode current running mode
|
||||||
*/
|
*/
|
||||||
int nr_initial_sync(PHY_VARS_NR_UE *phy_vars_ue, runmode_t mode);
|
int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||||
|
PHY_VARS_NR_UE *phy_vars_ue, runmode_t mode);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -1675,7 +1746,7 @@ int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue,
|
|||||||
uint8_t eNB_id,
|
uint8_t eNB_id,
|
||||||
int frame,
|
int frame,
|
||||||
uint8_t nr_tti_rx,
|
uint8_t nr_tti_rx,
|
||||||
uint32_t dci_pdu[4],
|
uint64_t dci_pdu[2],
|
||||||
uint16_t rnti,
|
uint16_t rnti,
|
||||||
uint8_t dci_length,
|
uint8_t dci_length,
|
||||||
NR_DCI_format_t dci_format,
|
NR_DCI_format_t dci_format,
|
||||||
@@ -1707,16 +1778,31 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
|||||||
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) ;
|
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) ;
|
||||||
|
|
||||||
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||||
short *dlsch_llr,
|
short *dlsch_llr,
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
NR_UE_DLSCH_t *dlsch,
|
NR_UE_DLSCH_t *dlsch,
|
||||||
NR_DL_UE_HARQ_t *harq_process,
|
NR_DL_UE_HARQ_t *harq_process,
|
||||||
uint32_t frame,
|
uint32_t frame,
|
||||||
uint16_t nb_symb_sch,
|
uint16_t nb_symb_sch,
|
||||||
uint8_t nr_tti_rx,
|
uint8_t nr_tti_rx,
|
||||||
uint8_t harq_pid,
|
uint8_t harq_pid,
|
||||||
uint8_t is_crnti,
|
uint8_t is_crnti,
|
||||||
uint8_t llr8_flag);
|
uint8_t llr8_flag);
|
||||||
|
|
||||||
|
int nr_extract_dci_info(PHY_VARS_NR_UE *ue,
|
||||||
|
uint8_t eNB_id,
|
||||||
|
lte_frame_type_t frame_type,
|
||||||
|
uint8_t dci_length,
|
||||||
|
uint16_t rnti,
|
||||||
|
uint64_t dci_pdu[2],
|
||||||
|
fapi_nr_dci_pdu_rel15_t *nr_pdci_info_extracted,
|
||||||
|
uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS],
|
||||||
|
NR_DCI_format_t dci_format,
|
||||||
|
uint8_t nr_tti_rx,
|
||||||
|
uint16_t n_RB_ULBWP,
|
||||||
|
uint16_t n_RB_DLBWP,
|
||||||
|
uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]);
|
||||||
|
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ typedef struct {
|
|||||||
uint16_t first_rb;
|
uint16_t first_rb;
|
||||||
/// Current Number of RBs
|
/// Current Number of RBs
|
||||||
uint16_t nb_rb;
|
uint16_t nb_rb;
|
||||||
|
/// number of layers
|
||||||
|
uint8_t Nl;
|
||||||
/// Last TPC command
|
/// Last TPC command
|
||||||
uint8_t TPC;
|
uint8_t TPC;
|
||||||
/// Transport block size
|
/// Transport block size
|
||||||
@@ -110,20 +112,24 @@ typedef struct {
|
|||||||
uint32_t B;
|
uint32_t B;
|
||||||
/// Length of ACK information (bits)
|
/// Length of ACK information (bits)
|
||||||
uint8_t O_ACK;
|
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
|
/// Index of current HARQ round for this ULSCH
|
||||||
uint8_t round;
|
uint8_t round;
|
||||||
/// MCS format of this ULSCH
|
/// MCS format of this ULSCH
|
||||||
uint8_t mcs;
|
uint8_t mcs;
|
||||||
/// Redundancy-version of the current sub-frame
|
/// Redundancy-version of the current sub-frame
|
||||||
uint8_t rvidx;
|
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
|
/// LDPC-code outputs
|
||||||
uint8_t d[MAX_NUM_ULSCH_SEGMENTS][3*8448];
|
uint8_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
|
||||||
/// Interleaver outputs
|
/// LDPC-code outputs (TS 36.212 V15.4.0, Sec 5.3.2 p. 17)
|
||||||
uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*8448];
|
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
|
/// Number of code segments
|
||||||
uint32_t C;
|
uint32_t C;
|
||||||
/// Number of bits in code segments
|
/// Number of bits in code segments
|
||||||
@@ -158,6 +164,8 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/// Current Number of Symbols
|
/// Current Number of Symbols
|
||||||
uint8_t Nsymb_pusch;
|
uint8_t Nsymb_pusch;
|
||||||
|
/// number of DMRS resource elements
|
||||||
|
uint8_t nb_re_dmrs;
|
||||||
/// SRS active flag
|
/// SRS active flag
|
||||||
uint8_t srs_active;
|
uint8_t srs_active;
|
||||||
//#if defined(UPGRADE_RAT_NR)
|
//#if defined(UPGRADE_RAT_NR)
|
||||||
@@ -168,6 +176,7 @@ typedef struct {
|
|||||||
// UL number of harq processes
|
// UL number of harq processes
|
||||||
uint8_t number_harq_processes_for_pusch;
|
uint8_t number_harq_processes_for_pusch;
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
/// Pointer to CQI data (+1 for 8 bits crc)
|
/// Pointer to CQI data (+1 for 8 bits crc)
|
||||||
uint8_t o[1+MAX_CQI_BYTES];
|
uint8_t o[1+MAX_CQI_BYTES];
|
||||||
/// Length of CQI data (bits)
|
/// Length of CQI data (bits)
|
||||||
@@ -180,22 +189,25 @@ typedef struct {
|
|||||||
uint8_t O_RI;
|
uint8_t O_RI;
|
||||||
/// Pointer to ACK
|
/// Pointer to ACK
|
||||||
uint8_t o_ACK[4];
|
uint8_t o_ACK[4];
|
||||||
|
*/
|
||||||
/// Minimum number of CQI bits for PUSCH (36-212 r8.6, Sec 5.2.4.1 p. 37)
|
/// Minimum number of CQI bits for PUSCH (36-212 r8.6, Sec 5.2.4.1 p. 37)
|
||||||
uint8_t O_CQI_MIN;
|
uint8_t O_CQI_MIN;
|
||||||
/// ACK/NAK Bundling flag
|
/// ACK/NAK Bundling flag
|
||||||
uint8_t bundling;
|
uint8_t bundling;
|
||||||
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
/// Concatenated "g"-sequences (for definition see 36-212 V15.4.0 2018-12, p.31)
|
||||||
uint8_t e[MAX_NUM_CHANNEL_BITS];
|
uint8_t g[MAX_NUM_NR_CHANNEL_BITS];
|
||||||
/// Interleaved "h"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
/// 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)
|
/// 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)
|
/// 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)
|
/// 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)
|
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
|
||||||
uint8_t q[MAX_CQI_PAYLOAD];
|
uint8_t q[MAX_CQI_PAYLOAD];
|
||||||
|
|
||||||
/// coded and interleaved CQI bits
|
/// coded and interleaved CQI bits
|
||||||
uint8_t o_w[(MAX_CQI_BITS+8)*3];
|
uint8_t o_w[(MAX_CQI_BITS+8)*3];
|
||||||
/// coded CQI bits
|
/// coded CQI bits
|
||||||
@@ -204,6 +216,7 @@ typedef struct {
|
|||||||
uint8_t q_ACK[MAX_ACK_PAYLOAD];
|
uint8_t q_ACK[MAX_ACK_PAYLOAD];
|
||||||
/// coded RI bits
|
/// coded RI bits
|
||||||
uint8_t q_RI[MAX_RI_PAYLOAD];
|
uint8_t q_RI[MAX_RI_PAYLOAD];
|
||||||
|
*/
|
||||||
/// beta_offset_cqi times 8
|
/// beta_offset_cqi times 8
|
||||||
uint16_t beta_offset_cqi_times8;
|
uint16_t beta_offset_cqi_times8;
|
||||||
/// beta_offset_ri times 8
|
/// beta_offset_ri times 8
|
||||||
@@ -229,11 +242,11 @@ typedef struct {
|
|||||||
/// num active cba group
|
/// num active cba group
|
||||||
uint8_t num_active_cba_groups;
|
uint8_t num_active_cba_groups;
|
||||||
/// num dci found for cba
|
/// num dci found for cba
|
||||||
uint8_t num_cba_dci[10];
|
//uint8_t num_cba_dci[10];
|
||||||
/// allocated CBA RNTI
|
/// 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
|
/// UL max-harq-retransmission
|
||||||
uint8_t Mlimit;
|
uint16_t Mlimit;
|
||||||
} NR_UE_ULSCH_t;
|
} NR_UE_ULSCH_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -260,11 +273,11 @@ typedef struct {
|
|||||||
/// Redundancy-version of the current sub-frame
|
/// Redundancy-version of the current sub-frame
|
||||||
uint8_t rvidx;
|
uint8_t rvidx;
|
||||||
/// MIMO mode for this DLSCH
|
/// MIMO mode for this DLSCH
|
||||||
MIMO_mode_t mimo_mode;
|
MIMO_nrmode_t mimo_mode;
|
||||||
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||||
int16_t w[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
|
int16_t w[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
|
||||||
/// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
/// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||||
double w_abs[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
|
//double w_abs[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
|
||||||
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||||
int16_t *d[MAX_NUM_NR_DLSCH_SEGMENTS];
|
int16_t *d[MAX_NUM_NR_DLSCH_SEGMENTS];
|
||||||
/// LDPC processing buffers
|
/// LDPC processing buffers
|
||||||
|
|||||||
@@ -0,0 +1,454 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_dlsch.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,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;
|
||||||
|
//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;
|
||||||
|
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;
|
||||||
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
|
uint16_t Kr_bytes;
|
||||||
|
Kr_bytes = Kr>>3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///////////
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////// 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");
|
||||||
|
#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);
|
||||||
|
}
|
||||||
@@ -898,7 +898,8 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fo_flag){
|
if (fo_flag){
|
||||||
// fractional frequency offser computation according to Cross-correlation Synchronization Algorithm Using PSS
|
|
||||||
|
// 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.
|
// 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;
|
int64_t result1,result2;
|
||||||
|
|||||||
@@ -990,7 +990,7 @@ void nr_uci_encoding(uint64_t payload,
|
|||||||
// A is the payload size, to be provided in function call
|
// A is the payload size, to be provided in function call
|
||||||
uint8_t A = nr_bit;
|
uint8_t A = nr_bit;
|
||||||
// L is the CRC size
|
// L is the CRC size
|
||||||
uint8_t L;
|
//uint8_t L;
|
||||||
// E is the rate matching output sequence length as given in TS 38.212 subclause 6.3.1.4.1
|
// E is the rate matching output sequence length as given in TS 38.212 subclause 6.3.1.4.1
|
||||||
uint16_t E=0,E_init;
|
uint16_t E=0,E_init;
|
||||||
|
|
||||||
@@ -1047,7 +1047,7 @@ void nr_uci_encoding(uint64_t payload,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*M_bit = E;
|
*M_bit = E;
|
||||||
int I_seg;
|
//int I_seg;
|
||||||
#ifdef DEBUG_NR_PUCCH_TX
|
#ifdef DEBUG_NR_PUCCH_TX
|
||||||
printf("\t\t [nr_uci_encoding] start function with fmt=%d, encoding A=%d bits into M_bit=%d (where nrofSymbols=%d,nrofPRB=%d)\n",fmt,A,*M_bit,nrofSymbols,nrofPRB);
|
printf("\t\t [nr_uci_encoding] start function with fmt=%d, encoding A=%d bits into M_bit=%d (where nrofSymbols=%d,nrofPRB=%d)\n",fmt,A,*M_bit,nrofSymbols,nrofPRB);
|
||||||
#endif
|
#endif
|
||||||
@@ -1057,19 +1057,19 @@ void nr_uci_encoding(uint64_t payload,
|
|||||||
// CRC bits are not attached, and coding small block lengths (subclause 5.3.3)
|
// CRC bits are not attached, and coding small block lengths (subclause 5.3.3)
|
||||||
} else if (A>=12) {
|
} else if (A>=12) {
|
||||||
// procedure in subclause 6.3.1.2.1 (UCI encoded by Polar code -> subclause 6.3.1.3.1)
|
// procedure in subclause 6.3.1.2.1 (UCI encoded by Polar code -> subclause 6.3.1.3.1)
|
||||||
if ((A>=360 && E>=1088)||(A>=1013)) {
|
/*if ((A>=360 && E>=1088)||(A>=1013)) {
|
||||||
I_seg = 1;
|
I_seg = 1;
|
||||||
} else {
|
} else {
|
||||||
I_seg = 0;
|
I_seg = 0;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (A>=20) {
|
/*if (A>=20) {
|
||||||
// parity bits (subclause 5.2.1) computed by setting L=11 and using generator polynomial gCRC11(D) (subclause 5.1)
|
// parity bits (subclause 5.2.1) computed by setting L=11 and using generator polynomial gCRC11(D) (subclause 5.1)
|
||||||
L=11;
|
L=11;
|
||||||
} else if (A<=19) {
|
} else if (A<=19) {
|
||||||
// parity bits (subclause 5.2.1) computed by setting L=6 and using generator polynomial gCRC6(D) (subclause 5.1)
|
// parity bits (subclause 5.2.1) computed by setting L=6 and using generator polynomial gCRC6(D) (subclause 5.1)
|
||||||
L=6;
|
L=6;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// code block segmentation and CRC attachment is performed according to subclause 5.2.1
|
// code block segmentation and CRC attachment is performed according to subclause 5.2.1
|
||||||
// polar coding subclause 5.3.1
|
// polar coding subclause 5.3.1
|
||||||
|
|||||||
@@ -430,39 +430,6 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
|
|||||||
int32_t metric, metric_re;
|
int32_t metric, metric_re;
|
||||||
int16_t *d;
|
int16_t *d;
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
|
|
||||||
int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
|
|
||||||
// For now, symbol 0 = PSS/PBCH and it is never in symbol 0 or 7*2^mu (i.e. always shorter prefix)
|
|
||||||
frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples;
|
|
||||||
|
|
||||||
// Do FFTs for SSS/PSS
|
|
||||||
// SSS
|
|
||||||
nr_slot_fep(ue,
|
|
||||||
SSS_SYMBOL_NB-PSS_SYMBOL_NB, // symbol number w.r.t. PSS
|
|
||||||
0, // Ns slot number
|
|
||||||
ue->ssb_offset, // sample_offset of int16_t
|
|
||||||
0, // no_prefix
|
|
||||||
1, // reset frequency estimation
|
|
||||||
NR_SSS_EST);
|
|
||||||
|
|
||||||
// PSS
|
|
||||||
nr_slot_fep(ue,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
ue->ssb_offset,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
NR_SSS_EST);
|
|
||||||
|
|
||||||
frame_parms->nb_prefix_samples0 = nb_prefix_samples0;
|
|
||||||
|
|
||||||
// pss sss extraction
|
// pss sss extraction
|
||||||
pss_sss_extract_nr(ue,
|
pss_sss_extract_nr(ue,
|
||||||
|
|||||||
@@ -158,122 +158,6 @@ int32_t dot_product(int16_t *x,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t dot_product64(int16_t *x,
|
|
||||||
int16_t *y,
|
|
||||||
uint32_t N, //must be a multiple of 8
|
|
||||||
uint8_t output_shift)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint32_t n;
|
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
|
||||||
__m128i *x128,*y128,mmtmp1,mmtmp2,mmtmp3,mmcumul,mmcumul_re,mmcumul_im;
|
|
||||||
__m128i minus_i = _mm_set_epi16(-1,1,-1,1,-1,1,-1,1);
|
|
||||||
int64_t result;
|
|
||||||
|
|
||||||
x128 = (__m128i*) x;
|
|
||||||
y128 = (__m128i*) y;
|
|
||||||
|
|
||||||
mmcumul_re = _mm_setzero_si128();
|
|
||||||
mmcumul_im = _mm_setzero_si128();
|
|
||||||
|
|
||||||
for (n=0; n<(N>>2); n++) {
|
|
||||||
|
|
||||||
// printf("n=%d, x128=%p, y128=%p\n",n,x128,y128);
|
|
||||||
// print_shorts("x",&x128[0]);
|
|
||||||
// print_shorts("y",&y128[0]);
|
|
||||||
|
|
||||||
// this computes Re(z) = Re(x)*Re(y) + Im(x)*Im(y)
|
|
||||||
mmtmp1 = _mm_madd_epi16(x128[0],y128[0]);
|
|
||||||
// print_ints("retmp",&mmtmp1);
|
|
||||||
// mmtmp1 contains real part of 4 consecutive outputs (32-bit)
|
|
||||||
// shift and accumulate results
|
|
||||||
mmtmp1 = _mm_srai_epi32(mmtmp1,output_shift);
|
|
||||||
mmcumul_re = _mm_add_epi32(mmcumul_re,mmtmp1);
|
|
||||||
//print_ints("re",&mmcumul_re);
|
|
||||||
|
|
||||||
|
|
||||||
// this computes Im(z) = Re(x)*Im(y) - Re(y)*Im(x)
|
|
||||||
mmtmp2 = _mm_shufflelo_epi16(y128[0],_MM_SHUFFLE(2,3,0,1));
|
|
||||||
//print_shorts("y",&mmtmp2);
|
|
||||||
mmtmp2 = _mm_shufflehi_epi16(mmtmp2,_MM_SHUFFLE(2,3,0,1));
|
|
||||||
//print_shorts("y",&mmtmp2);
|
|
||||||
mmtmp2 = _mm_sign_epi16(mmtmp2,minus_i);
|
|
||||||
// print_shorts("y",&mmtmp2);
|
|
||||||
|
|
||||||
mmtmp3 = _mm_madd_epi16(x128[0],mmtmp2);
|
|
||||||
//print_ints("imtmp",&mmtmp3);
|
|
||||||
// mmtmp3 contains imag part of 4 consecutive outputs (32-bit)
|
|
||||||
// shift and accumulate results
|
|
||||||
mmtmp3 = _mm_srai_epi32(mmtmp3,output_shift);
|
|
||||||
mmcumul_im = _mm_add_epi32(mmcumul_im,mmtmp3);
|
|
||||||
//print_ints("im",&mmcumul_im);
|
|
||||||
|
|
||||||
x128++;
|
|
||||||
y128++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this gives Re Re Im Im
|
|
||||||
mmcumul = _mm_hadd_epi32(mmcumul_re,mmcumul_im);
|
|
||||||
//print_ints("cumul1",&mmcumul);
|
|
||||||
// this gives Re Im Re Im
|
|
||||||
mmcumul = _mm_hadd_epi32(mmcumul,mmcumul);
|
|
||||||
//print_ints("cumul2",&mmcumul);
|
|
||||||
|
|
||||||
//mmcumul = _mm_srai_epi32(mmcumul,output_shift);
|
|
||||||
// extract the lower half
|
|
||||||
result = _mm_extract_epi64(mmcumul,0);
|
|
||||||
//printf("result: (%d,%d)\n",((int32_t*)&result)[0],((int32_t*)&result)[1]);
|
|
||||||
_mm_empty();
|
|
||||||
_m_empty();
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
|
|
||||||
#elif defined(__arm__)
|
|
||||||
int16x4_t *x_128=(int16x4_t*)x;
|
|
||||||
int16x4_t *y_128=(int16x4_t*)y;
|
|
||||||
int32x4_t tmp_re,tmp_im;
|
|
||||||
int32x4_t tmp_re1,tmp_im1;
|
|
||||||
int32x4_t re_cumul,im_cumul;
|
|
||||||
int32x2_t re_cumul2,im_cumul2;
|
|
||||||
int32x4_t shift = vdupq_n_s32(-output_shift);
|
|
||||||
int32x2x2_t result2;
|
|
||||||
int16_t conjug[4]__attribute__((aligned(16))) = {-1,1,-1,1} ;
|
|
||||||
|
|
||||||
re_cumul = vdupq_n_s32(0);
|
|
||||||
im_cumul = vdupq_n_s32(0);
|
|
||||||
|
|
||||||
for (n=0; n<(N>>2); n++) {
|
|
||||||
|
|
||||||
tmp_re = vmull_s16(*x_128++, *y_128++);
|
|
||||||
//tmp_re = [Re(x[0])Re(y[0]) Im(x[0])Im(y[0]) Re(x[1])Re(y[1]) Im(x[1])Im(y[1])]
|
|
||||||
tmp_re1 = vmull_s16(*x_128++, *y_128++);
|
|
||||||
//tmp_re1 = [Re(x1[1])Re(x2[1]) Im(x1[1])Im(x2[1]) Re(x1[1])Re(x2[2]) Im(x1[1])Im(x2[2])]
|
|
||||||
tmp_re = vcombine_s32(vpadd_s32(vget_low_s32(tmp_re),vget_high_s32(tmp_re)),
|
|
||||||
vpadd_s32(vget_low_s32(tmp_re1),vget_high_s32(tmp_re1)));
|
|
||||||
//tmp_re = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2]) Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]
|
|
||||||
|
|
||||||
tmp_im = vmull_s16(vrev32_s16(vmul_s16(*x_128++,*(int16x4_t*)conjug)),*y_128++);
|
|
||||||
//tmp_im = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
|
|
||||||
tmp_im1 = vmull_s16(vrev32_s16(vmul_s16(*x_128++,*(int16x4_t*)conjug)),*y_128++);
|
|
||||||
//tmp_im1 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
|
|
||||||
tmp_im = vcombine_s32(vpadd_s32(vget_low_s32(tmp_im),vget_high_s32(tmp_im)),
|
|
||||||
vpadd_s32(vget_low_s32(tmp_im1),vget_high_s32(tmp_im1)));
|
|
||||||
//tmp_im = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
|
|
||||||
|
|
||||||
re_cumul = vqaddq_s32(re_cumul,vqshlq_s32(tmp_re,shift));
|
|
||||||
im_cumul = vqaddq_s32(im_cumul,vqshlq_s32(tmp_im,shift));
|
|
||||||
}
|
|
||||||
|
|
||||||
re_cumul2 = vpadd_s32(vget_low_s32(re_cumul),vget_high_s32(re_cumul));
|
|
||||||
im_cumul2 = vpadd_s32(vget_low_s32(im_cumul),vget_high_s32(im_cumul));
|
|
||||||
re_cumul2 = vpadd_s32(re_cumul2,re_cumul2);
|
|
||||||
im_cumul2 = vpadd_s32(im_cumul2,im_cumul2);
|
|
||||||
result2 = vzip_s32(re_cumul2,im_cumul2);
|
|
||||||
return(vget_lane_s32(result2.val[0],0));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MAIN
|
#ifdef MAIN
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user