mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-21 08:30:31 +00:00
Compare commits
9 Commits
fix/ci-fix
...
2_Step_RA_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26956bf8e1 | ||
|
|
3a8e3b9408 | ||
|
|
c9461ac4d4 | ||
|
|
d95d911e96 | ||
|
|
97ac8a5cd1 | ||
|
|
778fb90f44 | ||
|
|
80735e2b39 | ||
|
|
ed53bd8f95 | ||
|
|
ea35109ba2 |
@@ -5,8 +5,8 @@ project (OpenAirInterface LANGUAGES C CXX)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(OAI_VERSION 2.4.0)
|
||||
|
||||
option(ENABLE_CHANNEL_SIM_CUDA "Enable CUDA accelerated channel simulation" OFF)
|
||||
if(ENABLE_CHANNEL_SIM_CUDA)
|
||||
option(CUDA_ENABLE "Enable CUDA accelerated channel simulation" OFF)
|
||||
if(CUDA_ENABLE)
|
||||
find_package(CUDA REQUIRED)
|
||||
find_package(CUDAToolkit REQUIRED)
|
||||
message(STATUS "CUDA explicitly enabled, building with GPU acceleration support.")
|
||||
@@ -34,7 +34,7 @@ if(ENABLE_CHANNEL_SIM_CUDA)
|
||||
message(STATUS "CUDA Explicit Copy path enabled (default ATS was overridden).")
|
||||
endif()
|
||||
|
||||
add_compile_definitions(CHANNEL_SIM_CUDA)
|
||||
add_compile_definitions(ENABLE_CUDA)
|
||||
endif()
|
||||
|
||||
#########################################################
|
||||
@@ -155,17 +155,14 @@ add_boolean_option(AVX512 ${AUTODETECT_AVX512} "Whether AVX512 intrinsics is ava
|
||||
eval_boolean(AUTODETECT_AVX2 DEFINED CPUFLAGS AND CPUFLAGS MATCHES "avx2")
|
||||
add_boolean_option(AVX2 ${AUTODETECT_AVX2} "Whether AVX2 intrinsics is available on the host processor" ON)
|
||||
|
||||
eval_boolean(AUTODETECT_GFNI DEFINED CPUFLAGS AND CPUFLAGS MATCHES "gfni")
|
||||
add_boolean_option(GFNI ${AUTODETECT_GFNI} "Whether GFNI intrinsics is available on the host processor" ON)
|
||||
|
||||
message(STATUS "CPU architecture is ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
if (CROSS_COMPILE)
|
||||
message(STATUS "setting as aarch64")
|
||||
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -lgcc -lrt")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||
# The following intrinsics are assumed to be available on any x86 system
|
||||
# (avx, f16c, fma, mmx, pclmul, sse, sse2, sse3, xop)
|
||||
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -DSIMDE_X86_AVX_NATIVE -DSIMDE_X86_AVX_NATIVE -DSIMDE_X86_F16C_NATIVE -DSIMDE_X86_FMA_NATIVE -DSIMDE_X86_MMX_NATIVE -DSIMDE_X86_PCLMUL_NATIVE -DSIMDE_X86_SSE2_NATIVE -DSIMDE_X86_SSE3_NATIVE -DSIMDE_X86_SSE_NATIVE -DSIMDE_X86_XOP_HAVE_COM_ -DSIMDE_X86_XOP_NATIVE")
|
||||
# (avx, f16c, fma, gnfi, mmx, pclmul, sse, sse2, sse3, xop)
|
||||
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -DSIMDE_X86_AVX_NATIVE -DSIMDE_X86_AVX_NATIVE -DSIMDE_X86_F16C_NATIVE -DSIMDE_X86_FMA_NATIVE -DSIMDE_X86_GFNI_NATIVE -DSIMDE_X86_MMX_NATIVE -DSIMDE_X86_PCLMUL_NATIVE -DSIMDE_X86_SSE2_NATIVE -DSIMDE_X86_SSE3_NATIVE -DSIMDE_X86_SSE_NATIVE -DSIMDE_X86_XOP_HAVE_COM_ -DSIMDE_X86_XOP_NATIVE")
|
||||
message(STATUS "AVX512 intrinsics are ${AVX512}")
|
||||
if(${AVX512})
|
||||
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -DSIMDE_X86_AVX512BW_NATIVE -DSIMDE_X86_AVX512F_NATIVE -DSIMDE_X86_AVX512VL_NATIVE -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512")
|
||||
@@ -176,17 +173,13 @@ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||
if(${AVX2})
|
||||
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -DSIMDE_X86_AVX2_NATIVE -DSIMDE_X86_VPCLMULQDQ_NATIVE")
|
||||
endif()
|
||||
message(STATUS "GFNI intrinsics are ${GFNI}")
|
||||
if(${GFNI})
|
||||
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -DSIMDE_X86_GFNI_NATIVE -mgfni")
|
||||
endif()
|
||||
if (CPUFLAGS MATCHES "sse4_1")
|
||||
if (CPUINFO MATCHES "sse4_1")
|
||||
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -DSIMDE_X86_SSE4_1_NATIVE")
|
||||
endif()
|
||||
if(CPUFLAGS MATCHES "sse4_2")
|
||||
if(CPUINFO MATCHES "sse4_2")
|
||||
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -DSIMDE_X86_SSE4_2_NATIVE")
|
||||
endif()
|
||||
if(CPUFLAGS MATCHES "ssse3")
|
||||
if(CPUINFO MATCHES "ssse3")
|
||||
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -DSIMDE_X86_SSSE3_NATIVE")
|
||||
endif()
|
||||
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l")
|
||||
@@ -228,9 +221,9 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(commonOpts "${commonOpts} -Wno-packed-bitfield-compat")
|
||||
endif()
|
||||
# clang: suppress complaints about unused command line argument (-rdynamic only
|
||||
# used during linking) and "const member leaves the object uninitialized"
|
||||
# used during linking)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(commonOpts "${commonOpts} -Wno-unused-command-line-argument -Wno-default-const-init-field-unsafe")
|
||||
set(commonOpts "${commonOpts} -Wno-unused-command-line-argument")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS
|
||||
@@ -849,7 +842,6 @@ set(PHY_NRLDPC_CODINGIF
|
||||
)
|
||||
|
||||
add_library(dfts MODULE ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts.c ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts_neon.c)
|
||||
target_compile_options(dfts PRIVATE -fno-semantic-interposition)
|
||||
|
||||
set(PHY_SRC_COMMON
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c
|
||||
@@ -1279,9 +1271,7 @@ set (MAC_NR_SRC
|
||||
${NR_GNB_MAC_DIR}/gNB_scheduler.c
|
||||
${NR_GNB_MAC_DIR}/gNB_scheduler_bch.c
|
||||
${NR_GNB_MAC_DIR}/gNB_scheduler_dlsch.c
|
||||
${NR_GNB_MAC_DIR}/gNB_scheduler_dlsch_default_policies.c
|
||||
${NR_GNB_MAC_DIR}/gNB_scheduler_ulsch.c
|
||||
${NR_GNB_MAC_DIR}/gNB_scheduler_ulsch_default_policies.c
|
||||
${NR_GNB_MAC_DIR}/gNB_scheduler_primitives.c
|
||||
${NR_GNB_MAC_DIR}/gNB_scheduler_phytest.c
|
||||
${NR_GNB_MAC_DIR}/gNB_scheduler_uci.c
|
||||
@@ -2108,13 +2098,13 @@ target_link_libraries(nr_srssim PRIVATE
|
||||
m pthread ITTI dl nr_ue_phy_meas physim_common softmodem_common
|
||||
)
|
||||
|
||||
if(ENABLE_CHANNEL_SIM_CUDA)
|
||||
if(CUDA_ENABLE)
|
||||
if (TARGET oai_cuda_lib)
|
||||
target_link_libraries(nr_dlsim PRIVATE oai_cuda_lib)
|
||||
target_link_libraries(nr_ulsim PRIVATE oai_cuda_lib)
|
||||
|
||||
target_compile_definitions(nr_dlsim PRIVATE CHANNEL_SIM_CUDA)
|
||||
target_compile_definitions(nr_ulsim PRIVATE CHANNEL_SIM_CUDA)
|
||||
target_compile_definitions(nr_dlsim PRIVATE ENABLE_CUDA)
|
||||
target_compile_definitions(nr_ulsim PRIVATE ENABLE_CUDA)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
<a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-CSSL--v1.0-blue" alt="License"></a>
|
||||
<a href="https://releases.ubuntu.com/22.04/"><img src="https://img.shields.io/badge/OS-Ubuntu22-Green" alt="Supported OS Ubuntu 22"></a>
|
||||
<a href="https://releases.ubuntu.com/24.04/"><img src="https://img.shields.io/badge/OS-Ubuntu24-Green" alt="Supported OS Ubuntu 24"></a>
|
||||
<a href="https://releases.ubuntu.com/26.04/"><img src="https://img.shields.io/badge/OS-Ubuntu26-Green" alt="Supported OS Ubuntu 26"></a>
|
||||
<a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux"><img src="https://img.shields.io/badge/OS-RHEL9-Green" alt="Supported OS RHEL9"></a>
|
||||
<a href="https://getfedora.org/en/workstation/"><img src="https://img.shields.io/badge/OS-Fedore44-Green" alt="Supported OS Fedora 44"></a>
|
||||
<a href="https://getfedora.org/en/workstation/"><img src="https://img.shields.io/badge/OS-Fedore41-Green" alt="Supported OS Fedora 43"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
||||
69
ci-scripts/Jenkinsfile
vendored
69
ci-scripts/Jenkinsfile
vendored
@@ -20,13 +20,12 @@ if (params.LockResources != null && params.LockResources.trim().length() > 0)
|
||||
// Global Parameters. Normally they should be populated when the master job
|
||||
// triggers the slave job with parameters
|
||||
|
||||
def INTERNAL_REPO = "asterix:/home/git/openairinterface5g.git"
|
||||
def sourceBranch = params.sourceBranch ?: env.GIT_BRANCH
|
||||
def targetBranch = params.targetBranch ?: 'develop'
|
||||
def commitID = params.sourceCommit ?: env.GIT_COMMIT
|
||||
def testRepository = params.customRepository ?: INTERNAL_REPO
|
||||
def testBranch = params.customBranch ?: "${sourceBranch}-${commitID}"
|
||||
def mergeWithTarget = params.mergeWithTarget ?: false
|
||||
def sourceRepository = params.eNB_Repository ?: env.GIT_URL
|
||||
def sourceBranch = params.eNB_Branch ?: env.GIT_BRANCH
|
||||
def targetRepository = params.Target_Repository ?: sourceRepository
|
||||
def targetBranch = params.eNB_TargetBranch ?: 'develop'
|
||||
def commitID = params.eNB_CommitID ?: env.GIT_COMMIT
|
||||
def is_MR = params.eNB_mergeRequest ?: false
|
||||
|
||||
def flexricOption = ""
|
||||
def runWithOC = false
|
||||
@@ -41,22 +40,17 @@ pipeline {
|
||||
timestamps()
|
||||
ansiColor('xterm')
|
||||
lock(extra: lockResources)
|
||||
skipDefaultCheckout()
|
||||
}
|
||||
|
||||
stages {
|
||||
stage("Build Init") {
|
||||
steps {
|
||||
checkout(
|
||||
scmGit(branches: [[name: "${branch}"]],
|
||||
userRemoteConfigs: [[url: "${repository}"]])
|
||||
)
|
||||
script {
|
||||
echo '\u2705 \u001B[94mBuild Init\u001B[0m'
|
||||
JOB_TIMESTAMP = sh(returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"').trim()
|
||||
}
|
||||
// update the build name and description
|
||||
buildName "${params.requestNumber}"
|
||||
buildName "${params.eNB_MR}"
|
||||
buildDescription "Branch : ${sourceBranch}"
|
||||
}
|
||||
}
|
||||
@@ -70,12 +64,12 @@ pipeline {
|
||||
echo "no LockResources given"
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.workspace == null) {
|
||||
echo "no workspace given"
|
||||
if (params.eNB_SourceCodePath == null) {
|
||||
echo "no eNB_SourceCodePath given"
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.OC_Credentials != null) {
|
||||
echo "This pipeline is configured to run with Openshift Cluster."
|
||||
echo "This pipeline is configured to run with Opensift Cluster."
|
||||
runWithOC = true
|
||||
if (params.OC_ProjectName == null) {
|
||||
echo "no OC_ProjectName given"
|
||||
@@ -90,11 +84,21 @@ pipeline {
|
||||
}
|
||||
|
||||
echo "CI executor node : ${pythonExecutor}"
|
||||
echo "Testing Repository : ${testRepository}"
|
||||
echo "Testing Branch : ${testBranch}"
|
||||
echo "Source Repository : ${sourceRepository}"
|
||||
echo "Source Branch : ${sourceBranch}"
|
||||
echo "Target Repository : ${targetRepository}"
|
||||
echo "Target Branch : ${targetBranch}"
|
||||
echo "Commit ID : ${commitID}"
|
||||
|
||||
if (allParametersPresent) {
|
||||
echo '\u2705 \u001B[94m All parameters are present\u001B[0m'
|
||||
if (is_MR) {
|
||||
sh "git fetch"
|
||||
sh "./ci-scripts/doGitLabMerge.sh --src-branch ${sourceBranch} --src-commit ${commitID} --target-branch ${targetBranch} --target-commit latest"
|
||||
} else {
|
||||
sh "git fetch"
|
||||
sh "git checkout -f ${commitID}"
|
||||
}
|
||||
} else {
|
||||
echo "\u274C Some parameters are missing"
|
||||
sh "./ci-scripts/fail.sh"
|
||||
@@ -117,21 +121,28 @@ pipeline {
|
||||
}
|
||||
}
|
||||
sh """
|
||||
python3 main.py --mode=InitiateHtml --repository=${testRepository} \
|
||||
--branch=${testBranch} --commitID=${commitID} \
|
||||
${mainPythonAllXmlFiles}
|
||||
python3 main.py --mode=InitiateHtml --ranRepository=${targetRepository} \
|
||||
--ranBranch=${sourceBranch} --ranCommitID=${commitID} \
|
||||
--ranAllowMerge=${is_MR} --ranTargetBranch=${targetBranch} \
|
||||
${flexricOption} ${mainPythonAllXmlFiles}
|
||||
"""
|
||||
if (runWithOC) {
|
||||
withCredentials([usernamePassword(credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password')]) {
|
||||
sh """
|
||||
python3 main.py --mode=InitiateHtml --ranRepository=${targetRepository} \
|
||||
--ranBranch=${sourceBranch} --ranCommitID=${commitID} \
|
||||
--ranAllowMerge=${is_MR} --ranTargetBranch=${targetBranch} \
|
||||
${flexricOption} ${mainPythonAllXmlFiles}
|
||||
"""
|
||||
for (xmlFile in myXmlTestSuite) {
|
||||
if (fileExists(xmlFile)) {
|
||||
try {
|
||||
timeout (time: 60, unit: 'MINUTES') {
|
||||
sh """
|
||||
python3 main.py --mode=TesteNB --repository=${testRepository} \
|
||||
--branch=${testBranch} \
|
||||
--ranAllowMerge=${mergeWithTarget} --targetBranch=${targetBranch} \
|
||||
--workspace=${params.workspace} --XMLTestFile=${xmlFile} \
|
||||
python3 main.py --mode=TesteNB --ranRepository=${targetRepository} \
|
||||
--ranBranch=${sourceBranch} --ranCommitID=${commitID} \
|
||||
--ranAllowMerge=${is_MR} --ranTargetBranch=${targetBranch} \
|
||||
--eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} \
|
||||
--OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName} \
|
||||
${flexricOption}
|
||||
"""
|
||||
@@ -149,10 +160,10 @@ pipeline {
|
||||
try {
|
||||
timeout (time: 60, unit: 'MINUTES') {
|
||||
sh """
|
||||
python3 main.py --mode=TesteNB --repository=${testRepository} \
|
||||
--branch=${testBranch} \
|
||||
--ranAllowMerge=${mergeWithTarget} --targetBranch=${targetBranch} \
|
||||
--workspace=${params.workspace} --XMLTestFile=${xmlFile} \
|
||||
python3 main.py --mode=TesteNB --ranRepository=${targetRepository} \
|
||||
--ranBranch=${sourceBranch} --ranCommitID=${commitID} \
|
||||
--ranAllowMerge=${is_MR} --ranTargetBranch=${targetBranch} \
|
||||
--eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} \
|
||||
${flexricOption}
|
||||
"""
|
||||
}
|
||||
|
||||
@@ -880,20 +880,12 @@ def triggerSlaveJob (jobName, gitlabStatusName) {
|
||||
def localStatus = build job: jobName,
|
||||
parameters: [
|
||||
string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)),
|
||||
string(name: 'targetRepo', value: String.valueOf(GIT_URL)),
|
||||
string(name: 'SourceRepo', value: String.valueOf(env.gitlabSourceRepoHttpUrl)),
|
||||
string(name: 'sourceRepo', value: String.valueOf(env.gitlabSourceRepoHttpUrl)),
|
||||
string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)),
|
||||
string(name: 'sourceBranch', value: String.valueOf(env.gitlabSourceBranch)),
|
||||
string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)),
|
||||
string(name: 'sourceCommit', value: String.valueOf(env.gitlabMergeRequestLastCommit)),
|
||||
string(name: 'eNB_MR', value: String.valueOf(MR_NUMBER)),
|
||||
string(name: 'requestNumber', value: String.valueOf(MR_NUMBER)),
|
||||
booleanParam(name: 'eNB_mergeRequest', value: "MERGE".equals(env.gitlabActionType)),
|
||||
booleanParam(name: 'mergeWithTarget', value: "MERGE".equals(env.gitlabActionType)),
|
||||
string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)),
|
||||
string(name: 'targetBranch', value: String.valueOf(env.gitlabTargetBranch)),
|
||||
string(name: 'testBranch', value: "${env.gitlabSourceBranch.replace('/', '-')}-${env.gitlabMergeRequestLastCommit}")
|
||||
string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch))
|
||||
], propagate: false
|
||||
def localResult = localStatus.getResult()
|
||||
echo "${jobName} Slave Job status is ${localResult}"
|
||||
@@ -908,9 +900,13 @@ def triggerSlaveJob (jobName, gitlabStatusName) {
|
||||
|
||||
def triggerCN5GSlaveJob (jobName, gitlabStatusName) {
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
fullRanTag = OAI_Registry + '/oai-gnb:' + "${env.gitlabSourceBranch.replace('/', '-')}-${env.gitlabMergeRequestLastCommit}"
|
||||
shaOne = sh returnStdout: true, script: 'git log -1 --pretty=format:"%H" ' + env.gitlabMergeRequestLastCommit
|
||||
shaOne = shaOne.trim()
|
||||
fullRanTag = OAI_Registry + '/oai-gnb:' + env.gitlabSourceBranch + '-' + shaOne
|
||||
} else {
|
||||
fullRanTag = OAI_Registry + '/oai-gnb:develop-' + env.GIT_COMMIT
|
||||
shaOne = sh returnStdout: true, script: 'git log -1 --pretty=format:"%H" ' + env.GIT_COMMIT
|
||||
shaOne = shaOne.trim()
|
||||
fullRanTag = OAI_Registry + '/oai-gnb:develop-' + shaOne
|
||||
}
|
||||
// Workaround for the "cancelled" GitLab pipeline notification
|
||||
// The slave job is triggered with the propagate false so the following commands are executed
|
||||
|
||||
@@ -27,26 +27,21 @@ pipeline {
|
||||
steps {
|
||||
script {
|
||||
def missingParams = []
|
||||
if (!params.sourceRepo?.trim()) { missingParams << 'sourceRepo' }
|
||||
if (!params.sourceBranch?.trim()) { missingParams << 'sourceBranch' }
|
||||
if (!params.sourceCommit?.trim()) { missingParams << 'sourceCommit' }
|
||||
if (params.mergeWithTarget) {
|
||||
if (!params.targetRepo?.trim()) { missingParams << 'targetRepo' }
|
||||
if (!params.targetBranch?.trim()) { missingParams << 'targetBranch' }
|
||||
}
|
||||
if (!params.SourceRepo?.trim()) { missingParams << 'SourceRepo' }
|
||||
if (!params.eNB_Branch?.trim()) { missingParams << 'eNB_Branch' }
|
||||
if (!params.eNB_CommitID?.trim()) { missingParams << 'eNB_CommitID' }
|
||||
if (!params.eNB_TargetBranch?.trim()) { missingParams << 'eNB_TargetBranch' }
|
||||
if (!params.eNB_Repository?.trim()) { missingParams << 'eNB_Repository' }
|
||||
|
||||
if (missingParams) {
|
||||
error "Missing required parameters: ${missingParams.join(', ')}"
|
||||
}
|
||||
|
||||
echo "Source Repo : ${params.sourceRepo}"
|
||||
echo "Source Branch : ${params.sourceBranch}"
|
||||
echo "Source Commit : ${params.sourceCommit}"
|
||||
echo "Merge : ${params.mergeWithTarget}"
|
||||
if (params.mergeWithTarget) {
|
||||
echo "Target Branch : ${params.targetBranch}"
|
||||
echo "Target Repo : ${params.targetRepo}"
|
||||
}
|
||||
echo "Source Repo : ${params.SourceRepo}"
|
||||
echo "Source Branch : ${params.eNB_Branch}"
|
||||
echo "Source Commit : ${params.eNB_CommitID}"
|
||||
echo "Target Branch : ${params.eNB_TargetBranch}"
|
||||
echo "Target Repo : ${params.eNB_Repository}"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +51,6 @@ pipeline {
|
||||
git config user.email "jenkins@openairinterface.org"
|
||||
git config user.name "OAI Jenkins"
|
||||
git remote remove source || true
|
||||
git remote remove target || true
|
||||
git remote remove internal-repo || true
|
||||
"""
|
||||
}
|
||||
@@ -64,38 +58,30 @@ pipeline {
|
||||
stage('Add source repo & fetch branches') {
|
||||
steps {
|
||||
sh """
|
||||
git remote add source ${params.sourceRepo} || true
|
||||
git fetch source ${params.sourceBranch}
|
||||
git remote add source ${params.SourceRepo} || true
|
||||
git fetch source ${params.eNB_Branch}
|
||||
git fetch origin ${params.eNB_TargetBranch}
|
||||
"""
|
||||
script {
|
||||
if (params.mergeWithTarget) {
|
||||
sh """
|
||||
git remote add target ${params.targetRepo} || true
|
||||
git fetch target ${params.targetBranch}
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Create temporary branch for CI') {
|
||||
steps {
|
||||
script {
|
||||
env.NEW_BRANCH = "${params.sourceBranch}-${params.sourceCommit}"
|
||||
env.NEW_BRANCH = "${params.eNB_Branch}-${params.eNB_CommitID}"
|
||||
echo "New branch: ${env.NEW_BRANCH}"
|
||||
}
|
||||
sh """
|
||||
# Checkout source commit
|
||||
git checkout -B ${env.NEW_BRANCH} ${params.sourceCommit}
|
||||
git checkout -B ${env.NEW_BRANCH} ${params.eNB_CommitID}
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('Merge target into source') {
|
||||
when { expression { return params.mergeWithTarget } }
|
||||
steps {
|
||||
sh """
|
||||
echo "Merging target branch ${params.targetBranch} into source branch ${env.NEW_BRANCH}"
|
||||
if ! git merge --ff target/${params.targetBranch} \
|
||||
-m "Merge ${params.targetBranch} into ${params.sourceBranch} for CI"; then
|
||||
echo "Merging target branch ${params.eNB_TargetBranch} into source branch ${env.NEW_BRANCH}"
|
||||
if ! git merge --ff origin/${params.eNB_TargetBranch} \
|
||||
-m "Merge ${params.eNB_TargetBranch} into ${params.eNB_Branch} for CI"; then
|
||||
echo "Merge conflicts detected. Aborting."
|
||||
git merge --abort || true
|
||||
exit 1
|
||||
|
||||
@@ -56,7 +56,7 @@ pipeline {
|
||||
echo "Forced Tag is ${WEEK_TAG}"
|
||||
}
|
||||
}
|
||||
WEEK_SHA = sh returnStdout: true, script: 'git log -n1 --pretty=format:"%H" origin/develop'
|
||||
WEEK_SHA = sh returnStdout: true, script: 'git log -n1 --pretty=format:"%h" origin/develop | cut -c 1-8'
|
||||
WEEK_SHA = WEEK_SHA.trim()
|
||||
|
||||
withCredentials([
|
||||
|
||||
@@ -44,11 +44,8 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER):
|
||||
elif re.match(r'^\-\-mode=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-mode=(.+)$', myArgv, re.IGNORECASE)
|
||||
mode = matchReg.group(1)
|
||||
elif re.match(r'^\-\-repository=(.+)$|^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE):
|
||||
if re.match(r'^\-\-repository=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-repository=(.+)$', myArgv, re.IGNORECASE)
|
||||
else:
|
||||
matchReg = re.match(r'^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE)
|
||||
elif re.match(r'^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE)
|
||||
CiTestObj.repository = matchReg.group(1)
|
||||
RAN.repository=matchReg.group(1)
|
||||
HTML.repository=matchReg.group(1)
|
||||
@@ -59,40 +56,34 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER):
|
||||
doMerge = matchReg.group(1)
|
||||
if ((doMerge == 'true') or (doMerge == 'True')):
|
||||
RAN.merge=True
|
||||
HTML.merge=True
|
||||
CONTAINERS.merge=True
|
||||
CLUSTER.merge=True
|
||||
elif re.match(r'^\-\-branch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
|
||||
if re.match(r'^\-\-branch=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-branch=(.+)$', myArgv, re.IGNORECASE)
|
||||
else:
|
||||
matchReg = re.match(r'^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE)
|
||||
elif re.match(r'^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE)
|
||||
CiTestObj.branch = matchReg.group(1)
|
||||
RAN.branch=matchReg.group(1)
|
||||
HTML.branch=matchReg.group(1)
|
||||
CONTAINERS.branch=matchReg.group(1)
|
||||
CLUSTER.branch=matchReg.group(1)
|
||||
elif re.match(r'^\-\-commitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
|
||||
if re.match(r'^\-\-commitID=(.*)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-commitID=(.*)$', myArgv, re.IGNORECASE)
|
||||
else:
|
||||
matchReg = re.match(r'^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE)
|
||||
elif re.match(r'^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE)
|
||||
RAN.commitID=matchReg.group(1)
|
||||
HTML.commitID=matchReg.group(1)
|
||||
elif re.match(r'^\-\-targetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
|
||||
if re.match(r'^\-\-targetBranch=(.*)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-targetBranch=(.*)$', myArgv, re.IGNORECASE)
|
||||
else:
|
||||
matchReg = re.match(r'^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE)
|
||||
CONTAINERS.commitID=matchReg.group(1)
|
||||
CLUSTER.commitID=matchReg.group(1)
|
||||
elif re.match(r'^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE)
|
||||
RAN.targetBranch=matchReg.group(1)
|
||||
HTML.targetBranch=matchReg.group(1)
|
||||
CONTAINERS.targetBranch=matchReg.group(1)
|
||||
CLUSTER.targetBranch=matchReg.group(1)
|
||||
elif re.match(r'^\-\-workspace=(.+)$|^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
|
||||
if re.match(r'^\-\-workspace=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-workspace=(.+)$', myArgv, re.IGNORECASE)
|
||||
else:
|
||||
elif re.match(r'^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
|
||||
if re.match(r'^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
|
||||
RAN.workspace=matchReg.group(1)
|
||||
CONTAINERS.workspace=matchReg.group(1)
|
||||
CLUSTER.workspace=matchReg.group(1)
|
||||
RAN.workspace=matchReg.group(1)
|
||||
CONTAINERS.workspace=matchReg.group(1)
|
||||
CLUSTER.workspace=matchReg.group(1)
|
||||
elif re.match(r'^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match(r'^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE)
|
||||
CiTestObj.testXMLfiles.append(matchReg.group(1))
|
||||
|
||||
@@ -58,6 +58,7 @@ class Cluster:
|
||||
self.OCRegistry = OCRegistry
|
||||
self.repository = ""
|
||||
self.branch = ""
|
||||
self.commitID = ""
|
||||
self.merge = False
|
||||
self.targetBranch = ""
|
||||
self.cmd = None
|
||||
@@ -156,7 +157,7 @@ class Cluster:
|
||||
OC_logout(cmd)
|
||||
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL)
|
||||
return False
|
||||
tag = self.branch
|
||||
tag = cls_containerize.CreateTag(self.commitID, self.branch, self.merge)
|
||||
registry = f'{self.OCRegistry}/{CI_OC_RAN_NAMESPACE}'
|
||||
success, msg = cls_containerize.Containerize.Pull_Image(cmd, images, tag, tag_prefix, registry, None, None)
|
||||
OC_logout(cmd)
|
||||
@@ -173,9 +174,9 @@ class Cluster:
|
||||
return (image, archiveArtifact(self.cmd, ctx, fn))
|
||||
|
||||
def BuildClusterImage(self, ctx, node, HTML):
|
||||
if self.repository == '' or self.branch == '':
|
||||
if self.repository == '' or self.branch == '' or self.commitID == '':
|
||||
HELP.GenericHelp(CONST.Version)
|
||||
raise ValueError(f'Insufficient Parameter: repository {self.repository} branch {self.branch}')
|
||||
raise ValueError(f'Insufficient Parameter: repository {self.repository} branch {self.branch} commitID {self.commitID}')
|
||||
lSourcePath = self.workspace
|
||||
if node == '' or lSourcePath == '':
|
||||
raise ValueError('Insufficient Parameter: workspace missing')
|
||||
@@ -201,7 +202,7 @@ class Cluster:
|
||||
forceBaseImageBuild = False
|
||||
if self.merge: # merging MR branch into develop -> temporary image
|
||||
branchName = self.branch.replace('/','-')
|
||||
imageTag = f'{branchName}'
|
||||
imageTag = f'{branchName}-{self.commitID}'
|
||||
if self.targetBranch == 'develop':
|
||||
ret = self.cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base.rhel9 | grep --colour=never -i INDEX')
|
||||
result = re.search('index', ret.stdout)
|
||||
@@ -214,7 +215,7 @@ class Cluster:
|
||||
forceBaseImageBuild = True
|
||||
baseTag = 'ci-temp'
|
||||
else:
|
||||
imageTag = self.branch
|
||||
imageTag = f'develop-{self.commitID}'
|
||||
forceBaseImageBuild = True
|
||||
|
||||
# logging to OC Cluster and then switch to corresponding project
|
||||
|
||||
@@ -32,15 +32,34 @@ from cls_ci_helper import archiveArtifact
|
||||
IMAGES = ['oai-enb', 'oai-lte-ru', 'oai-lte-ue', 'oai-gnb', 'oai-nr-cuup', 'oai-gnb-aw2s', 'oai-nr-ue', 'oai-enb-asan', 'oai-gnb-asan', 'oai-lte-ue-asan', 'oai-nr-ue-asan', 'oai-nr-cuup-asan', 'oai-gnb-aerial', 'oai-gnb-fhi72']
|
||||
DEFAULT_REGISTRY = "gracehopper3-oai.sboai.cs.eurecom.fr"
|
||||
|
||||
def CreateWorkspace(host, sourcePath, repository, branch):
|
||||
def CreateWorkspace(host, sourcePath, repository, commitID, targetBranch, merge):
|
||||
if commitID == '':
|
||||
logging.error('need commitID in CreateWorkspace()')
|
||||
raise ValueError('Insufficient Parameter in CreateWorkspace(): need commitID')
|
||||
|
||||
script = "scripts/create_workspace.sh"
|
||||
options = f"{sourcePath} {repository} {branch}"
|
||||
options = f"{sourcePath} {repository} {commitID}"
|
||||
if merge:
|
||||
if targetBranch == '':
|
||||
targetBranch = 'develop'
|
||||
options += f" {targetBranch}"
|
||||
logging.info(f'execute "{script}" with options "{options}" on node {host}')
|
||||
with cls_cmd.getConnection(host) as c:
|
||||
ret = c.exec_script(script, 90, options)
|
||||
logging.debug(f'"{script}" finished with code {ret.returncode}, output:\n{ret.stdout}')
|
||||
return ret.returncode == 0
|
||||
|
||||
def CreateTag(commitID, branch, merge):
|
||||
if commitID == 'develop':
|
||||
return 'develop'
|
||||
if merge:
|
||||
# Allowing contributor to have a name/branchName format
|
||||
branchName = branch.replace('/','-')
|
||||
tagToUse = f'{branchName}-{commitID}'
|
||||
else:
|
||||
tagToUse = f'develop-{commitID}'
|
||||
return tagToUse
|
||||
|
||||
def AnalyzeBuildLogs(image, lf):
|
||||
committed = False
|
||||
tagged = False
|
||||
@@ -155,6 +174,7 @@ class Containerize():
|
||||
self.repository = ''
|
||||
self.branch = ''
|
||||
self.merge = False
|
||||
self.commitID = ''
|
||||
self.targetBranch = ''
|
||||
self.workspace = ''
|
||||
self.imageKind = ''
|
||||
@@ -423,7 +443,7 @@ class Containerize():
|
||||
if self.merge:
|
||||
orgTag = 'ci-temp'
|
||||
for image in IMAGES:
|
||||
tagToUse = tag_prefix + self.branch
|
||||
tagToUse = tag_prefix + CreateTag(self.commitID, self.branch, self.merge)
|
||||
imageTag = f"{image}:{tagToUse}"
|
||||
ret = ssh.run(f'docker image tag {image}:{orgTag} {imagePrefix}/{imageTag}')
|
||||
if ret.returncode != 0:
|
||||
@@ -484,7 +504,7 @@ class Containerize():
|
||||
def Pull_Image_from_Registry(self, HTML, node, images, tag=None, tag_prefix="", registry=DEFAULT_REGISTRY, username="oaicicd", password="oaicicd"):
|
||||
logging.debug(f'\u001B[1m Pulling image(s) on server: {node}\u001B[0m')
|
||||
if not tag:
|
||||
tag = self.branch
|
||||
tag = CreateTag(self.commitID, self.branch, self.merge)
|
||||
with cls_cmd.getConnection(node) as cmd:
|
||||
success, msg = Containerize.Pull_Image(cmd, images, tag, tag_prefix, registry, username, password)
|
||||
param = f"on node {node}"
|
||||
@@ -497,7 +517,7 @@ class Containerize():
|
||||
def Clean_Test_Server_Images(self, HTML, node, images, tag=None):
|
||||
logging.debug(f'\u001B[1m Cleaning image(s) from server: {node}\u001B[0m')
|
||||
if not tag:
|
||||
tag = self.branch
|
||||
tag = CreateTag(self.commitID, self.branch, self.merge)
|
||||
|
||||
status = True
|
||||
with cls_cmd.getConnection(node) as myCmd:
|
||||
@@ -516,10 +536,10 @@ class Containerize():
|
||||
return status
|
||||
|
||||
def Create_Workspace(self, node, HTML):
|
||||
sourcePath = self.workspace
|
||||
success = CreateWorkspace(node, sourcePath, self.repository, self.branch)
|
||||
lSourcePath = self.workspace
|
||||
success = CreateWorkspace(node, lSourcePath, self.repository, self.commitID, self.targetBranch, self.merge)
|
||||
if success:
|
||||
HTML.CreateHtmlTestRowQueue('N/A', 'OK', [f"created workspace {sourcePath} on node {node}"])
|
||||
HTML.CreateHtmlTestRowQueue('N/A', 'OK', [f"created workspace {lSourcePath}"])
|
||||
else:
|
||||
HTML.CreateHtmlTestRowQueue('N/A', 'KO', ["cannot create workspace"])
|
||||
return success
|
||||
|
||||
@@ -36,6 +36,8 @@ class HTMLManagement():
|
||||
self.repository = ''
|
||||
self.branch = ''
|
||||
self.commitID = ''
|
||||
self.merge = False
|
||||
self.targetBranch = ''
|
||||
|
||||
self.nbTestXMLfiles = 0
|
||||
self.htmlTabRefs = []
|
||||
@@ -97,15 +99,44 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' <td><a href="' + self.repository + '">' + self.repository + '</a></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-out"></span> Test Branch </td>\n')
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-wrench"></span> Job Trigger </td>\n')
|
||||
if (self.merge):
|
||||
self.htmlFile.write(' <td>Merge-Request</td>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <td>Push to Branch</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
if (self.merge):
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-out"></span> Source Branch </td>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tree-deciduous"></span> Branch</td>\n')
|
||||
self.htmlFile.write(' <td>' + self.branch + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.commitID, shell=True, universal_newlines=True)
|
||||
commit_message = commit_message.strip()
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Commit Message </td>\n')
|
||||
self.htmlFile.write(' <td>' + commit_message + '</td>\n')
|
||||
if (self.merge):
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Source Commit ID </td>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Commit ID </td>\n')
|
||||
self.htmlFile.write(' <td>' + self.commitID + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
if self.merge != '' and self.commitID != 'develop':
|
||||
commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.commitID, shell=True, universal_newlines=True)
|
||||
commit_message = commit_message.strip()
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
if (self.merge):
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Source Commit Message </td>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Commit Message </td>\n')
|
||||
self.htmlFile.write(' <td>' + commit_message + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
if (self.merge):
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-in"></span> Target Branch </td>\n')
|
||||
if (self.targetBranch == ''):
|
||||
self.htmlFile.write(' <td>develop</td>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <td>' + self.targetBranch + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' </table>\n')
|
||||
|
||||
self.htmlFile.write(' <br>\n')
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
|
||||
Active_gNBs = ( "gNB-OAI");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "gNB-OAI";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) });
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 1;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
|
||||
absoluteFrequencySSB = 641280;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3600 MHz
|
||||
dl_absoluteFrequencyPointA = 640008;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 106;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=27,L=48 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 106;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 28875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 148;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 13;
|
||||
preambleReceivedTargetPower = -96;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 10;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
#one (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant =-90;
|
||||
|
||||
# 0=sl1, 1=sl2, 2=sl4, 3=sl8, 4=sl10, 5=sl20, 6=sl40, 7=sl80, 8=sl160, 9=sl320
|
||||
msgB_ResponseWindow_r16 = 5;
|
||||
msgA_RSRP_Threshold_r16 = 19;
|
||||
|
||||
msgA_CB_PreamblesPerSSB_PerSharedRO_r16 = 1;
|
||||
|
||||
msgA_MCS_r16 = 2;
|
||||
nrofSlotsMsgA_PUSCH_r16 = 1;
|
||||
# 0=one, 1=two, 2=three, 3=six
|
||||
nrofMsgA_PO_PerSlot_r16 = 0;
|
||||
msgA_PUSCH_TimeDomainOffset_r16 = 8;
|
||||
startSymbolAndLengthMsgA_PO_r16 = 38;
|
||||
mappingTypeMsgA_PUSCH_r16 = 0;
|
||||
guardBandMsgA_PUSCH_r16 = 0;
|
||||
frequencyStartMsgA_PUSCH_r16 = 0;
|
||||
nrofPRBs_PerMsgA_PO_r16 = 8;
|
||||
# 0=one, 1=two, 2=four, 3=eight
|
||||
nrofMsgA_PO_FDM_r16 = 0;
|
||||
msgA_PUSCH_NrofPorts_r16 = 1;
|
||||
nrofDMRS_Sequences_r16 = 1;
|
||||
# 0=enabled, 1=disabled
|
||||
msgA_TransformPrecoder_r16 = 1;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ({ ipv4 = "192.168.71.132"; });
|
||||
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/24";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/24";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 120;
|
||||
pucch0_dtx_threshold = 100;
|
||||
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "yes"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 12;
|
||||
att_rx = 12;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
rfsimulator :
|
||||
{
|
||||
serveraddr = "server";
|
||||
serverport = 4043;
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs";
|
||||
};
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="debug";
|
||||
};
|
||||
|
||||
e2_agent = {
|
||||
near_ric_ip_addr = "127.0.0.1";
|
||||
#sm_dir = "/path/where/the/SMs/are/located/"
|
||||
sm_dir = "/usr/local/lib/flexric/"
|
||||
};
|
||||
@@ -207,40 +207,3 @@ channelmod:
|
||||
forgetfact: 0
|
||||
offset: 0
|
||||
ds_tdl: 0
|
||||
vrtsim:
|
||||
role: server
|
||||
# Channel mode: exactly one of the three modes below should be active.
|
||||
#
|
||||
# No channel - plain passthrough, no impairments:
|
||||
# cirdb: 0
|
||||
# chanmod: 0
|
||||
#
|
||||
# Built-in channel model defined in the channelmod: section above:
|
||||
# chanmod: 1
|
||||
# cirdb: 0
|
||||
#
|
||||
# External taps emitter publishing over a nanomsg socket.
|
||||
# Requires a running emit_from_db.py and build with -DOAI_VRTSIM_TAPS_CLIENT=ON:
|
||||
# cirdb: 0
|
||||
# chanmod: 0
|
||||
# taps-socket: "tcp://127.0.0.1:5555"
|
||||
#
|
||||
# In-process CIR database: reads precomputed 3GPP TDL taps directly from
|
||||
# cir_db.bin. No external emitter required. Generate the database offline
|
||||
# with cir_generator.py. Use cirdb-path to point to the directory containing
|
||||
# cir_db.bin and cir_db.yaml.
|
||||
cirdb_file: /cirdb/cir_db.bin
|
||||
cirdb_yaml: /cirdb/cir_db.yaml
|
||||
#
|
||||
# Per-UE channel configuration for multi-UE operation
|
||||
ue_config:
|
||||
- antennas: "2x2" # NxM where N=UE-TX, M=gNB-TX; M must equal RU nb_tx
|
||||
model_id: 0 # 0=TDL-A 1=TDL-B 2=TDL-C 3=TDL-D 4=TDL-E
|
||||
ds_ns: 1.0 # RMS delay spread in ns
|
||||
speed_mps: 1.5 # UE speed in m/s
|
||||
# aoa_deg: 0.0 # angle of arrival in degrees; TDL-D/E only
|
||||
- antennas: "1x2"
|
||||
model_id: 0
|
||||
ds_ns: 1.0
|
||||
speed_mps: 1.5
|
||||
# aoa_deg: 0.0
|
||||
|
||||
126
ci-scripts/doGitLabMerge.sh
Executable file
126
ci-scripts/doGitLabMerge.sh
Executable file
@@ -0,0 +1,126 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
|
||||
function usage {
|
||||
echo "OAI GitLab merge request applying script"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo ""
|
||||
echo " doGitLabMerge.sh [OPTIONS] [MANDATORY_OPTIONS]"
|
||||
echo ""
|
||||
echo "Mandatory Options:"
|
||||
echo "------------------"
|
||||
echo ""
|
||||
echo " --src-branch #### OR -sb ####"
|
||||
echo " Specify the source branch of the merge request."
|
||||
echo ""
|
||||
echo " --src-commit #### OR -sc ####"
|
||||
echo " Specify the source commit ID (SHA-1) of the merge request."
|
||||
echo ""
|
||||
echo " --target-branch #### OR -tb ####"
|
||||
echo " Specify the target branch of the merge request (usually develop)."
|
||||
echo ""
|
||||
echo " --target-commit #### OR -tc ####"
|
||||
echo " Specify the target commit ID (SHA-1) of the merge request."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo "--------"
|
||||
echo " --help OR -h"
|
||||
echo " Print this help message."
|
||||
echo ""
|
||||
}
|
||||
|
||||
if [ $# -ne 8 ] && [ $# -ne 1 ]
|
||||
then
|
||||
echo "Syntax Error: not the correct number of arguments"
|
||||
echo ""
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
checker=0
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
|
||||
case $key in
|
||||
-h|--help)
|
||||
shift
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-sb|--src-branch)
|
||||
SOURCE_BRANCH="$2"
|
||||
let "checker|=0x1"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-sc|--src-commit)
|
||||
SOURCE_COMMIT_ID="$2"
|
||||
let "checker|=0x2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-tb|--target-branch)
|
||||
TARGET_BRANCH="$2"
|
||||
let "checker|=0x4"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-tc|--target-commit)
|
||||
TARGET_COMMIT_ID="$2"
|
||||
let "checker|=0x8"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Syntax Error: unknown option: $key"
|
||||
echo ""
|
||||
usage
|
||||
exit 1
|
||||
esac
|
||||
|
||||
done
|
||||
|
||||
if [[ $TARGET_COMMIT_ID == "latest" ]]
|
||||
then
|
||||
TARGET_COMMIT_ID=`git log -n1 --pretty=format:%H origin/$TARGET_BRANCH`
|
||||
fi
|
||||
|
||||
echo "Source Branch is : $SOURCE_BRANCH"
|
||||
echo "Source Commit ID is : $SOURCE_COMMIT_ID"
|
||||
echo "Target Branch is : $TARGET_BRANCH"
|
||||
echo "Target Commit ID is : $TARGET_COMMIT_ID"
|
||||
|
||||
if [ $checker -ne 15 ]
|
||||
then
|
||||
echo ""
|
||||
echo "Syntax Error: missing option"
|
||||
echo ""
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git config user.email "jenkins@openairinterface.org"
|
||||
git config user.name "OAI Jenkins"
|
||||
|
||||
git checkout -f $SOURCE_COMMIT_ID > checkout.txt 2>&1
|
||||
STATUS=`grep -E -c "fatal: reference is not a tree" checkout.txt`
|
||||
rm -f checkout.txt
|
||||
if [ $STATUS -ne 0 ]
|
||||
then
|
||||
echo "fatal: reference is not a tree --> $SOURCE_COMMIT_ID"
|
||||
STATUS=-1
|
||||
exit $STATUS
|
||||
fi
|
||||
|
||||
git merge --ff $TARGET_COMMIT_ID -m "Temporary merge for CI"
|
||||
|
||||
STATUS=`git status | grep -E -c "You have unmerged paths.|fix conflicts"`
|
||||
if [ $STATUS -ne 0 ]
|
||||
then
|
||||
echo "There are merge conflicts.. Cannot perform further build tasks"
|
||||
STATUS=-1
|
||||
fi
|
||||
exit $STATUS
|
||||
@@ -26,7 +26,7 @@ RUN cmake -GNinja -DENABLE_PHYSIM_TESTS=ON -DENABLE_TESTS=ON \
|
||||
-DSANITIZE_UNDEFINED=OFF -DSANITIZE_ADDRESS=OFF \
|
||||
-DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror \
|
||||
-DPHYSIM_CHECK_FILES="ThresholdsCuda.cmake" \
|
||||
-DENABLE_CHANNEL_SIM_CUDA=ON \
|
||||
-DCUDA_ENABLE=ON \
|
||||
-DUSE_UNIFIED_MEMORY=ON \
|
||||
-DUSE_ATS_MEMORY=OFF \
|
||||
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/oai-ran/cmake_targets/ran_build/build \
|
||||
|
||||
@@ -26,7 +26,7 @@ RUN cmake -GNinja -DENABLE_PHYSIM_TESTS=ON -DENABLE_TESTS=ON \
|
||||
-DSANITIZE_UNDEFINED=OFF -DSANITIZE_ADDRESS=OFF \
|
||||
-DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror \
|
||||
-DPHYSIM_CHECK_FILES="ThresholdsCuda.cmake" \
|
||||
-DENABLE_CHANNEL_SIM_CUDA=ON \
|
||||
-DCUDA_ENABLE=ON \
|
||||
-DUSE_UNIFIED_MEMORY=ON \
|
||||
-DUSE_ATS_MEMORY=OFF \
|
||||
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/oai-ran/cmake_targets/ran_build/build \
|
||||
|
||||
@@ -22,4 +22,4 @@ WORKDIR /oai-ran
|
||||
COPY . .
|
||||
|
||||
WORKDIR /oai-ran/build
|
||||
RUN cmake -GNinja -DENABLE_TESTS=ON -DENABLE_CHANNEL_SIM_CUDA=ON .. && ninja tests
|
||||
RUN cmake -GNinja -DENABLE_TESTS=ON -DCUDA_ENABLE=ON .. && ninja tests
|
||||
|
||||
@@ -28,15 +28,16 @@ def GenericHelp(vers):
|
||||
print(' images are available locally, will not remove any images and will run inside the current repo directory')
|
||||
|
||||
def GitSrvHelp(repository,branch,commit,mergeallow,targetbranch):
|
||||
print(' --repository=[OAI RAN Repository URL] -- ' + repository)
|
||||
print(' --branch=[OAI RAN Repository Branch] -- ' + branch)
|
||||
print(' --commitID=[OAI RAN Repository Commit SHA-1] -- ' + commit)
|
||||
print(' --ranRepository=[OAI RAN Repository URL] -- ' + repository)
|
||||
print(' --ranBranch=[OAI RAN Repository Branch] -- ' + branch)
|
||||
print(' --ranCommitID=[OAI RAN Repository Commit SHA-1] -- ' + commit)
|
||||
print(' --ranAllowMerge=[Allow Merge Request (with target branch) (true or false)] -- ' + mergeallow)
|
||||
print(' --targetBranch=[Target Branch in case of a Merge Request] -- ' + targetbranch)
|
||||
print(' --ranTargetBranch=[Target Branch in case of a Merge Request] -- ' + targetbranch)
|
||||
|
||||
def SrvHelp(sourcepath):
|
||||
print(' --workspace=[directory for workspaces on remote hosts] -- ' + sourcepath)
|
||||
def eNBSrvHelp(sourcepath):
|
||||
print(' --eNBSourceCodePath=[eNB\'s Source Code Path] -- ' + sourcepath)
|
||||
|
||||
def XmlHelp(filename):
|
||||
print(' --XMLTestFile=[XML Test File to be run] -- ' + filename)
|
||||
print(' Note: multiple xml files can be specified (--XMLFile=File1 ... --XMLTestFile=FileN) when HTML headers are created ("InitiateHtml" mode)')
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ def ExecuteActionWithParam(action, ctx, node):
|
||||
elif action == 'Deploy_Run_OC_PhySim':
|
||||
oc_release = test.findtext('oc_release')
|
||||
script = "scripts/oc-deploy-physims.sh"
|
||||
image_tag = CLUSTER.branch
|
||||
image_tag = cls_containerize.CreateTag(CLUSTER.commitID, CLUSTER.branch, CLUSTER.merge)
|
||||
options = f"oaicicd-core-for-ci-ran {oc_release} {image_tag} {CLUSTER.workspace}"
|
||||
workdir = CLUSTER.workspace
|
||||
success = cls_oaicitest.Deploy_Physim(ctx, HTML, node, workdir, script, options)
|
||||
@@ -169,7 +169,7 @@ def ExecuteActionWithParam(action, ctx, node):
|
||||
CONTAINERS.yamlPath = test.findtext('yaml_path')
|
||||
CONTAINERS.services = test.findtext('services')
|
||||
CONTAINERS.num_attempts = int(test.findtext('num_attempts') or 1)
|
||||
CONTAINERS.deploymentTag = CONTAINERS.branch
|
||||
CONTAINERS.deploymentTag = cls_containerize.CreateTag(CONTAINERS.commitID, CONTAINERS.branch, CONTAINERS.merge)
|
||||
if action == 'Deploy_Object':
|
||||
success = CONTAINERS.DeployObject(ctx, node, HTML)
|
||||
elif action == 'Stop_Object':
|
||||
@@ -368,9 +368,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
|
||||
if RAN.repository == '' or RAN.branch == '' or RAN.workspace == '':
|
||||
HELP.GenericHelp(CONST.Version)
|
||||
if RAN.repository == '':
|
||||
HELP.GitSrvHelp(RAN.repository, RAN.branch, RAN.merge, RAN.targetBranch)
|
||||
HELP.GitSrvHelp(RAN.repository, RAN.branch, RAN.commitID, RAN.merge, RAN.targetBranch)
|
||||
if RAN.workspace == '':
|
||||
HELP.SrvHelp(RAN.workspace)
|
||||
HELP.eNBSrvHelp(RAN.workspace)
|
||||
sys.exit('Insufficient Parameter')
|
||||
else:
|
||||
if CiTestObj.repository == '' or CiTestObj.branch == '':
|
||||
|
||||
@@ -35,6 +35,7 @@ class RANManagement():
|
||||
self.repository = ''
|
||||
self.branch = ''
|
||||
self.merge = False
|
||||
self.commitID = ''
|
||||
self.targetBranch = ''
|
||||
self.workspace = ''
|
||||
self.Initialize_eNB_args = ''
|
||||
|
||||
@@ -30,13 +30,15 @@ docker tag oai-nr-ue oai-ci/oai-nr-ue:develop-${SHORT_COMMIT_SHA}
|
||||
docker tag oai-gnb oai-ci/oai-gnb:develop-${SHORT_COMMIT_SHA}
|
||||
docker tag oai-nr-cuup oai-ci/oai-nr-cuup:develop-${SHORT_COMMIT_SHA}
|
||||
|
||||
python3 main.py --mode=InitiateHtml --repository=NONE --branch=${CURRENT_BRANCH} \
|
||||
python3 main.py --mode=InitiateHtml --ranRepository=NONE --ranBranch=${CURRENT_BRANCH} \
|
||||
--ranCommitID=${COMMIT_SHA} --ranAllowMerge=false \
|
||||
--ranTargetBranch=NONE \
|
||||
--XMLTestFile=xml_files/${TESTCASE} --local --datefmt="%H:%M:%S"
|
||||
|
||||
python3 main.py --mode=TesteNB --repository=NONE --branch=${CURRENT_BRANCH} \
|
||||
--ranAllowMerge=false \
|
||||
--targetBranch=NONE \
|
||||
--workspace=${REPO_PATH} \
|
||||
python3 main.py --mode=TesteNB --ranRepository=NONE --ranBranch=${CURRENT_BRANCH} \
|
||||
--ranCommitID=${COMMIT_SHA} --ranAllowMerge=false \
|
||||
--ranTargetBranch=NONE \
|
||||
--eNBSourceCodePath=${REPO_PATH} \
|
||||
--XMLTestFile=${TESTCASE} --local --datefmt="%H:%M:%S"
|
||||
RET=$?
|
||||
|
||||
|
||||
@@ -6,16 +6,22 @@ function die() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ $# -eq 3 ] || die "usage: $0 <directory> <repository> <branch>"
|
||||
[ $# -ge 3 -a $# -le 4 ] || die "usage: $0 <directory> <repository> <ref> [<merge-ref>]"
|
||||
|
||||
set -ex
|
||||
|
||||
dir=$1
|
||||
repo=$2
|
||||
branch=$3
|
||||
ref=$3
|
||||
merge=$4
|
||||
|
||||
rm -rf ${dir}
|
||||
git clone --depth=1 --branch "${branch}" "${repo}" "${dir}"
|
||||
git clone --filter=blob:none -n ${repo} ${dir}
|
||||
cd ${dir}
|
||||
git config user.email "jenkins@openairinterface.org"
|
||||
git config user.name "OAI Jenkins"
|
||||
git config advice.detachedHead false
|
||||
mkdir -p cmake_targets/log
|
||||
git checkout -f ${ref}
|
||||
[ -n "${merge}" ] && git fetch origin ${merge} && git merge --ff FETCH_HEAD -m "Temporary merge for CI"
|
||||
exit 0
|
||||
|
||||
@@ -43,6 +43,7 @@ class TestDeploymentMethods(unittest.TestCase):
|
||||
self.cont.yamlPath = ''
|
||||
self.cont.merge = True
|
||||
self.cont.branch = ''
|
||||
self.cont.commitID = ''
|
||||
self.cont.workspace = os.getcwd()
|
||||
self.cont.num_attempts = 3
|
||||
self.node = 'localhost'
|
||||
@@ -137,6 +138,7 @@ class TestDeploymentMethods(unittest.TestCase):
|
||||
def test_create_workspace(self):
|
||||
self.cont.workspace = tempfile.mkdtemp()
|
||||
self.cont.repository = "https://gitlab.eurecom.fr/oai/openairinterface5g.git"
|
||||
self.cont.commitID = "05f9c975eeecbca1bdff5940affad44465f1301f"
|
||||
self.cont.branch = "develop"
|
||||
ws = self.cont.Create_Workspace(self.node, self.html)
|
||||
with cls_cmd.LocalCmd() as cmd:
|
||||
|
||||
@@ -9,17 +9,21 @@ rm -f ${file}
|
||||
cd ../../
|
||||
python3 main.py \
|
||||
--mode=InitiateHtml \
|
||||
--repository=https://gitlab.eurecom.fr/oai/openairinterface5g.git \
|
||||
--branch=${branch} \
|
||||
--ranRepository=https://gitlab.eurecom.fr/oai/openairinterface5g.git \
|
||||
--ranBranch=${branch} \
|
||||
--ranCommitID=${commit} \
|
||||
--ranAllowMerge=true \
|
||||
--ranTargetBranch=develop \
|
||||
--XMLTestFile=tests/test-runner/test.xml
|
||||
|
||||
python3 main.py \
|
||||
--mode=TesteNB \
|
||||
--repository=https://gitlab.eurecom.fr/oai/openairinterface5g.git \
|
||||
--branch=${branch} \
|
||||
--ranRepository=https://gitlab.eurecom.fr/oai/openairinterface5g.git \
|
||||
--ranBranch=${branch} \
|
||||
--ranCommitID=${commit} \
|
||||
--ranAllowMerge=true \
|
||||
--targetBranch=develop \
|
||||
--workspace=NONE \
|
||||
--ranTargetBranch=develop \
|
||||
--eNBSourceCodePath=NONE \
|
||||
--XMLTestFile=tests/test-runner/test.xml
|
||||
|
||||
python3 main.py \
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>obelix</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>gracehopper3-oai</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>jetson3-oai</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>hutch</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>hutch</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>hutch</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>hutch</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>hutch</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>hutch</node>
|
||||
</testCase>
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 1</desc>
|
||||
<node>carabe</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>hutch</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>starsky</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>starsky</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>starsky</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>starsky</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>starsky</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>gracehopper1-oai</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>gracehopper1-oai</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>ofqot</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>cacofonix</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>cacofonix</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<desc>Create new Workspace for server 0</desc>
|
||||
<node>cacofonix</node>
|
||||
</testCase>
|
||||
|
||||
|
||||
85
ci-scripts/xml_files/monolithic_2step_ra_gnb_rfsim.xml
Normal file
85
ci-scripts/xml_files/monolithic_2step_ra_gnb_rfsim.xml
Normal file
@@ -0,0 +1,85 @@
|
||||
<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->
|
||||
|
||||
<testCaseList>
|
||||
<htmlTabRef>monolithic_2step_ra_gnb_rfsim</htmlTabRef>
|
||||
<htmlTabName>Monolithic 2-Step RA gNB rfsim</htmlTabName>
|
||||
<htmlTabIcon>wrench</htmlTabIcon>
|
||||
|
||||
<testCase>
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
<node>localhost</node>
|
||||
<images>oai-gnb-asan oai-nr-ue-asan</images>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<node>localhost</node>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy OAI gNB</desc>
|
||||
<node>localhost</node>
|
||||
<yaml_path>ci-scripts/yaml_files/monolithic_2step_ra_gnb_rfsim</yaml_path>
|
||||
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy OAI NR-UE</desc>
|
||||
<node>localhost</node>
|
||||
<yaml_path>ci-scripts/yaml_files/monolithic_2step_ra_gnb_rfsim</yaml_path>
|
||||
<services>oai-gnb oai-nr-ue</services>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach OAI UE (Wait for IP)</desc>
|
||||
<id>rfsim5g_ue</id>
|
||||
<node>localhost</node>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Ping</class>
|
||||
<desc>Ping ext-dn from NR-UE</desc>
|
||||
<id>rfsim5g_ue</id>
|
||||
<node>localhost</node>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>localhost</svr_node>
|
||||
<ping_args>-c 20 -i0.2</ping_args>
|
||||
<ping_packetloss_threshold>0</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Ping</class>
|
||||
<desc>Ping NR-UE from ext-dn</desc>
|
||||
<id>rfsim5g_ext_dn</id>
|
||||
<node>localhost</node>
|
||||
<svr_id>rfsim5g_ue</svr_id>
|
||||
<svr_node>localhost</svr_node>
|
||||
<ping_args>-c 20 -i0.2</ping_args>
|
||||
<ping_packetloss_threshold>0</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Undeploy_Object</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<node>localhost</node>
|
||||
<yaml_path>ci-scripts/yaml_files/monolithic_2step_ra_gnb_rfsim</yaml_path>
|
||||
<analysis>
|
||||
<services>oai-gnb=RetxCheck=10,0,0,0 oai-gnb=EndsWithBye oai-nr-ue</services>
|
||||
</analysis>
|
||||
</testCase>
|
||||
|
||||
<testCase>
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<node>localhost</node>
|
||||
<images>oai-gnb-asan oai-nr-ue-asan</images>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
@@ -97,7 +97,7 @@ services:
|
||||
cap_drop:
|
||||
- ALL
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role server --vrtsim.chanmod 1 --vrtsim.num_ues 1
|
||||
USE_ADDITIONAL_OPTIONS: -E --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role server --vrtsim.chanmod 1
|
||||
depends_on:
|
||||
- oai-ext-dn
|
||||
networks:
|
||||
@@ -123,7 +123,7 @@ services:
|
||||
- NET_ADMIN # for interface bringup
|
||||
- NET_RAW # for ping
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --uicc0.imsi 208990100001100 --log_config.global_log_options level,nocolor,time --device.name vrtsim --ue-nb-ant-rx 2 --ue-nb-ant-tx 2
|
||||
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --uicc0.imsi 208990100001100 --log_config.global_log_options level,nocolor,time --device.name vrtsim
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
|
||||
@@ -111,7 +111,7 @@ services:
|
||||
cap_drop:
|
||||
- ALL
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role server --vrtsim.cirdb 1 --vrtsim.num_ues 1
|
||||
USE_ADDITIONAL_OPTIONS: -E --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role server --vrtsim.cirdb 1 --vrtsim.cirdb_file /cirdb/cir_db.bin --vrtsim.cirdb_yaml /cirdb/cir_db.yaml --vrtsim.cirdb_model_id 0 --vrtsim.cirdb_ds_ns 1 --vrtsim.cirdb_speed_mps 1.5
|
||||
depends_on:
|
||||
cir-generator:
|
||||
condition: service_completed_successfully
|
||||
@@ -142,7 +142,7 @@ services:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --uicc0.imsi 208990100001100 --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role client --ue-nb-ant-rx 2 --ue-nb-ant-tx 2
|
||||
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --uicc0.imsi 208990100001100 --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role client
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
|
||||
@@ -111,7 +111,7 @@ services:
|
||||
cap_drop:
|
||||
- ALL
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role server --vrtsim.cirdb 1 --vrtsim.num_ues 2 --gNBs.[0].min_rxtxtime 8
|
||||
USE_ADDITIONAL_OPTIONS: -E --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role server --vrtsim.num_ues 2 --vrtsim.cirdb 1 --vrtsim.cirdb_file /cirdb/cir_db.bin --vrtsim.cirdb_yaml /cirdb/cir_db.yaml --vrtsim.ue_config.[0].antennas 1x2 --vrtsim.ue_config.[0].model_id 0 --vrtsim.ue_config.[0].ds_ns 10.0 --vrtsim.ue_config.[0].speed_mps 1.5 --vrtsim.ue_config.[1].antennas 2x2 --vrtsim.ue_config.[1].model_id 1 --vrtsim.ue_config.[1].ds_ns 10.0 --vrtsim.ue_config.[1].speed_mps 1.5 --gNBs.[0].min_rxtxtime 8
|
||||
depends_on:
|
||||
cir-generator:
|
||||
condition: service_completed_successfully
|
||||
@@ -142,7 +142,7 @@ services:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3319680000 --ssb 516 --uicc0.imsi 208990100001100 --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role client --vrtsim.ue_id 0 --ue-nb-ant-tx 2 --ue-nb-ant-rx 2
|
||||
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3319680000 --ssb 516 --uicc0.imsi 208990100001100 --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role client --vrtsim.ue_id 0 --ue-nb-ant-tx 1 --ue-nb-ant-rx 2
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
@@ -171,7 +171,7 @@ services:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3319680000 --ssb 516 --uicc0.imsi 208990100001101 --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role client --vrtsim.ue_id 1 --ue-nb-ant-tx 1 --ue-nb-ant-rx 2
|
||||
USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3319680000 --ssb 516 --uicc0.imsi 208990100001101 --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role client --vrtsim.ue_id 1 --ue-nb-ant-tx 2 --ue-nb-ant-rx 2
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
services:
|
||||
mysql:
|
||||
container_name: "rfsim5g-mysql"
|
||||
image: mysql:9.6
|
||||
init: true
|
||||
volumes:
|
||||
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
|
||||
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- MYSQL_DATABASE=oai_db
|
||||
- MYSQL_USER=test
|
||||
- MYSQL_PASSWORD=test
|
||||
- MYSQL_ROOT_PASSWORD=linux
|
||||
healthcheck:
|
||||
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
|
||||
start_period: 10s
|
||||
start_interval: 500ms
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.131
|
||||
oai-amf:
|
||||
container_name: "rfsim5g-oai-amf"
|
||||
image: oaisoftwarealliance/oai-amf:v2.2.1
|
||||
environment:
|
||||
- TZ=Europe/paris
|
||||
volumes:
|
||||
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-amf/etc/config.yaml
|
||||
depends_on:
|
||||
- mysql
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.132
|
||||
oai-smf:
|
||||
container_name: "rfsim5g-oai-smf"
|
||||
image: oaisoftwarealliance/oai-smf:v2.2.1
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-smf/etc/config.yaml
|
||||
depends_on:
|
||||
- oai-amf
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.133
|
||||
oai-upf:
|
||||
container_name: "rfsim5g-oai-upf"
|
||||
image: oaisoftwarealliance/oai-upf:v2.2.1
|
||||
init: true
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
volumes:
|
||||
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-upf/etc/config.yaml
|
||||
depends_on:
|
||||
- oai-smf
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
cap_drop:
|
||||
- ALL
|
||||
privileged: true
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.134
|
||||
interface_name: eth0
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.134
|
||||
interface_name: eth1
|
||||
oai-ext-dn:
|
||||
privileged: true
|
||||
container_name: rfsim5g-oai-ext-dn
|
||||
image: oaisoftwarealliance/trf-gen-cn5g:latest
|
||||
init: true
|
||||
entrypoint: /bin/bash -c \
|
||||
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
|
||||
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
|
||||
depends_on:
|
||||
- oai-upf
|
||||
networks:
|
||||
traffic_net:
|
||||
ipv4_address: 192.168.72.135
|
||||
healthcheck:
|
||||
test: /bin/bash -c "ping -c 2 192.168.72.134"
|
||||
start_period: 10s
|
||||
start_interval: 500ms
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
oai-gnb:
|
||||
image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop}
|
||||
container_name: rfsim5g-oai-gnb
|
||||
cap_drop:
|
||||
- ALL
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --rfsim --log_config.global_log_options level,nocolor,time
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.140
|
||||
volumes:
|
||||
- ../../conf_files/gnb.sa.band78.106prb.usrpb210.RA_2-Step.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
start_period: 10s
|
||||
start_interval: 500ms
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue:
|
||||
image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop}
|
||||
container_name: rfsim5g-oai-nr-ue
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- NET_ADMIN # for interface bringup
|
||||
- NET_RAW # for ping
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --rfsim
|
||||
--rfsimulator.[0].serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
|
||||
-C 3619200000 -r 106 --numerology 1 --ssb 516 --band 78
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
volumes:
|
||||
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.150
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-uesoftmodem"
|
||||
start_period: 10s
|
||||
start_interval: 500ms
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
networks:
|
||||
public_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-public-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.71.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-public"
|
||||
traffic_net:
|
||||
driver: bridge
|
||||
name: rfsim5g-oai-traffic-net
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 192.168.72.128/26
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: "rfsim5g-traffic"
|
||||
@@ -88,85 +88,3 @@ function(run_asn1c ASN1C_GRAMMAR ASN1C_PREFIX)
|
||||
COMMENT "Generating ${ASN1C_COMMENT} from ${GRAMMAR_FILE}"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
define_property(TEST PROPERTY TEST_DESCRIPTION
|
||||
BRIEF_DOCS "A human-readable description of this test"
|
||||
FULL_DOCS "A human-readable description of this test")
|
||||
|
||||
define_property(TEST PROPERTY CHECK_COUNT
|
||||
BRIEF_DOCS "helper property to enumerate checks in environment"
|
||||
FULL_DOCS "the property counts the number of threshold checks, used to enumerate environment variables given to analyze-timing.sh")
|
||||
|
||||
function(add_physim_test test_name test_description test_exec)
|
||||
# catch all the arguments past the last expected arqument and store them in the options_list
|
||||
if (NOT TARGET ${test_exec})
|
||||
message(FATAL_ERROR "test executable ${test_exec} is not an executable")
|
||||
endif()
|
||||
set(test_invocation $<TARGET_FILE:${test_exec}> ${ARGN})
|
||||
add_test(
|
||||
NAME ${test_name}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
"-DTEST_CMD=${test_invocation}"
|
||||
"-DCHECK_SCRIPT=${CMAKE_SOURCE_DIR}/openair1/SIMULATION/tests/analyze-timing.sh"
|
||||
-P ${CMAKE_SOURCE_DIR}/openair1/SIMULATION/tests/RunTimedTest.cmake
|
||||
)
|
||||
set_tests_properties(${test_name} PROPERTIES
|
||||
LABELS "${test_exec}"
|
||||
TEST_DESCRIPTION "${test_description}"
|
||||
# pass test description also through environment variable: for cmake < 3.30,
|
||||
# in JSON export, we cannot recover the description otherwise
|
||||
# see also https://gitlab.kitware.com/cmake/cmake/-/issues/21490
|
||||
ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR};TEST_DESCRIPTION=${test_description}"
|
||||
)
|
||||
set_tests_properties(${test_name} PROPERTIES CHECK_COUNT 0)
|
||||
add_dependencies(tests ${test_exec})
|
||||
endfunction()
|
||||
|
||||
function(check_threshold testname threshold condition)
|
||||
# check that threshold and condition don't have a colon (;), because that
|
||||
# would interfere with cmake's list management
|
||||
string(FIND "${threshold}" ";" pos)
|
||||
if (pos GREATER -1)
|
||||
message(FATAL_ERROR "colon not allowed in threshold, but have \"${threshold}\"")
|
||||
endif()
|
||||
string(FIND "${condition}" ";" pos)
|
||||
if (pos GREATER -1)
|
||||
message(FATAL_ERROR "colon not allowed in condition, but have \"${condition}\"")
|
||||
endif()
|
||||
set(THRCOND "${threshold}\;${condition}")
|
||||
|
||||
get_test_property(${testname} CHECK_COUNT count)
|
||||
#message(STATUS "add check ${count} ${THRCOND}")
|
||||
if (${count} GREATER 10)
|
||||
message(FATAL_ERROR "only maximum of 10 checks per test allowed")
|
||||
endif()
|
||||
|
||||
# add a new environment variable CHECK_X with this threshold+condition, then
|
||||
# increase test property regarding check count
|
||||
set_property(TEST ${testname} APPEND PROPERTY ENVIRONMENT "CHECK_${count}=${THRCOND}")
|
||||
MATH(EXPR count "${count}+1")
|
||||
set_tests_properties(${testname} PROPERTIES CHECK_COUNT ${count})
|
||||
endfunction()
|
||||
|
||||
function(check_threshold_range testname threshold)
|
||||
cmake_parse_arguments(RANGE "" "LOWER;UPPER" "" ${ARGN})
|
||||
if (NOT RANGE_LOWER AND NOT RANGE_UPPER)
|
||||
message(FATAL_ERROR "need at least one LOWER or one UPPER threshold")
|
||||
endif()
|
||||
if (RANGE_LOWER)
|
||||
check_threshold(${testname} ${threshold} "> ${RANGE_LOWER}")
|
||||
endif()
|
||||
if (RANGE_UPPER)
|
||||
check_threshold(${testname} ${threshold} "< ${RANGE_UPPER}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(check_threshold_variance testname threshold)
|
||||
cmake_parse_arguments(VARIANCE "" "AVG;ABS_VAR" "" ${ARGN})
|
||||
if (NOT VARIANCE_AVG AND NOT VARIANCE_ABS_VAR)
|
||||
message(FATAL_ERROR "need both AVG and ABS_VAR")
|
||||
endif()
|
||||
MATH(EXPR upper "${VARIANCE_AVG}+${VARIANCE_ABS_VAR}")
|
||||
MATH(EXPR lower "${VARIANCE_AVG}-${VARIANCE_ABS_VAR}")
|
||||
check_threshold_range(${testname} ${threshold} LOWER ${lower} UPPER ${upper})
|
||||
endfunction()
|
||||
|
||||
@@ -83,13 +83,11 @@ get_distribution_release() {
|
||||
check_supported_distribution() {
|
||||
local distribution=$(get_distribution_release)
|
||||
case "$distribution" in
|
||||
"ubuntu26.04") return 0 ;;
|
||||
"ubuntu24.04") return 0 ;;
|
||||
"ubuntu22.04") return 0 ;;
|
||||
"debian11") return 0 ;;
|
||||
"debian12") return 0 ;;
|
||||
"fedora43") return 0 ;;
|
||||
"fedora44") return 0 ;;
|
||||
"rhel9.0") return 0 ;;
|
||||
"rhel9.1") return 0 ;;
|
||||
"rhel9.2") return 0 ;;
|
||||
@@ -98,7 +96,6 @@ check_supported_distribution() {
|
||||
"rhel9.5") return 0 ;;
|
||||
"rhel9.6") return 0 ;;
|
||||
"rhel9.7") return 0 ;;
|
||||
"rhel9.8") return 0 ;;
|
||||
"centos9") return 0 ;; # CentOS stream
|
||||
"rocky9.1") return 0 ;;
|
||||
"rocky9.2") return 0 ;;
|
||||
@@ -107,7 +104,6 @@ check_supported_distribution() {
|
||||
"rocky9.5") return 0 ;;
|
||||
"rocky9.6") return 0 ;;
|
||||
"rocky9.7") return 0 ;;
|
||||
"rocky9.8") return 0 ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
@@ -145,8 +141,12 @@ install_usrp_uhd_driver_from_source(){
|
||||
# - 3.15.0.0
|
||||
git apply $OPENAIR_DIR/cmake_targets/tools/uhd-3.15-tdd-patch.diff
|
||||
ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch"
|
||||
elif [[ "$UHD_VERSION" == "4.10.0.0" || "$UHD_VERSION" == "4.9.0.0" || "$UHD_VERSION" == "4.8.0.0" || "$UHD_VERSION" == "4.7.0.0" || "$UHD_VERSION" == "4.6.0.0" || "$UHD_VERSION" == "4.5.0.0" ]]; then
|
||||
# Tested patch for versions listed in elif clause
|
||||
elif [[ "$UHD_VERSION" == "4.8.0.0" || "$UHD_VERSION" == "4.7.0.0" || "$UHD_VERSION" == "4.6.0.0" || "$UHD_VERSION" == "4.5.0.0" ]]; then
|
||||
# Tested that patch for the following versions:
|
||||
# - 4.7.0.0
|
||||
cp $OPENAIR_DIR/cmake_targets/tools/uhd-4.x-tdd-patch.diff $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff
|
||||
sed -i '9,13 s/STATE_OFF/STATE_RX1_OFF/' $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff
|
||||
sed -i '24,28 s/STATE_OFF/STATE_RX2_OFF/' $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff
|
||||
git apply $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff
|
||||
ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch"
|
||||
else
|
||||
@@ -162,8 +162,8 @@ install_usrp_uhd_driver_from_source(){
|
||||
ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch"
|
||||
fi
|
||||
else
|
||||
git checkout tags/v4.8.0.0
|
||||
git apply $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff
|
||||
git checkout tags/v4.0.0.0
|
||||
git apply $OPENAIR_DIR/cmake_targets/tools/uhd-4.x-tdd-patch.diff
|
||||
ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch"
|
||||
fi
|
||||
# Printing out the results of the patch to make sure it was properly applied
|
||||
@@ -199,14 +199,29 @@ check_install_usrp_uhd_driver(){
|
||||
install_usrp_uhd_driver_from_source
|
||||
return
|
||||
fi
|
||||
# The new USRP repository
|
||||
# Raphael Defosseux: Adding a loop on adding PPA because in CI the gpg key retrieve may
|
||||
# timeout due to proxy / network latencies in Eurecom on VM
|
||||
echo_info "\nAdding PPA repository ettusresearch/uhd\n"
|
||||
$SUDO add-apt-repository ppa:ettusresearch/uhd -y
|
||||
x=0
|
||||
while [ $x -le 5 ]
|
||||
do
|
||||
if $SUDO add-apt-repository ppa:ettusresearch/uhd -y
|
||||
then
|
||||
echo_info "add-apt-repository successful\n"
|
||||
break
|
||||
else
|
||||
echo_info "add-apt-repository failed, retrying...\n"
|
||||
sleep 30
|
||||
fi
|
||||
x=$((x + 1))
|
||||
done
|
||||
$SUDO apt-get update
|
||||
$SUDO apt-get -y install python3-tk $boost_libs_ubuntu libusb-1.0-0-dev
|
||||
case "$(get_distribution_release)" in
|
||||
"ubuntu22.04") $SUDO apt-get -y install libuhd-dev libuhd4.5.0 uhd-host ;;
|
||||
"ubuntu24.04") $SUDO apt-get -y install libuhd-dev libuhd4.8.0 uhd-host ;;
|
||||
"ubuntu26.04") $SUDO apt-get -y install libuhd-dev libuhd4.9.0 uhd-host ;;
|
||||
"ubuntu22.04")
|
||||
$SUDO apt-get -y install libuhd-dev libuhd4.5.0 uhd-host
|
||||
;;
|
||||
esac
|
||||
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
|
||||
boost_libs_fedora="boost-chrono boost-date-time boost-filesystem boost-program-options boost-thread boost-test boost-regex boost-devel"
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
|
||||
index 6de161e87..432af5784 100644
|
||||
--- a/host/lib/usrp/b200/b200_impl.cpp
|
||||
+++ b/host/lib/usrp/b200/b200_impl.cpp
|
||||
@@ -1410,10 +1410,10 @@ void b200_impl::update_atrs(void)
|
||||
if (not enb_rx and enb_tx)
|
||||
fd = txonly;
|
||||
gpio_atr_3000::sptr atr = perif.atr;
|
||||
- atr->set_atr_reg(ATR_REG_IDLE, STATE_RX1_OFF);
|
||||
- atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly);
|
||||
- atr->set_atr_reg(ATR_REG_TX_ONLY, txonly);
|
||||
- atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd);
|
||||
+ atr->set_atr_reg(ATR_REG_IDLE, STATE_RX1_OFF | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd | (1<<7));
|
||||
}
|
||||
if (_radio_perifs.size() > _fe2 and _radio_perifs[_fe2].atr) {
|
||||
radio_perifs_t& perif = _radio_perifs[_fe2];
|
||||
@@ -1431,10 +1431,10 @@ void b200_impl::update_atrs(void)
|
||||
if (not enb_rx and enb_tx)
|
||||
fd = txonly;
|
||||
gpio_atr_3000::sptr atr = perif.atr;
|
||||
- atr->set_atr_reg(ATR_REG_IDLE, STATE_RX2_OFF);
|
||||
- atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly);
|
||||
- atr->set_atr_reg(ATR_REG_TX_ONLY, txonly);
|
||||
- atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd);
|
||||
+ atr->set_atr_reg(ATR_REG_IDLE, STATE_RX2_OFF | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd | (1<<7));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# define NUMBER_OF_SCH_STATS_MAX 16
|
||||
|
||||
|
||||
# ifndef PHYSIM
|
||||
# ifndef UE_EXPANSION
|
||||
# define NUMBER_OF_UE_MAX 40
|
||||
# define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||
@@ -26,5 +27,10 @@
|
||||
# define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||
# define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||
# endif
|
||||
# else
|
||||
# define NUMBER_OF_UE_MAX 4
|
||||
# define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||
# define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||
# endif
|
||||
|
||||
#endif /* OPENAIRINTERFACE5G_LIMITS_H_ */
|
||||
|
||||
@@ -62,7 +62,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef malloc16
|
||||
#define malloc16(x) memalign(64, x + 64)
|
||||
# define malloc16(x) memalign(32,x+32)
|
||||
#endif
|
||||
#define free16(y,x) free(y)
|
||||
#define openair_free(y,x) free((y))
|
||||
@@ -76,7 +76,7 @@ extern "C" {
|
||||
} while (0)
|
||||
|
||||
static inline void *malloc16_clear( size_t size ) {
|
||||
void *ptr = memalign(64, size + 64);
|
||||
void *ptr = memalign(32, size+32);
|
||||
DevAssert(ptr);
|
||||
memset( ptr, 0, size );
|
||||
return ptr;
|
||||
@@ -110,7 +110,7 @@ static inline void *malloc_or_fail(size_t size)
|
||||
# define msg(aRGS...) LOG_D(PHY, ##aRGS)
|
||||
#endif
|
||||
#ifndef malloc16
|
||||
#define malloc16(x) memalign(64, x)
|
||||
# define malloc16(x) memalign(32,x)
|
||||
#endif
|
||||
|
||||
#define free16(y,x) free(y)
|
||||
|
||||
@@ -192,7 +192,7 @@ Now, when installing the pre-requisites, especially the `UHD` driver, you can no
|
||||
|
||||
```bash
|
||||
export BUILD_UHD_FROM_SOURCE=True
|
||||
export UHD_VERSION=4.10.0.0
|
||||
export UHD_VERSION=3.15.0.0
|
||||
./build_oai -I -w USRP
|
||||
```
|
||||
|
||||
@@ -206,7 +206,6 @@ See:
|
||||
|
||||
* `cmake_targets/tools/uhd-3.15-tdd-patch.diff`
|
||||
* `cmake_targets/tools/uhd-4.x-tdd-patch.diff`
|
||||
* `cmake_targets/tools/uhd-4.5plus-tdd-patch.diff`
|
||||
* `cmake_targets/tools/build_helper` --> function `install_usrp_uhd_driver_from_source`
|
||||
|
||||
### Building PHY Simulators
|
||||
|
||||
@@ -10,9 +10,7 @@ out the various configuration options that influence its behavior.
|
||||
|
||||
The 5G MAC scheduler is a proportional fair (PF) scheduler, "approximating
|
||||
wide-band CQI" (for lack of a better term, but CQI is typically used for PF)
|
||||
through the selection of an MCS to use. For a detailed description of the
|
||||
scheduler pipeline and how to replace individual policies, see
|
||||
[Scheduler Architecture](scheduler-architecture.md).
|
||||
through the selection of an MCS to use.
|
||||
|
||||
Concretely, the scheduler loops through all UEs and calculates the PF
|
||||
coefficient using the currently selected MCS, and the historical achieved rate.
|
||||
@@ -24,13 +22,9 @@ UEs with retransmissions are allocated first; similarly, UEs that have not been
|
||||
scheduled for some time in UL are scheduled automatically in UL and have
|
||||
therefore priority over data with "normal" traffic.
|
||||
|
||||
The MCS selection is done in `nr_dl_mcs_select_default()` / `nr_ul_mcs_select_default()` in files
|
||||
[`gNB_scheduler_dlsch_default_policies.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch_default_policies.c)
|
||||
and
|
||||
[`gNB_scheduler_ulsch_default_policies.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch_default_policies.c).
|
||||
The BLER estimation itself is computed separately in `update_bler_stats()` in
|
||||
[`gNB_scheduler_primitives.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c),
|
||||
and the MCS policy reads the result. It considers two thresholds for a "BLER" that is computed from the number of
|
||||
The MCS selection is done in `get_mcs_from_bler()` in file
|
||||
[`gNB_scheduler_primitives.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c).
|
||||
It consider two thresholds for a "BLER" that is computed from the number of
|
||||
first-round retransmissions over total transmissions in the last window (50ms).
|
||||
If that ratio is higher than an "upper" threshold (see
|
||||
`dl/ul_bler_target_upper` in the configuration section below), it is
|
||||
@@ -39,11 +33,11 @@ lower than a "lower" threshold (see `dl/ul_bler_target_lower`), it is
|
||||
interpreted as "good channel" and MCS is incremented by 1. This happens each
|
||||
window.
|
||||
|
||||
The actual scheduler implementation can be found in functions `nr_dl_proportional_fair()` and
|
||||
`nr_ul_proportional_fair()` in files
|
||||
[`gNB_scheduler_dlsch_default_policies.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch_default_policies.c)
|
||||
The actual scheduler implementation can be found in functions `pf_dl()` and
|
||||
`pf_ul()` in files
|
||||
[`gNB_scheduler_dlsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c)
|
||||
(for DL) and
|
||||
[`gNB_scheduler_ulsch_default_policies.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch_default_policies.c)
|
||||
[`gNB_scheduler_ulsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c)
|
||||
(for UL), respectively.
|
||||
|
||||
## PDCCH aggregation level
|
||||
@@ -126,8 +120,9 @@ Example:
|
||||
UE RNTI 2460 CU-UE-ID 2 in-sync PH 28 dB PCMAX 24 dBm, average RSRP -74 (8 meas), average SINR 40.0 (32 meas)
|
||||
UE 2460: CQI 15, RI 2, PMI (14,1)
|
||||
UE 2460: UL-RI 2 TPMI 0
|
||||
UE 2460: dlsch_rounds 32917/5113/1504/560, dlsch_errors 211, pucch0_DTX 1385 (SNR 19.8+0.2 dB), BLER 0.19557 MCS (1) 23 CCE fail 3, goodput 120.50 Mbps
|
||||
UE 2460: ulsch_rounds 3756/353/182/179, ulsch_errors 170, ulsch_DTX 285, BLER 0.33021 MCS (1) 27 (Qm 8 deltaMCS 0 dB) NPRB 5 SNR 31.0 (-1.0) dB CCE fail 0, goodput 12.30 Mbps
|
||||
UE 2460: dlsch_rounds 32917/5113/1504/560, dlsch_errors 211, pucch0_DTX 1385 (SNR 19.8+0.2 dB), BLER 0.19557 MCS (1) 23 CCE fail 3
|
||||
UE 2460: ulsch_rounds 3756/353/182/179, ulsch_errors 170, ulsch_DTX 285, BLER 0.33021 MCS (1) 27 (Qm 8 dB) NPRB 5 SNR 31.0 (-1.0) dB CCE fail 0
|
||||
UE 2460: MAC: TX 1530943191 RX 194148 bytes
|
||||
UE 2460: LCID 1: TX 651 RX 3031 bytes
|
||||
UE 2460: LCID 2: TX 0 RX 0 bytes
|
||||
UE 2460: LCID 4: TX 1526169592 RX 16152 bytes
|
||||
@@ -214,11 +209,11 @@ The fourth and fifth line show HARQ-related information:
|
||||
* Both ULSCH/DLSCH `CCE fail`: lists the number of failed CCE attempts. If this
|
||||
number gets high, it signifies that the scheduler tried to scheduled this UE,
|
||||
but could not allocate the DCI.
|
||||
* Both ULSCH/DLSCH `goodput`: smoothed (EWMA) goodput in Mbps, reflecting the
|
||||
actual MAC-layer throughput achieved by the UE.
|
||||
|
||||
In the last lines:
|
||||
|
||||
* `MAC` shows the amount of MAC PDU bytes scheduled in transmit (`TX`,
|
||||
`1530943191`) and receive (`RX`, `194148`) directions
|
||||
* `LCID X` shows the amount of MAC SDU/RLC PDU data for Logical Channel ID with
|
||||
ID `X` in transmit and receive directions. LCIDs 1 and 2 are mapped to SRBs 1
|
||||
and 2. LCIDs 4 and onward are mapped to DRBs 1 onward. If you have an LCID 4,
|
||||
|
||||
@@ -1,433 +0,0 @@
|
||||
# gNB MAC Scheduler Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
The gNB MAC scheduler runs once per DL slot. It allocates PDSCH resources for the
|
||||
current slot and PUSCH resources for a future UL slot (selected via K2), sending the
|
||||
UL DCI grant in the current DL slot. The DL and UL schedulers follow the same pipeline
|
||||
design: a fixed orchestration loop calls a sequence of **pluggable function pointers**,
|
||||
each handling one stage of the scheduling decision. Any stage can be replaced
|
||||
independently without touching the rest of the pipeline.
|
||||
|
||||
Both schedulers send their DCIs in the same DL slot and share the same physical
|
||||
CORESET/CCE resources. The UL scheduler runs first (`nr_schedule_ulsch` in
|
||||
`gNB_scheduler.c`), then the DL scheduler (`nr_schedule_ue_spec`). CCEs are claimed on
|
||||
a first-come basis via `get_cce_index` + `fill_pdcch_vrb_map`, so UL DCIs take
|
||||
priority. If CCE space is tight, DL UEs are more likely to be skipped. The two
|
||||
schedulers use separate FAPI containers (`UL_dci_req` for UL grants, `DL_req` for DL
|
||||
grants) but the underlying CCE map is shared.
|
||||
|
||||
All scheduler code lives under `openair2/LAYER2/NR_MAC_gNB/`. The DL scheduler is in
|
||||
[`gNB_scheduler_dlsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c),
|
||||
the UL scheduler in
|
||||
[`gNB_scheduler_ulsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c),
|
||||
and shared primitives in
|
||||
[`gNB_scheduler_primitives.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c).
|
||||
Data structures and typedefs are in
|
||||
[`nr_mac_gNB.h`](../../openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h).
|
||||
Default policy implementations are in
|
||||
[`gNB_scheduler_dlsch_default_policies.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch_default_policies.c)
|
||||
and
|
||||
[`gNB_scheduler_ulsch_default_policies.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch_default_policies.c).
|
||||
Function pointers are assigned at startup in
|
||||
[`main.c`](../../openair2/LAYER2/NR_MAC_gNB/main.c).
|
||||
|
||||
## Scheduler Pipeline
|
||||
|
||||
Both DL and UL follow the same 7-stage pipeline, plus a DL-only 8th stage.
|
||||
|
||||
```
|
||||
DL UL
|
||||
┌────────────┐ ┌────────────┐
|
||||
│ 1.Collect │ │ 1.Collect │ ◄── nr_ulsch_preprocessor
|
||||
│ Candidates │ │ Candidates │ (iterates over
|
||||
└─────┬──────┘ └─────┬──────┘ reachable UL slots)
|
||||
│ │
|
||||
┌─────┴──────┐ ┌─────┴──────┐
|
||||
│ 2. RI/PMI │ │ 2. RI/TPMI│ ◄─┐
|
||||
│ Selection │ │ Selection │ │
|
||||
└─────┬──────┘ └─────┬──────┘ │
|
||||
│ │ │
|
||||
┌─────┴──────┐ ┌─────┴──────┐ │
|
||||
│ 3. Beam │ │ 3. Beam │ │
|
||||
│ Selection │ │ Selection │ │
|
||||
└─────┬──────┘ └─────┬──────┘ │
|
||||
│ │ │ nr_ul_schedule
|
||||
┌─────┴──────┐ ┌─────┴──────┐ │ (per UL slot)
|
||||
│ 4. TDA │ │ 4. TDA │ │
|
||||
│ Selection │ │ Selection │ │
|
||||
└─────┬──────┘ └─────┬──────┘ │
|
||||
│ │ │
|
||||
┌─────┴──────┐ ┌─────┴──────┐ │
|
||||
│ 5. MCS │ │ 5. MCS │ │
|
||||
│ Selection │ │ Selection │ │
|
||||
└─────┬──────┘ └─────┬──────┘ │
|
||||
│ │ │
|
||||
┌─────┴──────┐ ┌─────┴──────┐ │
|
||||
│ 6. RB │ │ 6. RB │ │
|
||||
│ Allocation │ │ Allocation │ │
|
||||
│ (per beam) │ │ (per beam) │ │
|
||||
└─────┬──────┘ └─────┬──────┘ │
|
||||
│ │ │
|
||||
┌─────┴──────┐ ┌─────┴──────┐ │
|
||||
│ 7.Dispatch│ │ 7.Dispatch│ ◄─┘
|
||||
│ (fixed) │ │ (fixed) │
|
||||
└─────┬──────┘ └────────────┘
|
||||
│
|
||||
┌─────┴──────┐
|
||||
│ 8. LCID │ (DL only)
|
||||
│ Allocation │
|
||||
└────────────┘
|
||||
```
|
||||
|
||||
### UL preprocessor split
|
||||
|
||||
The UL pipeline is split across two functions. The preprocessor
|
||||
(`nr_ulsch_preprocessor`) runs a loop over **multiple candidate UL slots**: for each DL
|
||||
slot there may be several reachable UL slots (depending on K2), and the scheduler must
|
||||
pick one. The loop iterates until the DCI budget is exhausted or no TDA can reach
|
||||
further UL slots.
|
||||
|
||||
**Only step 1 (candidate collection) lives in the preprocessor loop.** Candidates depend
|
||||
on `sched_frame`/`sched_slot` (e.g. inactivity checks), so they are rebuilt each
|
||||
iteration. The preprocessor also runs a lightweight TDA reachability gate
|
||||
(`get_num_ul_tda == 0 → break`) to short-circuit the loop when no TDA can reach the
|
||||
target slot.
|
||||
|
||||
**Steps 2–7 live in `nr_ul_schedule`**, called once per UL slot with the collected
|
||||
candidates. `k2` is passed as a parameter for TDA selection. This mirrors the DL
|
||||
structure where all stages run in a single function.
|
||||
|
||||
Beam selection (step 3) runs before TDA selection (step 4) so that TDA selection can
|
||||
use the allocated beam to check the correct VRB map and pick the best TDA per beam.
|
||||
|
||||
The preprocessor itself is a pluggable function pointer (`pre_processor_ul`), so a
|
||||
custom implementation can replace the entire outer strategy — including how many UL
|
||||
slots to target and what to do when the DCI budget is limited.
|
||||
|
||||
### Candidate struct
|
||||
|
||||
Each candidate is an `nr_{dl,ul}_candidate_t` struct that flows through the pipeline,
|
||||
accumulating decisions. Its fields are split into three sections:
|
||||
|
||||
1. **Identity / scheduling state** — set by collect, read-only afterwards: `UE` pointer,
|
||||
`rnti`, HARQ state, pending bytes, BLER estimate, current MCS, BWP geometry, QoS.
|
||||
2. **CSI observations** — set by collect: `cqi` (DL), `beam_rsrp[]`, `beam_sinr[]` (per-SSB).
|
||||
3. **gNB decisions** — written by the stage indicated below. Some live in the
|
||||
embedded `sched_pdsch` / `sched_pusch` sub-struct, others are `alloc_`-prefixed
|
||||
fields on the candidate itself:
|
||||
- `sched_p{d,u}sch.nrOfLayers`, `.pm_index` (DL) / `.tpmi` (UL) — set by ri_pmi/tpmi_select
|
||||
- `sched_p{d,u}sch.time_domain_allocation`, `.tda_info`, `alloc_slbitmap` — set by tda_select
|
||||
- `alloc_beam_idx`, `alloc_dci_beam_idx` (UL), etc. — set by beam_select
|
||||
- `sched_p{d,u}sch.mcs` — set by mcs_select
|
||||
- `sched_p{d,u}sch.rbStart`, `.rbSize` — set by rb_alloc
|
||||
- `alloc_cce_index`, `alloc_aggregation_level`, `alloc_sched_pdcch` — set by commit_alloc
|
||||
|
||||
The policy (`rb_alloc`) writes to `sched_p{d,u}sch.rbStart/rbSize/mcs` via the
|
||||
`COMMIT_ALLOC` / `COMMIT_UL_ALLOC` macro, which also runs CCE validation and sets
|
||||
`cand->scheduled = true`. Only candidates with that flag set are dispatched.
|
||||
|
||||
---
|
||||
|
||||
### Stage 1. Candidate Collection (fixed)
|
||||
|
||||
**Functions:** `collect_dl_candidates()`, `collect_ul_candidates()`
|
||||
|
||||
Iterates over connected UEs and builds an array of `nr_{dl,ul}_candidate_t` structs.
|
||||
Populates the identity/state and CSI sections. Not a function pointer — fixed scaffolding
|
||||
that feeds the pipeline.
|
||||
|
||||
### Stage 2. RI / PMI Selection
|
||||
|
||||
**Function pointers:** `mac->dl_ri_pmi_select` (`nr_dl_ri_pmi_select_fn`),
|
||||
`mac->ul_ri_tpmi_select` (`nr_ul_ri_tpmi_select_fn`)
|
||||
|
||||
Sets rank and precoder index per candidate. In DL, rank and PMI come from the UE's CSI
|
||||
report (RI + PMI). In UL, the gNB has full authority and reads rank and TPMI from SRS
|
||||
feedback.
|
||||
|
||||
**DL outputs:** `cand->sched_pdsch.nrOfLayers`, `cand->sched_pdsch.pm_index`.
|
||||
**UL outputs:** `cand->sched_pusch.nrOfLayers`, `cand->sched_pusch.tpmi`.
|
||||
|
||||
### Stage 3. Beam Selection
|
||||
|
||||
**Function pointers:** `mac->dl_beam_select` (`nr_dl_beam_select_fn`),
|
||||
`mac->ul_beam_select` (`nr_ul_beam_select_fn`)
|
||||
|
||||
Assigns a beam structure index to each candidate. For UL, two beams are needed — one
|
||||
for the DCI slot, one for the PUSCH slot — since they may fall in different beam periods.
|
||||
Candidates that fail beam allocation (no beam available) are marked with `skipped=true`.
|
||||
|
||||
Placed before TDA selection so that TDA selection can use the allocated beam to check
|
||||
the correct VRB map and pick the best TDA per beam.
|
||||
|
||||
**Outputs:** `cand->alloc_beam_idx` (PUSCH/PDSCH beam), `cand->alloc_dci_beam_idx` (UL DCI beam).
|
||||
|
||||
### Stage 4. TDA Selection
|
||||
|
||||
**Function pointers:** `mac->dl_tda_select` (`nr_dl_tda_select_fn`),
|
||||
`mac->ul_tda_select` (`nr_ul_tda_select_fn`)
|
||||
|
||||
Picks the Time Domain Allocation for each candidate. For UL retransmissions, also
|
||||
validates feasibility: if the TDA differs from the original transmission (e.g. because
|
||||
targeting a different UL slot), the TBS must be preservable with the new symbol/DMRS
|
||||
layout. Infeasible retx candidates are marked with `skipped=true`.
|
||||
|
||||
**Outputs:** `cand->sched_p{d,u}sch.time_domain_allocation`, `.tda_info`, `cand->alloc_slbitmap`. UL retx
|
||||
candidates get `cand->retx_rbSize` set.
|
||||
**Returns:** number of surviving candidates.
|
||||
|
||||
### Stage 5. MCS Selection
|
||||
|
||||
**Function pointers:** `mac->dl_mcs_select` (`nr_dl_mcs_select_fn`),
|
||||
`mac->ul_mcs_select` (`nr_ul_mcs_select_fn`)
|
||||
|
||||
Runs for **all surviving candidates** — including those that may ultimately not be
|
||||
scheduled due to CCE failure. Sets `sched_p{d,u}sch.mcs` from BLER stats or SINR, and persists
|
||||
the decision to `{ul,dl}_bler_stats.mcs` so continuity is maintained across slots even
|
||||
for unscheduled UEs.
|
||||
|
||||
Placed after beam selection so custom implementations can use `alloc_beam_idx` and
|
||||
`beam_rsrp/sinr` for beam-aware MCS adaptation.
|
||||
|
||||
### Stage 6. RB Allocation (per beam)
|
||||
|
||||
**Function pointers:** `mac->dl_rb_alloc` (`nr_dl_rb_alloc_fn`),
|
||||
`mac->ul_rb_alloc` (`nr_ul_rb_alloc_fn`)
|
||||
|
||||
The core resource allocation decision and the most likely stage to be replaced. Called
|
||||
once per beam with candidates filtered to that beam. Decides which UEs to schedule and
|
||||
how many PRBs each gets. MCS is already set on `sched_p{d,u}sch.mcs` by the previous
|
||||
stage; the policy may refine it (e.g. downward PHR adjustment).
|
||||
|
||||
Each allocation must go through the `COMMIT_ALLOC` / `COMMIT_UL_ALLOC` macro, which
|
||||
writes `sched_p{d,u}sch.rbStart/rbSize/mcs` onto the candidate, runs CCE validation
|
||||
(and PUCCH validation on DL), and sets `cand->scheduled = true`. UEs that fail CCE are
|
||||
skipped transparently.
|
||||
|
||||
**Outputs:** `cand->scheduled` flag on accepted candidates.
|
||||
**Returns:** number of scheduled UEs.
|
||||
|
||||
### Stage 7. Dispatch (fixed)
|
||||
|
||||
Not a function pointer. Iterates over candidates with `scheduled == true`, reads the `alloc_*` fields
|
||||
from each candidate, applies CCE results to `sched_ctrl`, marks the VRB map, and calls
|
||||
`apply_{dl,ul}_{new_transmission,retransmission}` to build the final
|
||||
`NR_sched_{pusch,pdsch}_t` and trigger FAPI message preparation.
|
||||
|
||||
### Stage 8. Per-LCID Byte Allocation (DL only)
|
||||
|
||||
**Function pointer:** `mac->dl_lcid_alloc` (`nr_dl_lcid_alloc_fn`)
|
||||
|
||||
Called inside `generate_dl_mac_pdu` for initial DL transmissions. Decides how many bytes
|
||||
each logical channel gets within the available TBS. The candidate flows from the dispatch
|
||||
stage into `post_process_dlsch` → `generate_dl_mac_pdu`, giving this stage access to the
|
||||
full candidate context (per-LCID pending bytes, QoS, priority).
|
||||
|
||||
The function pointer receives the MAC instance, the candidate, the TBS available after
|
||||
MAC CEs, and writes an output array `lcid_alloc[NR_MAX_NUM_LCID]` specifying the byte
|
||||
budget per LCID. The MAC PDU builder then executes the plan: it iterates over LCs in
|
||||
config order, requests up to `lcid_alloc[lcid]` bytes from RLC for each, and builds the
|
||||
MAC subheaders. RLC may return fewer bytes than budgeted; the builder handles this
|
||||
transparently.
|
||||
|
||||
**Inputs:** `candidate->pending_bytes_per_lcid[]`, `candidate->fiveQI`, `candidate->priority`,
|
||||
`candidate->nssai`, `tbs_available`.
|
||||
**Outputs:** `lcid_alloc[NR_MAX_NUM_LCID]` — byte budget per LCID.
|
||||
|
||||
Not invoked for retransmissions (which reuse the stored transport block) or for phy-test
|
||||
mode (which fills random data). In these cases the candidate pointer is NULL.
|
||||
|
||||
---
|
||||
|
||||
## Default Implementations
|
||||
|
||||
All function pointers are assigned in
|
||||
[`main.c`](../../openair2/LAYER2/NR_MAC_gNB/main.c) at startup.
|
||||
The `COMMIT_ALLOC` / `COMMIT_UL_ALLOC` macros are defined in
|
||||
[`mac_proto.h`](../../openair2/LAYER2/NR_MAC_gNB/mac_proto.h).
|
||||
|
||||
### `nr_dl_ri_pmi_select_default`, `nr_ul_ri_tpmi_select_default`
|
||||
|
||||
DL reads rank and PMI from the UE's CSI report (`csi_ri`, `csi_pm_index` on
|
||||
`sched_ctrl`). Retransmissions reuse rank/PMI from the original HARQ process.
|
||||
UL reads rank and TPMI from SRS feedback (`srs_feedback` on `sched_ctrl`).
|
||||
Both write `cand->sched_p{d,u}sch.nrOfLayers` and the respective precoder index.
|
||||
|
||||
### `nr_dl_tda_select_default`, `nr_ul_tda_select_default`
|
||||
|
||||
Assigns the same TDA to all candidates in a slot (picks the first valid one for the
|
||||
scheduled frame/slot). For UL retransmissions, calls `check_ul_retx_feasibility` to
|
||||
verify TBS preservation under the new symbol/DMRS layout.
|
||||
|
||||
### `nr_dl_beam_select_default`, `nr_ul_beam_select_default`
|
||||
|
||||
Uses OAI's beam management framework (`NR_beam_info_t`). For UL, allocates both a DCI
|
||||
beam and a PUSCH beam. Candidates that fail beam allocation are compacted out.
|
||||
|
||||
### `nr_dl_mcs_select_default`, `nr_ul_mcs_select_default`
|
||||
|
||||
BLER-based (when `harq_round_max > 1`): calls `nr_adapt_mcs_from_bler` for candidates
|
||||
with a fresh BLER estimate; holds current MCS otherwise. SINR-based (when
|
||||
`harq_round_max == 1`): maps measured PUSCH SINR to MCS via lookup table. In both
|
||||
cases, persists to `{dl,ul}_bler_stats.mcs`.
|
||||
|
||||
### `nr_dl_proportional_fair`, `nr_ul_proportional_fair`
|
||||
|
||||
Proportional-fair scheduler with three phases:
|
||||
|
||||
- **Phase 1 — Retransmissions:** find the largest free block >= `retx_rbSize`.
|
||||
- **Phase 2 — Minimal-grant UEs:** in DL, targets UEs with no pending RLC data
|
||||
(`pending_bytes == 0`) that still need a TA command or beam-switch MAC CE. In UL,
|
||||
targets inactive UEs (`sched_inactive`) that need scheduling for TA/SR. Both get a
|
||||
minimum grant (`min_rb`).
|
||||
- **Phase 3 — New data:** sort by PF weight (`pending_bytes / avg_throughput`), allocate
|
||||
the largest free block to each UE in order.
|
||||
|
||||
The UL policy also checks PHR (Power Headroom) and adjusts MCS/RBs accordingly.
|
||||
All phases use `COMMIT_ALLOC` / `COMMIT_UL_ALLOC` to validate CCE (and PUCCH on DL).
|
||||
|
||||
### `nr_dl_lcid_alloc_default`
|
||||
|
||||
Greedy fill: sets each LCID's budget to its full `pending_bytes_per_lcid` value. The
|
||||
execution loop in `generate_dl_mac_pdu` then fills LCIDs in LC config order until the
|
||||
TBS is exhausted, reproducing the original first-come-first-served behavior. A custom
|
||||
implementation could use the candidate's QoS fields (`fiveQI`, `priority`, `nssai`)
|
||||
to implement weighted fair queuing, strict priority with rate limiting, or slice-aware
|
||||
allocation across LCIDs.
|
||||
|
||||
### `nr_dlsch_preprocessor`, `nr_ulsch_preprocessor`
|
||||
|
||||
Top-level orchestrators that run the full pipeline above. In phy-test mode, replaced by
|
||||
`nr_preprocessor_phytest` / `nr_ul_preprocessor_phytest` which bypass the staged pipeline.
|
||||
|
||||
---
|
||||
|
||||
## Function Pointer Reference
|
||||
|
||||
### DL
|
||||
|
||||
| Field on `gNB_MAC_INST` | Typedef | Default | Stage |
|
||||
|--------------------------|---------------------------|-------------------------------|-------|
|
||||
| `pre_processor_dl` | `nr_pp_impl_dl` | `nr_dlsch_preprocessor` | Orchestrator |
|
||||
| `dl_ri_pmi_select` | `nr_dl_ri_pmi_select_fn` | `nr_dl_ri_pmi_select_default` | 2. RI/PMI |
|
||||
| `dl_beam_select` | `nr_dl_beam_select_fn` | `nr_dl_beam_select_default` | 3. Beam |
|
||||
| `dl_tda_select` | `nr_dl_tda_select_fn` | `nr_dl_tda_select_default` | 4. TDA |
|
||||
| `dl_mcs_select` | `nr_dl_mcs_select_fn` | `nr_dl_mcs_select_default` | 5. MCS |
|
||||
| `dl_rb_alloc` | `nr_dl_rb_alloc_fn` | `nr_dl_proportional_fair` | 6. RB alloc |
|
||||
| `dl_lcid_alloc` | `nr_dl_lcid_alloc_fn` | `nr_dl_lcid_alloc_default` | 8. LCID alloc |
|
||||
|
||||
### UL
|
||||
|
||||
| Field on `gNB_MAC_INST` | Typedef | Default | Stage |
|
||||
|--------------------------|---------------------------|--------------------------------|-------|
|
||||
| `pre_processor_ul` | `nr_pp_impl_ul` | `nr_ulsch_preprocessor` | Orchestrator |
|
||||
| `ul_ri_tpmi_select` | `nr_ul_ri_tpmi_select_fn` | `nr_ul_ri_tpmi_select_default` | 2. RI/TPMI |
|
||||
| `ul_beam_select` | `nr_ul_beam_select_fn` | `nr_ul_beam_select_default` | 3. Beam |
|
||||
| `ul_tda_select` | `nr_ul_tda_select_fn` | `nr_ul_tda_select_default` | 4. TDA |
|
||||
| `ul_mcs_select` | `nr_ul_mcs_select_fn` | `nr_ul_mcs_select_default` | 5. MCS |
|
||||
| `ul_rb_alloc` | `nr_ul_rb_alloc_fn` | `nr_ul_proportional_fair` | 6. RB alloc |
|
||||
|
||||
---
|
||||
|
||||
## Key Data Structures
|
||||
|
||||
All defined in `nr_mac_gNB.h`.
|
||||
|
||||
### Candidate (`nr_{dl,ul}_candidate_t`)
|
||||
|
||||
Flows through the pipeline accumulating decisions. Three sections:
|
||||
|
||||
**Identity / scheduling state** (set by collect, read-only after):
|
||||
`UE` pointer, `rnti`, `is_retx`, `retx_harq_pid`, `retx_rbSize`, `pending_bytes`,
|
||||
`pending_bytes_per_lcid[NR_MAX_NUM_LCID]`, `avg_throughput`, `bler`, `current_mcs`,
|
||||
`max_mcs`, `bwp_start`, `bwp_size`, `fiveQI`, `priority`, `nssai`.
|
||||
|
||||
**CSI observations** (set by collect, read-only after):
|
||||
`cqi` (DL CQI), `beam_rsrp[]`, `beam_sinr[]` (per-SSB L1-RSRP/SINR, `INT16_MIN` = no data).
|
||||
|
||||
**gNB decisions** (written by the named stage — some in `sched_p{d,u}sch`, some `alloc_*`):
|
||||
`sched_p{d,u}sch.nrOfLayers`, `.pm_index`/`.tpmi`, `.time_domain_allocation`, `.tda_info`,
|
||||
`.mcs`, `.rbStart`, `.rbSize`;
|
||||
`alloc_slbitmap`, `alloc_beam_idx`, `alloc_dci_beam_idx` (UL),
|
||||
`alloc_cce_index`, `alloc_aggregation_level`, `alloc_sched_pdcch`.
|
||||
|
||||
### Sched Params (`nr_{dl,ul}_sched_params_t`)
|
||||
|
||||
Per-beam context passed to `rb_alloc`. Contains the MAC instance, slot info, VRB map,
|
||||
available RBs, BLER thresholds, TDA info, and serving cell config.
|
||||
|
||||
---
|
||||
|
||||
## Writing a Custom Scheduler
|
||||
|
||||
### Replacing the RB allocation policy
|
||||
|
||||
Write a function matching the typedef:
|
||||
|
||||
```c
|
||||
int my_ul_rb_alloc(const nr_ul_sched_params_t *params,
|
||||
nr_ul_candidate_t *candidates,
|
||||
int n_candidates)
|
||||
{
|
||||
int n_scheduled = 0;
|
||||
for (int i = 0; i < n_candidates; i++) {
|
||||
nr_ul_candidate_t *cand = &candidates[i];
|
||||
// ... decide rbStart, rbSize, mcs ...
|
||||
// COMMIT_UL_ALLOC writes sched_pusch fields, validates CCE, sets cand->scheduled:
|
||||
COMMIT_UL_ALLOC(params, cand, rbStart, rbSize, mcs, n_scheduled);
|
||||
}
|
||||
return n_scheduled;
|
||||
}
|
||||
```
|
||||
|
||||
Register it in `openair2/LAYER2/NR_MAC_gNB/main.c`:
|
||||
|
||||
```c
|
||||
RC.nrmac[i]->ul_rb_alloc = my_ul_rb_alloc;
|
||||
```
|
||||
|
||||
### Replacing the per-LCID allocation policy (DL)
|
||||
|
||||
Write a function matching the typedef:
|
||||
|
||||
```c
|
||||
void my_lcid_alloc(const gNB_MAC_INST *mac,
|
||||
const nr_dl_candidate_t *candidate,
|
||||
int tbs_available,
|
||||
int lcid_alloc[NR_MAX_NUM_LCID])
|
||||
{
|
||||
memset(lcid_alloc, 0, NR_MAX_NUM_LCID * sizeof(int));
|
||||
// ... use candidate->pending_bytes_per_lcid[], candidate->fiveQI,
|
||||
// candidate->priority, tbs_available to decide budgets ...
|
||||
for (int lcid = 0; lcid < NR_MAX_NUM_LCID; lcid++)
|
||||
lcid_alloc[lcid] = my_budget_for(lcid);
|
||||
}
|
||||
```
|
||||
|
||||
Register it:
|
||||
|
||||
```c
|
||||
RC.nrmac[i]->dl_lcid_alloc = my_lcid_alloc;
|
||||
```
|
||||
|
||||
### Replacing other stages
|
||||
|
||||
Any function pointer can be replaced independently:
|
||||
|
||||
```c
|
||||
RC.nrmac[i]->ul_ri_tpmi_select = my_ri_tpmi_select;
|
||||
RC.nrmac[i]->ul_mcs_select = my_mcs_select;
|
||||
RC.nrmac[i]->ul_beam_select = my_beam_select;
|
||||
```
|
||||
|
||||
### Recommendations
|
||||
|
||||
- **Always use `COMMIT_ALLOC` / `COMMIT_UL_ALLOC`** to accept an allocation. It writes
|
||||
`sched_p{d,u}sch` fields onto the candidate, validates CCE (and PUCCH on DL), and sets
|
||||
`cand->scheduled`.
|
||||
- **Do not mark the VRB map** — `commit_alloc` / `commit_ul_alloc` handles that inside the macro.
|
||||
- `sched_p{d,u}sch.mcs` is already set by `mcs_select` when your policy runs. You may
|
||||
refine it downward (e.g. PHR); pass the final value to `COMMIT_ALLOC` / `COMMIT_UL_ALLOC`.
|
||||
- Candidates are non-const: the policy is allowed to write `sched_p{d,u}sch` and `alloc_*`
|
||||
fields. Do not modify identity/state or CSI fields.
|
||||
@@ -169,6 +169,7 @@ generate DL shared channel (user data)
|
||||
|
||||
#### nr_feptx_prec()
|
||||
tx precoding
|
||||
<<<<<<< HEAD:doc/SW_archi.md
|
||||
|
||||
#### nr_feptx0
|
||||
do the inverse DFT
|
||||
|
||||
@@ -67,7 +67,7 @@ RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.pr
|
||||
# Copying only the needed files to create ran-base
|
||||
WORKDIR /oai-ran/cmake_targets/tools
|
||||
COPY cmake_targets/tools/build_helper \
|
||||
cmake_targets/tools/uhd-4.5plus-tdd-patch.diff \
|
||||
cmake_targets/tools/uhd-4.x-tdd-patch.diff \
|
||||
./
|
||||
|
||||
WORKDIR /oai-ran/cmake_targets
|
||||
|
||||
@@ -55,7 +55,7 @@ RUN wget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linu
|
||||
# Copying only the needed files to create ran-base
|
||||
WORKDIR /oai-ran/cmake_targets/tools
|
||||
COPY cmake_targets/tools/build_helper \
|
||||
cmake_targets/tools/uhd-4.5plus-tdd-patch.diff \
|
||||
cmake_targets/tools/uhd-4.x-tdd-patch.diff \
|
||||
./
|
||||
|
||||
WORKDIR /oai-ran/cmake_targets
|
||||
|
||||
@@ -60,7 +60,7 @@ RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.pr
|
||||
# Copying only the needed files to create ran-base
|
||||
WORKDIR /oai-ran/cmake_targets/tools
|
||||
COPY cmake_targets/tools/build_helper \
|
||||
cmake_targets/tools/uhd-4.5plus-tdd-patch.diff \
|
||||
cmake_targets/tools/uhd-4.x-tdd-patch.diff \
|
||||
./
|
||||
|
||||
WORKDIR /oai-ran/cmake_targets
|
||||
|
||||
@@ -63,7 +63,7 @@ RUN chmod +x /tini
|
||||
# Copying only the needed files to create ran-base
|
||||
WORKDIR /oai-ran/cmake_targets/tools
|
||||
COPY cmake_targets/tools/build_helper \
|
||||
cmake_targets/tools/uhd-4.5plus-tdd-patch.diff \
|
||||
cmake_targets/tools/uhd-4.x-tdd-patch.diff \
|
||||
./
|
||||
|
||||
WORKDIR /oai-ran/cmake_targets
|
||||
|
||||
@@ -558,8 +558,8 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
|
||||
if (phy_data->dlsch[0].active
|
||||
&& (phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_ || phy_data->dlsch[0].rnti_type == TYPE_RA_RNTI_)) {
|
||||
// indicate to tx thread to wait for DLSCH decoding
|
||||
if (phy_data->dlsch_config.k1_feedback) { // if feedback is 0 there is no HARQ associated with this DLSCH
|
||||
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch_config.k1_feedback) % fp->slots_per_frame;
|
||||
if (phy_data->dlsch[0].dlsch_config.k1_feedback) { // if feedback is 0 there is no HARQ associated with this DLSCH
|
||||
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % fp->slots_per_frame;
|
||||
tx_wait_for_dlsch[ack_nack_slot]++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ int main(int argc, char **argv)
|
||||
|
||||
init_opt();
|
||||
|
||||
int ret_loader = load_nrLDPC_coding_interface(NULL, &nrLDPC_coding_interface, 32);
|
||||
int ret_loader = load_nrLDPC_coding_interface(NULL, &nrLDPC_coding_interface);
|
||||
AssertFatal(ret_loader == 0, "error loading LDPC library\n");
|
||||
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
|
||||
@@ -118,7 +118,6 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8_t harq_pid;
|
||||
uint8_t cw_idx;
|
||||
uint8_t ack_nack;
|
||||
uint32_t pdu_length;
|
||||
uint8_t* pdu;
|
||||
@@ -467,17 +466,6 @@ typedef struct {
|
||||
|
||||
typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t mcs;
|
||||
bool new_data_indicator;
|
||||
uint8_t rv;
|
||||
uint16_t targetCodeRate;
|
||||
uint8_t qamModOrder;
|
||||
uint32_t TBS;
|
||||
uint8_t ldpcBaseGraph;
|
||||
uint8_t Nl;
|
||||
} fapi_nr_dl_cw_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t BWPSize;
|
||||
uint16_t BWPStart;
|
||||
@@ -494,8 +482,15 @@ typedef struct {
|
||||
uint8_t prb_bundling_size_ind;
|
||||
uint8_t rate_matching_ind;
|
||||
uint8_t zp_csi_rs_trigger;
|
||||
uint8_t n_codewords;
|
||||
fapi_nr_dl_cw_info_t cw_info[2];
|
||||
uint8_t mcs;
|
||||
bool new_data_indicator;
|
||||
uint8_t rv;
|
||||
uint16_t targetCodeRate;
|
||||
uint8_t qamModOrder;
|
||||
uint32_t TBS;
|
||||
uint8_t tb2_mcs;
|
||||
bool tb2_new_data_indicator;
|
||||
uint8_t tb2_rv;
|
||||
uint8_t harq_process_nbr;
|
||||
vrb_to_prb_mapping_t vrb_to_prb_mapping;
|
||||
uint8_t dai;
|
||||
@@ -528,6 +523,7 @@ typedef struct {
|
||||
uint16_t dlDataScramblingId;
|
||||
uint16_t pduBitmap;
|
||||
uint32_t k1_feedback;
|
||||
uint8_t ldpcBaseGraph;
|
||||
uint8_t numCsiRsForRateMatching;
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t csiRsForRateMatching[NFAPI_MAX_NUM_CSI_RATEMATCH];
|
||||
} fapi_nr_dl_config_dlsch_pdu_rel15_t;
|
||||
|
||||
@@ -334,7 +334,7 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
|
||||
n_iter = ldpc_toCompare.LDPCdecoder(&decParams[j],
|
||||
(int8_t *)channel_output_fixed[j],
|
||||
estimated_output[j],
|
||||
(int8_t *)estimated_output[j],
|
||||
&decoder_profiler,
|
||||
&dec_abort);
|
||||
stop_meas(&ret.time_decoder);
|
||||
|
||||
@@ -458,9 +458,8 @@ static int init_op_data_objs_dec(struct rte_bbdev_op_data *bufs,
|
||||
bool large_input = false;
|
||||
int j = 0;
|
||||
for (int h = 0; h < nrLDPC_slot_decoding_parameters->nb_TBs; ++h) {
|
||||
nrLDPC_TB_decoding_parameters_t *p = &nrLDPC_slot_decoding_parameters->TBs[h];
|
||||
for (int i = 0; i < p->C; ++i) {
|
||||
uint32_t data_len = i < p->first_rE2 ? p->E : p->E2;
|
||||
for (int i = 0; i < nrLDPC_slot_decoding_parameters->TBs[h].C; ++i) {
|
||||
uint32_t data_len = nrLDPC_slot_decoding_parameters->TBs[h].segments[i].E;
|
||||
char *data;
|
||||
struct rte_mbuf *m_head = rte_pktmbuf_alloc(mbuf_pool);
|
||||
AssertFatal(m_head != NULL,
|
||||
@@ -603,19 +602,20 @@ static void set_ldpc_dec_op(struct rte_bbdev_dec_op **ops,
|
||||
bool special_case_tb_mode = !active_dev.is_t2 && (nrLDPC_slot_decoding_parameters->nb_TBs == 1)
|
||||
&& (nb_segments_decoding(nrLDPC_slot_decoding_parameters) == 1);
|
||||
for (int h = 0; h < nrLDPC_slot_decoding_parameters->nb_TBs; ++h) {
|
||||
nrLDPC_TB_decoding_parameters_t *p = &nrLDPC_slot_decoding_parameters->TBs[h];
|
||||
for (int i = 0; i < p->C; ++i) {
|
||||
ops[j]->ldpc_dec.basegraph = p->BG;
|
||||
ops[j]->ldpc_dec.z_c = p->Z;
|
||||
ops[j]->ldpc_dec.q_m = p->Qm;
|
||||
ops[j]->ldpc_dec.n_filler = p->F;
|
||||
ops[j]->ldpc_dec.n_cb = (p->BG == 1) ? (66 * p->Z) : (50 * p->Z);
|
||||
ops[j]->ldpc_dec.iter_max = p->max_ldpc_iterations;
|
||||
ops[j]->ldpc_dec.rv_index = p->rv_index;
|
||||
for (int i = 0; i < nrLDPC_slot_decoding_parameters->TBs[h].C; ++i) {
|
||||
ops[j]->ldpc_dec.basegraph = nrLDPC_slot_decoding_parameters->TBs[h].BG;
|
||||
ops[j]->ldpc_dec.z_c = nrLDPC_slot_decoding_parameters->TBs[h].Z;
|
||||
ops[j]->ldpc_dec.q_m = nrLDPC_slot_decoding_parameters->TBs[h].Qm;
|
||||
ops[j]->ldpc_dec.n_filler = nrLDPC_slot_decoding_parameters->TBs[h].F;
|
||||
ops[j]->ldpc_dec.n_cb = (nrLDPC_slot_decoding_parameters->TBs[h].BG == 1) ? (66 * nrLDPC_slot_decoding_parameters->TBs[h].Z)
|
||||
: (50 * nrLDPC_slot_decoding_parameters->TBs[h].Z);
|
||||
ops[j]->ldpc_dec.iter_max = nrLDPC_slot_decoding_parameters->TBs[h].max_ldpc_iterations;
|
||||
ops[j]->ldpc_dec.rv_index = nrLDPC_slot_decoding_parameters->TBs[h].rv_index;
|
||||
ops[j]->ldpc_dec.op_flags = RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE | RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE;
|
||||
if (p->d_to_be_cleared) {
|
||||
if (*nrLDPC_slot_decoding_parameters->TBs[h].segments[i].d_to_be_cleared) {
|
||||
*nrLDPC_slot_decoding_parameters->TBs[h].segments[i].d_to_be_cleared = false;
|
||||
if (active_dev.is_t2)
|
||||
*p->processedSegments = 0;
|
||||
*nrLDPC_slot_decoding_parameters->TBs[h].processedSegments = 0;
|
||||
} else {
|
||||
ops[j]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE;
|
||||
if (active_dev.support_internal_harq_memory) {
|
||||
@@ -625,12 +625,12 @@ static void set_ldpc_dec_op(struct rte_bbdev_dec_op **ops,
|
||||
}
|
||||
|
||||
if (!active_dev.is_t2)
|
||||
*p->processedSegments = 0;
|
||||
*nrLDPC_slot_decoding_parameters->TBs[h].processedSegments = 0;
|
||||
|
||||
if (!special_case_tb_mode) {
|
||||
ops[j]->ldpc_dec.code_block_mode = 1;
|
||||
ops[j]->ldpc_dec.cb_params.e = i < p->first_rE2 ? p->E : p->E2;
|
||||
if (p->C > 1) {
|
||||
ops[j]->ldpc_dec.cb_params.e = nrLDPC_slot_decoding_parameters->TBs[h].segments[i].E;
|
||||
if (nrLDPC_slot_decoding_parameters->TBs[h].C > 1) {
|
||||
ops[j]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP;
|
||||
ops[j]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK;
|
||||
}
|
||||
@@ -646,12 +646,12 @@ static void set_ldpc_dec_op(struct rte_bbdev_dec_op **ops,
|
||||
ops[j]->ldpc_dec.tb_params.c = 1;
|
||||
ops[j]->ldpc_dec.tb_params.r = 0;
|
||||
ops[j]->ldpc_dec.tb_params.cab = 1;
|
||||
ops[j]->ldpc_dec.tb_params.ea = i < p->first_rE2 ? p->E : p->E2;
|
||||
ops[j]->ldpc_dec.tb_params.eb = i < p->first_rE2 ? p->E : p->E2;
|
||||
ops[j]->ldpc_dec.tb_params.ea = nrLDPC_slot_decoding_parameters->TBs[h].segments[i].E;
|
||||
ops[j]->ldpc_dec.tb_params.eb = nrLDPC_slot_decoding_parameters->TBs[h].segments[i].E;
|
||||
}
|
||||
// Calculate offset in the HARQ combined buffers
|
||||
// Unique segment offset
|
||||
uint32_t segment_offset = (p->harq_unique_pid * NR_LDPC_MAX_NUM_CB) + i;
|
||||
uint32_t segment_offset = (nrLDPC_slot_decoding_parameters->TBs[h].harq_unique_pid * NR_LDPC_MAX_NUM_CB) + i;
|
||||
// Prune to avoid shooting above maximum id
|
||||
uint32_t pruned_segment_offset = segment_offset % active_dev.num_harq_codeblock;
|
||||
// Segment offset to byte offset
|
||||
@@ -673,7 +673,6 @@ static void set_ldpc_dec_op(struct rte_bbdev_dec_op **ops,
|
||||
ops[j]->ldpc_dec.input = inputs[j];
|
||||
++j;
|
||||
}
|
||||
p->d_to_be_cleared = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,16 +729,14 @@ static int retrieve_ldpc_dec_op(struct rte_bbdev_dec_op **ops, nrLDPC_slot_decod
|
||||
{
|
||||
int j = 0;
|
||||
for (int h = 0; h < nrLDPC_slot_decoding_parameters->nb_TBs; ++h) {
|
||||
nrLDPC_TB_decoding_parameters_t *p = &nrLDPC_slot_decoding_parameters->TBs[h];
|
||||
size_t data_off = 0;
|
||||
for (int i = 0; i < p->C; ++i) {
|
||||
for (int i = 0; i < nrLDPC_slot_decoding_parameters->TBs[h].C; ++i) {
|
||||
struct rte_bbdev_op_data *hard_output = &ops[j]->ldpc_dec.hard_output;
|
||||
struct rte_mbuf *m = hard_output->data;
|
||||
uint16_t data_len = rte_pktmbuf_data_len(m) - hard_output->offset;
|
||||
uint8_t *data = rte_pktmbuf_mtod_offset(m, uint8_t *, hard_output->offset);
|
||||
memcpy(p->c + data_off, data, data_len);
|
||||
memcpy(nrLDPC_slot_decoding_parameters->TBs[h].segments[i].c, data, data_len);
|
||||
|
||||
uint32_t segment_offset = (p->harq_unique_pid * NR_LDPC_MAX_NUM_CB) + i;
|
||||
uint32_t segment_offset = (nrLDPC_slot_decoding_parameters->TBs[h].harq_unique_pid * NR_LDPC_MAX_NUM_CB) + i;
|
||||
uint32_t pruned_segment_offset = segment_offset % active_dev.num_harq_codeblock;
|
||||
struct rte_bbdev_op_data *harq_output = &ops[j]->ldpc_dec.harq_combined_output;
|
||||
if (!active_dev.support_internal_harq_memory) {
|
||||
@@ -752,7 +749,6 @@ static int retrieve_ldpc_dec_op(struct rte_bbdev_dec_op **ops, nrLDPC_slot_decod
|
||||
active_dev.harq_buffers[pruned_segment_offset].offset = harq_output->offset;
|
||||
active_dev.harq_buffers[pruned_segment_offset].length = harq_output->length;
|
||||
++j;
|
||||
data_off += p->K >> 3;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -827,7 +823,7 @@ static int pmd_lcore_ldpc_dec(void *arg)
|
||||
|
||||
// Start timer
|
||||
// We report timing only once in (0,0) since the timers are merged at the end
|
||||
start_meas(&nrLDPC_slot_decoding_parameters->TBs[0].ts_ldpc_decode);
|
||||
start_meas(&nrLDPC_slot_decoding_parameters->TBs[0].segments[0].ts_ldpc_decode);
|
||||
|
||||
uint16_t enq = 0, deq = 0;
|
||||
while (enq < num_segments) {
|
||||
@@ -844,7 +840,7 @@ static int pmd_lcore_ldpc_dec(void *arg)
|
||||
|
||||
// Stop timer
|
||||
// We report timing only once in (0,0) since the timers are merged at the end
|
||||
stop_meas(&nrLDPC_slot_decoding_parameters->TBs[0].ts_ldpc_decode);
|
||||
stop_meas(&nrLDPC_slot_decoding_parameters->TBs[0].segments[0].ts_ldpc_decode);
|
||||
|
||||
if (deq == enq) {
|
||||
ret = retrieve_ldpc_dec_op(ops_deq, nrLDPC_slot_decoding_parameters);
|
||||
@@ -853,24 +849,24 @@ static int pmd_lcore_ldpc_dec(void *arg)
|
||||
/* get the max of iter_count for all dequeued ops */
|
||||
int j = 0;
|
||||
for (int h = 0; h < nrLDPC_slot_decoding_parameters->nb_TBs; ++h) {
|
||||
nrLDPC_TB_decoding_parameters_t *p = &nrLDPC_slot_decoding_parameters->TBs[h];
|
||||
for (int i = 0; i < p->C; ++i) {
|
||||
bool *status = &p->decodeSuccess[i];
|
||||
for (int i = 0; i < nrLDPC_slot_decoding_parameters->TBs[h].C; ++i) {
|
||||
bool *status = &nrLDPC_slot_decoding_parameters->TBs[h].segments[i].decodeSuccess;
|
||||
tp->iter_count = RTE_MAX(ops_enq[j]->ldpc_dec.iter_count, tp->iter_count);
|
||||
|
||||
// Check if CRC is available otherwise rely on ops_enq[j]->status to detect decoding success
|
||||
// CRC is NOT available if the CRC type is 24_B which is when C is greater than 1
|
||||
if (p->C > 1) {
|
||||
if (nrLDPC_slot_decoding_parameters->TBs[h].C > 1) {
|
||||
*status = (ops_enq[j]->status == 0);
|
||||
} else {
|
||||
uint8_t *decoded_bytes = p->c;
|
||||
uint8_t crc_type = crcType(p->C, p->A);
|
||||
uint32_t len_with_crc = lenWithCrc(p->C, p->A);
|
||||
uint8_t *decoded_bytes = nrLDPC_slot_decoding_parameters->TBs[h].segments[i].c;
|
||||
uint8_t crc_type = crcType(nrLDPC_slot_decoding_parameters->TBs[h].C, nrLDPC_slot_decoding_parameters->TBs[h].A);
|
||||
uint32_t len_with_crc = lenWithCrc(nrLDPC_slot_decoding_parameters->TBs[h].C, nrLDPC_slot_decoding_parameters->TBs[h].A);
|
||||
*status = check_crc(decoded_bytes, len_with_crc, crc_type);
|
||||
}
|
||||
|
||||
if (*status) {
|
||||
*p->processedSegments = *p->processedSegments + 1;
|
||||
*nrLDPC_slot_decoding_parameters->TBs[h].processedSegments =
|
||||
*nrLDPC_slot_decoding_parameters->TBs[h].processedSegments + 1;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
@@ -1061,7 +1057,7 @@ static int normalize_dpdk_dev(const char *input, char *output, size_t out_len)
|
||||
}
|
||||
|
||||
// OAI CODE
|
||||
int32_t nrLDPC_coding_init(int max_num_pxsch)
|
||||
int32_t nrLDPC_coding_init()
|
||||
{
|
||||
pthread_mutex_init(&encode_mutex, NULL);
|
||||
pthread_mutex_init(&decode_mutex, NULL);
|
||||
@@ -1287,24 +1283,28 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec
|
||||
int8_t llr_decimal = (active_dev.info.drv.capabilities)[RTE_BBDEV_OP_LDPC_DEC].cap.ldpc_dec.llr_decimals;
|
||||
int offset = 0;
|
||||
for (int h = 0; h < nrLDPC_slot_decoding_parameters->nb_TBs; ++h) {
|
||||
nrLDPC_TB_decoding_parameters_t *p = &nrLDPC_slot_decoding_parameters->TBs[h];
|
||||
size_t data_off = 0;
|
||||
for (int r = 0; r < p->C; r++) {
|
||||
uint32_t E = r < p->first_rE2 ? p->E : p->E2;
|
||||
for (int r = 0; r < nrLDPC_slot_decoding_parameters->TBs[h].C; r++) {
|
||||
if (active_dev.is_t2) {
|
||||
// For the T2, we simply saturate the LLRs.
|
||||
uint16_t z_ol[LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
|
||||
memcpy(z_ol, p->llr + data_off, E * sizeof(uint16_t));
|
||||
memcpy(z_ol,
|
||||
nrLDPC_slot_decoding_parameters->TBs[h].segments[r].llr,
|
||||
nrLDPC_slot_decoding_parameters->TBs[h].segments[r].E * sizeof(uint16_t));
|
||||
simde__m128i *pv_ol128 = (simde__m128i *)z_ol;
|
||||
simde__m128i *pl_ol128 = (simde__m128i *)&l_ol[offset];
|
||||
for (int i = 0, j = 0; j < ((E + 15) >> 4); i += 2, j++) {
|
||||
for (int i = 0, j = 0; j < ((nrLDPC_slot_decoding_parameters->TBs[h].segments[r].E + 15) >> 4); i += 2, j++) {
|
||||
pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]);
|
||||
}
|
||||
} else {
|
||||
llr_scaling(p->llr + data_off, E, &l_ol[offset], llr_size, llr_decimal, p->nb_layers, p->Qm);
|
||||
llr_scaling(nrLDPC_slot_decoding_parameters->TBs[h].segments[r].llr,
|
||||
nrLDPC_slot_decoding_parameters->TBs[h].segments[r].E,
|
||||
&l_ol[offset],
|
||||
llr_size,
|
||||
llr_decimal,
|
||||
nrLDPC_slot_decoding_parameters->TBs[h].nb_layers,
|
||||
nrLDPC_slot_decoding_parameters->TBs[h].Qm);
|
||||
}
|
||||
offset += LDPC_MAX_CB_SIZE;
|
||||
data_off += E;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,12 +8,43 @@
|
||||
|
||||
#include "common/utils/time_meas.h"
|
||||
#include "openair1/PHY/CODING/coding_defs.h"
|
||||
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
#ifndef __NRLDPC_CODING_INTERFACE__H__
|
||||
#define __NRLDPC_CODING_INTERFACE__H__
|
||||
|
||||
/**
|
||||
* \typedef nrLDPC_segment_decoding_parameters_t
|
||||
* \struct nrLDPC_segment_decoding_parameters_s
|
||||
* \brief decoding parameter of segments
|
||||
* \var E input llr segment size
|
||||
* \var R code rate indication
|
||||
* \var llr segment input llr array
|
||||
* \var d Pointers to code blocks before LDPC decoding (38.212 V15.4.0 section 5.3.2)
|
||||
* \var d_to_be_cleared
|
||||
* pointer to the flag used to clear d properly
|
||||
* when true, clear d after rate dematching
|
||||
* \var c Pointers to code blocks after LDPC decoding (38.212 V15.4.0 section 5.2.2)
|
||||
* \var decodeSuccess
|
||||
* flag indicating that the decoding of the segment was successful
|
||||
* IT MUST BE FILLED BY THE IMPLEMENTATION
|
||||
* \var ts_deinterleave deinterleaving time stats
|
||||
* \var ts_rate_unmatch rate unmatching time stats
|
||||
* \var ts_ldpc_decode decoding time stats
|
||||
*/
|
||||
typedef struct nrLDPC_segment_decoding_parameters_s{
|
||||
int E;
|
||||
uint8_t R;
|
||||
short *llr;
|
||||
int16_t *d;
|
||||
bool *d_to_be_cleared;
|
||||
uint8_t *c;
|
||||
bool decodeSuccess;
|
||||
time_stats_t ts_deinterleave;
|
||||
time_stats_t ts_rate_unmatch;
|
||||
time_stats_t ts_ldpc_decode;
|
||||
} nrLDPC_segment_decoding_parameters_t;
|
||||
|
||||
/**
|
||||
* \typedef nrLDPC_TB_decoding_parameters_t
|
||||
* \struct nrLDPC_TB_decoding_parameters_s
|
||||
@@ -65,20 +96,7 @@ typedef struct nrLDPC_TB_decoding_parameters_s{
|
||||
uint32_t F;
|
||||
|
||||
uint32_t C;
|
||||
int E;
|
||||
uint8_t R;
|
||||
int E2;
|
||||
uint8_t R2;
|
||||
int first_rE2;
|
||||
short *llr;
|
||||
uint8_t *c;
|
||||
int16_t *d;
|
||||
bool d_to_be_cleared;
|
||||
bool decodeSuccess[NR_LDPC_MAX_NUM_CB];
|
||||
time_stats_t ts_deinterleave;
|
||||
time_stats_t ts_rate_unmatch;
|
||||
time_stats_t ts_seg_prep;
|
||||
time_stats_t ts_ldpc_decode;
|
||||
nrLDPC_segment_decoding_parameters_t *segments;
|
||||
} nrLDPC_TB_decoding_parameters_t;
|
||||
|
||||
/**
|
||||
@@ -119,7 +137,6 @@ typedef struct nrLDPC_segment_encoding_parameters_s{
|
||||
time_stats_t ts_interleave;
|
||||
time_stats_t ts_rate_match;
|
||||
time_stats_t ts_ldpc_encode;
|
||||
time_stats_t ts_output;
|
||||
} nrLDPC_segment_encoding_parameters_t;
|
||||
|
||||
/**
|
||||
@@ -194,15 +211,13 @@ typedef struct nrLDPC_slot_encoding_parameters_s{
|
||||
int nb_TBs;
|
||||
tpool_t *threadPool;
|
||||
time_stats_t *tinput;
|
||||
time_stats_t *tinput_memcpy;
|
||||
time_stats_t *tprep;
|
||||
time_stats_t *tparity;
|
||||
time_stats_t *toutput;
|
||||
time_stats_t *tconcat;
|
||||
nrLDPC_TB_encoding_parameters_t *TBs;
|
||||
} nrLDPC_slot_encoding_parameters_t;
|
||||
|
||||
typedef int32_t(nrLDPC_coding_init_t)(int);
|
||||
typedef int32_t(nrLDPC_coding_init_t)(void);
|
||||
typedef int32_t(nrLDPC_coding_shutdown_t)(void);
|
||||
|
||||
/**
|
||||
@@ -224,7 +239,7 @@ typedef struct nrLDPC_coding_interface_s {
|
||||
nrLDPC_coding_encoder_t *nrLDPC_coding_encoder;
|
||||
} nrLDPC_coding_interface_t;
|
||||
|
||||
int load_nrLDPC_coding_interface(char *version, nrLDPC_coding_interface_t *interface, int);
|
||||
int load_nrLDPC_coding_interface(char *version, nrLDPC_coding_interface_t *interface);
|
||||
int free_nrLDPC_coding_interface(nrLDPC_coding_interface_t *interface);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
/* arg is used to initialize the config module so that the loader works as expected */
|
||||
char *arguments_phy_simulators[64]={"ldpctest",NULL};
|
||||
|
||||
int load_nrLDPC_coding_interface(char *version, nrLDPC_coding_interface_t *itf, int max_num_pxsch)
|
||||
int load_nrLDPC_coding_interface(char *version, nrLDPC_coding_interface_t *itf)
|
||||
{
|
||||
char *ptr = (char *)config_get_if();
|
||||
char libname[64] = "ldpc";
|
||||
@@ -46,7 +46,7 @@ int load_nrLDPC_coding_interface(char *version, nrLDPC_coding_interface_t *itf,
|
||||
itf->nrLDPC_coding_decoder = (nrLDPC_coding_decoder_t *)shlib_fdesc[2].fptr;
|
||||
itf->nrLDPC_coding_encoder = (nrLDPC_coding_encoder_t *)shlib_fdesc[3].fptr;
|
||||
|
||||
AssertFatal(itf->nrLDPC_coding_init(max_num_pxsch) == 0, "error starting LDPC library %s %s\n", libname, version);
|
||||
AssertFatal(itf->nrLDPC_coding_init() == 0, "error starting LDPC library %s %s\n", libname, version);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
typedef struct nrLDPC_decoding_parameters_s {
|
||||
t_nrLDPC_dec_params decoderParms;
|
||||
|
||||
int r;
|
||||
uint8_t Qm;
|
||||
|
||||
uint8_t Kc;
|
||||
@@ -84,16 +83,15 @@ typedef struct nrLDPC_decoding_parameters_s {
|
||||
int E;
|
||||
short *llr;
|
||||
int16_t *d;
|
||||
bool d_to_be_cleared;
|
||||
bool *d_to_be_cleared;
|
||||
uint8_t *c;
|
||||
bool *decodeSuccess;
|
||||
|
||||
task_ans_t *ans;
|
||||
|
||||
time_stats_t ts_deinterleave;
|
||||
time_stats_t ts_rate_unmatch;
|
||||
time_stats_t ts_seg_prep;
|
||||
time_stats_t ts_ldpc_decode;
|
||||
time_stats_t *p_ts_deinterleave;
|
||||
time_stats_t *p_ts_rate_unmatch;
|
||||
time_stats_t *p_ts_ldpc_decode;
|
||||
} nrLDPC_decoding_parameters_t;
|
||||
|
||||
static void nr_process_decode_segment(void *arg)
|
||||
@@ -119,7 +117,7 @@ static void nr_process_decode_segment(void *arg)
|
||||
|
||||
//////////////////////////// ulsch_llr =====> ulsch_harq->e //////////////////////////////
|
||||
|
||||
start_meas(&rdata->ts_deinterleave);
|
||||
start_meas(rdata->p_ts_deinterleave);
|
||||
|
||||
/// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
|
||||
int16_t harq_e[E];
|
||||
@@ -128,9 +126,9 @@ static void nr_process_decode_segment(void *arg)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
stop_meas(&rdata->ts_deinterleave);
|
||||
stop_meas(rdata->p_ts_deinterleave);
|
||||
|
||||
start_meas(&rdata->ts_rate_unmatch);
|
||||
start_meas(rdata->p_ts_rate_unmatch);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
|
||||
@@ -145,28 +143,21 @@ static void nr_process_decode_segment(void *arg)
|
||||
harq_e,
|
||||
rdata->C,
|
||||
rv_index,
|
||||
rdata->d_to_be_cleared,
|
||||
*rdata->d_to_be_cleared,
|
||||
E,
|
||||
rdata->F,
|
||||
K - rdata->F - 2 * (p_decoderParms->Z))
|
||||
== -1) {
|
||||
stop_meas(&rdata->ts_rate_unmatch);
|
||||
LOG_E(PHY,
|
||||
"nrLDPC_coding_segment_decoder.c: Problem in rate_matching BG %d, Z %d, C %d, rv_index %d, E %d, F %d, K%d, K-F-2*Z %d\n",
|
||||
p_decoderParms->BG,
|
||||
p_decoderParms->Z,
|
||||
rdata->C,
|
||||
rv_index,
|
||||
E,
|
||||
rdata->F,
|
||||
K,
|
||||
K - rdata->F - 2 * (p_decoderParms->Z));
|
||||
stop_meas(rdata->p_ts_rate_unmatch);
|
||||
LOG_E(PHY, "nrLDPC_coding_segment_decoder.c: Problem in rate_matching\n");
|
||||
|
||||
// Task completed
|
||||
completed_task_ans(rdata->ans);
|
||||
return;
|
||||
}
|
||||
stop_meas(&rdata->ts_rate_unmatch);
|
||||
stop_meas(rdata->p_ts_rate_unmatch);
|
||||
|
||||
*rdata->d_to_be_cleared = false;
|
||||
|
||||
p_decoderParms->crc_type = crcType(rdata->C, A);
|
||||
p_decoderParms->Kprime = lenWithCrc(rdata->C, A);
|
||||
@@ -175,8 +166,8 @@ static void nr_process_decode_segment(void *arg)
|
||||
|
||||
int16_t z[68 * 384 + 16] __attribute__((aligned(16)));
|
||||
|
||||
start_meas(rdata->p_ts_ldpc_decode);
|
||||
|
||||
start_meas(&rdata->ts_seg_prep);
|
||||
memset(z, 0, 2 * rdata->Z * sizeof(*z));
|
||||
// set Filler bits
|
||||
memset(z + Kprime, 127, rdata->F * sizeof(*z));
|
||||
@@ -191,7 +182,6 @@ static void nr_process_decode_segment(void *arg)
|
||||
for (int i = 0, j = 0; j < ((Kc * rdata->Z) >> 4) + 1; i += 2, j++) {
|
||||
pl[j] = simde_mm_packs_epi16(pv[i], pv[i + 1]);
|
||||
}
|
||||
stop_meas(&rdata->ts_seg_prep);
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -199,18 +189,16 @@ static void nr_process_decode_segment(void *arg)
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
|
||||
start_meas(&rdata->ts_ldpc_decode);
|
||||
int decodeIterations = LDPCdecoder(p_decoderParms, l, (uint8_t *)llrProcBuf, p_procTime, rdata->abort_decode);
|
||||
AssertFatal(rdata->c, "rdata->c is null, A %d, K %d\n", rdata->A, rdata->K);
|
||||
int decodeIterations = LDPCdecoder(p_decoderParms, l, llrProcBuf, p_procTime, rdata->abort_decode);
|
||||
|
||||
if (decodeIterations < p_decoderParms->numMaxIter) {
|
||||
memcpy(rdata->c, llrProcBuf, K >> 3);
|
||||
*rdata->decodeSuccess = true;
|
||||
} else {
|
||||
LOG_D(PHY, "Decoding failed: K %d, Z %d, rv_index %d\n", K, rdata->Z, rdata->rv_index);
|
||||
memset(rdata->c, 0, K >> 3);
|
||||
*rdata->decodeSuccess = false;
|
||||
}
|
||||
stop_meas(&rdata->ts_ldpc_decode);
|
||||
stop_meas(rdata->p_ts_ldpc_decode);
|
||||
|
||||
// Task completed
|
||||
completed_task_ans(rdata->ans);
|
||||
@@ -227,28 +215,20 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de
|
||||
decParams.BG = nrLDPC_TB_decoding_parameters->BG;
|
||||
decParams.Z = nrLDPC_TB_decoding_parameters->Z;
|
||||
decParams.numMaxIter = nrLDPC_TB_decoding_parameters->max_ldpc_iterations;
|
||||
decParams.outMode = nrLDPC_outMode_BIT;
|
||||
decParams.outMode = 0;
|
||||
|
||||
for (int r = 0; r < nrLDPC_TB_decoding_parameters->C; r++) {
|
||||
nrLDPC_decoding_parameters_t *rdata = &((nrLDPC_decoding_parameters_t *)t_info->buf)[t_info->len];
|
||||
DevAssert(t_info->len < t_info->cap);
|
||||
rdata->ans = t_info->ans;
|
||||
t_info->len += 1;
|
||||
int llr_offset;
|
||||
if (r < nrLDPC_TB_decoding_parameters->first_rE2) {
|
||||
decParams.R = nrLDPC_TB_decoding_parameters->R;
|
||||
rdata->E = nrLDPC_TB_decoding_parameters->E;
|
||||
llr_offset = r * rdata->E;
|
||||
} else {
|
||||
decParams.R = nrLDPC_TB_decoding_parameters->R2;
|
||||
rdata->E = nrLDPC_TB_decoding_parameters->E2;
|
||||
llr_offset = nrLDPC_TB_decoding_parameters->first_rE2 * nrLDPC_TB_decoding_parameters->E
|
||||
+ (r - nrLDPC_TB_decoding_parameters->first_rE2) * rdata->E;
|
||||
}
|
||||
rdata->r = r;
|
||||
|
||||
decParams.R = nrLDPC_TB_decoding_parameters->segments[r].R;
|
||||
rdata->decoderParms = decParams;
|
||||
rdata->llr = nrLDPC_TB_decoding_parameters->segments[r].llr;
|
||||
rdata->Kc = decParams.BG == 2 ? 52 : 68;
|
||||
rdata->C = nrLDPC_TB_decoding_parameters->C;
|
||||
rdata->E = nrLDPC_TB_decoding_parameters->segments[r].E;
|
||||
rdata->A = nrLDPC_TB_decoding_parameters->A;
|
||||
rdata->Qm = nrLDPC_TB_decoding_parameters->Qm;
|
||||
rdata->K = nrLDPC_TB_decoding_parameters->K;
|
||||
@@ -257,30 +237,18 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de
|
||||
rdata->rv_index = nrLDPC_TB_decoding_parameters->rv_index;
|
||||
rdata->tbslbrm = nrLDPC_TB_decoding_parameters->tbslbrm;
|
||||
rdata->abort_decode = nrLDPC_TB_decoding_parameters->abort_decode;
|
||||
rdata->d = nrLDPC_TB_decoding_parameters->d + r * rdata->Kc * rdata->Z;
|
||||
rdata->d_to_be_cleared = nrLDPC_TB_decoding_parameters->d_to_be_cleared;
|
||||
rdata->c = nrLDPC_TB_decoding_parameters->c + r * (rdata->K >> 3);
|
||||
AssertFatal(rdata->c != NULL,
|
||||
"rdata->c is null, r %d, K %d, A %d, rv_index %d, TB_decoding_parameters->c %p\n",
|
||||
r,
|
||||
rdata->K,
|
||||
rdata->A,
|
||||
rdata->rv_index,
|
||||
nrLDPC_TB_decoding_parameters->c);
|
||||
rdata->llr = nrLDPC_TB_decoding_parameters->llr + llr_offset; // rdata->Kc*rdata->Z;
|
||||
rdata->decodeSuccess = &nrLDPC_TB_decoding_parameters->decodeSuccess[r];
|
||||
memset(&rdata->ts_deinterleave, 0, sizeof(rdata->ts_deinterleave));
|
||||
memset(&rdata->ts_rate_unmatch, 0, sizeof(rdata->ts_rate_unmatch));
|
||||
memset(&rdata->ts_seg_prep, 0, sizeof(rdata->ts_seg_prep));
|
||||
memset(&rdata->ts_ldpc_decode, 0, sizeof(rdata->ts_ldpc_decode));
|
||||
reset_meas(&rdata->ts_deinterleave);
|
||||
reset_meas(&rdata->ts_rate_unmatch);
|
||||
reset_meas(&rdata->ts_seg_prep);
|
||||
reset_meas(&rdata->ts_ldpc_decode);
|
||||
rdata->d = nrLDPC_TB_decoding_parameters->segments[r].d;
|
||||
rdata->d_to_be_cleared = nrLDPC_TB_decoding_parameters->segments[r].d_to_be_cleared;
|
||||
rdata->c = nrLDPC_TB_decoding_parameters->segments[r].c;
|
||||
rdata->decodeSuccess = &nrLDPC_TB_decoding_parameters->segments[r].decodeSuccess;
|
||||
rdata->p_ts_deinterleave = &nrLDPC_TB_decoding_parameters->segments[r].ts_deinterleave;
|
||||
rdata->p_ts_rate_unmatch = &nrLDPC_TB_decoding_parameters->segments[r].ts_rate_unmatch;
|
||||
rdata->p_ts_ldpc_decode = &nrLDPC_TB_decoding_parameters->segments[r].ts_ldpc_decode;
|
||||
|
||||
task_t t = {.func = &nr_process_decode_segment, .args = rdata};
|
||||
pushTpool(nrLDPC_slot_decoding_parameters->threadPool, t);
|
||||
|
||||
LOG_D(PHY, "Added a block to decode, in pipe: %d, rdata->c %p\n", r, rdata->c);
|
||||
LOG_D(PHY, "Added a block to decode, in pipe: %d\n", r);
|
||||
}
|
||||
return nrLDPC_TB_decoding_parameters->C;
|
||||
}
|
||||
@@ -314,20 +282,12 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec
|
||||
// Execute thread pool tasks
|
||||
join_task_ans(t_info.ans);
|
||||
|
||||
size_t r_t_info = 0;
|
||||
for (int pusch_id = 0; pusch_id < nrLDPC_slot_decoding_parameters->nb_TBs; pusch_id++) {
|
||||
nrLDPC_TB_decoding_parameters_t *nrLDPC_TB_decoding_parameters = &nrLDPC_slot_decoding_parameters->TBs[pusch_id];
|
||||
*nrLDPC_TB_decoding_parameters->processedSegments = 0;
|
||||
for (int r = 0; r < nrLDPC_TB_decoding_parameters->C; r++) {
|
||||
if (nrLDPC_TB_decoding_parameters->decodeSuccess[r])
|
||||
if (nrLDPC_TB_decoding_parameters->segments[r].decodeSuccess) {
|
||||
*nrLDPC_TB_decoding_parameters->processedSegments = *nrLDPC_TB_decoding_parameters->processedSegments + 1;
|
||||
|
||||
nrLDPC_decoding_parameters_t *rdata = &((nrLDPC_decoding_parameters_t *)t_info.buf)[r_t_info];
|
||||
r_t_info += 1;
|
||||
merge_meas(&nrLDPC_TB_decoding_parameters->ts_deinterleave, &rdata->ts_deinterleave);
|
||||
merge_meas(&nrLDPC_TB_decoding_parameters->ts_rate_unmatch, &rdata->ts_rate_unmatch);
|
||||
merge_meas(&nrLDPC_TB_decoding_parameters->ts_seg_prep, &rdata->ts_seg_prep);
|
||||
merge_meas(&nrLDPC_TB_decoding_parameters->ts_ldpc_decode, &rdata->ts_ldpc_decode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -339,11 +339,9 @@ static int nrLDPC_launch_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_s
|
||||
encoder_implemparams_t common_segment_params = {
|
||||
.n_segments = nrLDPC_TB_encoding_parameters->C,
|
||||
.tinput = nrLDPC_slot_encoding_parameters->tinput,
|
||||
.tinput_memcpy = nrLDPC_slot_encoding_parameters->tinput_memcpy,
|
||||
.tprep = nrLDPC_slot_encoding_parameters->tprep,
|
||||
.tparity = nrLDPC_slot_encoding_parameters->tparity,
|
||||
.toutput = nrLDPC_slot_encoding_parameters->toutput,
|
||||
.tconcat = nrLDPC_slot_encoding_parameters->tconcat,
|
||||
.Kb = nrLDPC_TB_encoding_parameters->Kb,
|
||||
.Zc = nrLDPC_TB_encoding_parameters->Z,
|
||||
.BG = nrLDPC_TB_encoding_parameters->BG,
|
||||
@@ -426,15 +424,14 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
|
||||
join_task_ans(&ans);
|
||||
|
||||
// Write output
|
||||
time_stats_t *tconcat = nrLDPC_slot_encoding_parameters->tconcat;
|
||||
if (tconcat != NULL)
|
||||
start_meas(tconcat);
|
||||
nbTasks = 0;
|
||||
for (int dlsch_id = 0; dlsch_id < nrLDPC_slot_encoding_parameters->nb_TBs; dlsch_id++) {
|
||||
nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = &nrLDPC_slot_encoding_parameters->TBs[dlsch_id];
|
||||
uint32_t C = nrLDPC_TB_encoding_parameters->C;
|
||||
size_t n_seg = (C / 8 + ((C & 7) == 0 ? 0 : 1));
|
||||
|
||||
time_stats_t *toutput = nrLDPC_slot_encoding_parameters->toutput;
|
||||
|
||||
for (int j = 0; j < n_seg; j++) {
|
||||
unsigned int macro_segment = j * 8;
|
||||
unsigned int macro_segment_end = (C > macro_segment + 8) ? macro_segment + 8 : C;
|
||||
@@ -451,6 +448,7 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
|
||||
}
|
||||
}
|
||||
|
||||
if(toutput != NULL) start_meas(toutput);
|
||||
|
||||
uint32_t Eoffset=0;
|
||||
for (int s=0; s<macro_segment; s++)
|
||||
@@ -464,11 +462,11 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
|
||||
macro_segment_end - macro_segment,
|
||||
nrLDPC_TB_encoding_parameters->output,
|
||||
Eoffset);
|
||||
|
||||
if(toutput != NULL) stop_meas(toutput);
|
||||
}
|
||||
nbTasks += n_seg;
|
||||
}
|
||||
if (tconcat != NULL)
|
||||
stop_meas(tconcat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1296,7 +1296,7 @@ static inline void nrLDPC_bnProc(t_nrLDPC_lut* p_lut, int8_t* bnProcBuf, int8_t*
|
||||
\param llrOut Pointer to output LLRs
|
||||
\param numLLR Number of LLRs
|
||||
*/
|
||||
static inline void nrLDPC_llr2bit(uint8_t* out, int8_t* llrOut, uint16_t numLLR)
|
||||
static inline void nrLDPC_llr2bit(int8_t* out, int8_t* llrOut, uint16_t numLLR)
|
||||
{
|
||||
simde__m256i* p_llrOut = (simde__m256i*) llrOut;
|
||||
simde__m256i* p_out = (simde__m256i*) out;
|
||||
@@ -1313,7 +1313,7 @@ static inline void nrLDPC_llr2bit(uint8_t* out, int8_t* llrOut, uint16_t numLLR)
|
||||
|
||||
// Remaining LLRs that do not fit in multiples of 32 bytes
|
||||
int8_t* p_llrOut8 = (int8_t*)p_llrOut;
|
||||
uint8_t* p_out8 = (uint8_t*)p_out;
|
||||
int8_t* p_out8 = (int8_t*)p_out;
|
||||
|
||||
for (uint32_t i = 0; i < Mr; i++)
|
||||
p_out8[i] = p_llrOut8[i] < 0;
|
||||
@@ -1328,7 +1328,7 @@ static inline void nrLDPC_llr2bit(uint8_t* out, int8_t* llrOut, uint16_t numLLR)
|
||||
\param llrOut Pointer to output LLRs
|
||||
\param numLLR Number of LLRs
|
||||
*/
|
||||
static inline void nrLDPC_llr2bitPacked(uint8_t* out, int8_t* llrOut, uint16_t numLLR)
|
||||
static inline void nrLDPC_llr2bitPacked(int8_t* out, int8_t* llrOut, uint16_t numLLR)
|
||||
{
|
||||
/** Vector of indices for shuffling input */
|
||||
const uint8_t constShuffle_256_epi8[32] __attribute__ ((aligned(32))) = {7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8};
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
*/
|
||||
|
||||
static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr,
|
||||
uint8_t* p_out,
|
||||
int8_t* p_out,
|
||||
uint32_t numLLR,
|
||||
t_nrLDPC_lut* p_lut,
|
||||
t_nrLDPC_dec_params* p_decParams,
|
||||
@@ -155,7 +155,7 @@ int32_t LDPCshutdown()
|
||||
|
||||
int32_t LDPCdecoder(t_nrLDPC_dec_params* p_decParams,
|
||||
int8_t* p_llr,
|
||||
uint8_t* p_out,
|
||||
int8_t* p_out,
|
||||
t_nrLDPC_time_stats* p_profiler,
|
||||
decode_abort_t* ab)
|
||||
{
|
||||
@@ -185,7 +185,7 @@ int32_t LDPCdecoder(t_nrLDPC_dec_params* p_decParams,
|
||||
\param p_profilernrLDPC profiler statistics
|
||||
*/
|
||||
static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr,
|
||||
uint8_t* p_out,
|
||||
int8_t* p_out,
|
||||
uint32_t numLLR,
|
||||
t_nrLDPC_lut* p_lut,
|
||||
t_nrLDPC_dec_params* p_decParams,
|
||||
@@ -828,7 +828,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr,
|
||||
} else {
|
||||
if (numIter > 0) {
|
||||
int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__((aligned(64))) = {0};
|
||||
int8_t* p_llrOut = outMode == nrLDPC_outMode_LLRINT8 ? (int8_t*)p_out : llrOut;
|
||||
int8_t* p_llrOut = outMode == nrLDPC_outMode_LLRINT8 ? p_out : llrOut;
|
||||
nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG);
|
||||
if (outMode == nrLDPC_outMode_BIT)
|
||||
nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR);
|
||||
@@ -837,8 +837,6 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr,
|
||||
if (p_decParams->check_crc((uint8_t*)p_out, p_decParams->Kprime, p_decParams->crc_type)) {
|
||||
LOG_D(PHY, "Segment CRC OK, exiting LDPC decoder\n");
|
||||
break;
|
||||
} else {
|
||||
LOG_D(PHY, "Segment CRC NOK, Kprime %d, BG %d, Z %d\n", p_decParams->Kprime, BG, Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -847,7 +845,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr,
|
||||
}
|
||||
if (!p_decParams->check_crc) {
|
||||
int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__((aligned(64))) = {0};
|
||||
int8_t* p_llrOut = outMode == nrLDPC_outMode_LLRINT8 ? (int8_t*)p_out : llrOut;
|
||||
int8_t* p_llrOut = outMode == nrLDPC_outMode_LLRINT8 ? p_out : llrOut;
|
||||
// Assign results from processing buffer to output
|
||||
NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->llrRes2llrOut));
|
||||
nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG);
|
||||
|
||||
@@ -39,11 +39,9 @@ typedef struct {
|
||||
unsigned int first_seg; // optim8segmulti
|
||||
unsigned char gen_code; // orig
|
||||
time_stats_t *tinput;
|
||||
time_stats_t *tinput_memcpy;
|
||||
time_stats_t *tprep;
|
||||
time_stats_t *tparity;
|
||||
time_stats_t *toutput;
|
||||
time_stats_t *tconcat;
|
||||
/// Size in bits of the code segments
|
||||
uint32_t K;
|
||||
/// Number of lifting sizes to fit the payload
|
||||
@@ -73,7 +71,7 @@ typedef int32_t(LDPC_shutdownfunc_t)(void);
|
||||
*/
|
||||
typedef int32_t(LDPC_decoderfunc_t)(t_nrLDPC_dec_params *p_decParams,
|
||||
int8_t *p_llr,
|
||||
uint8_t *p_out,
|
||||
int8_t *p_out,
|
||||
t_nrLDPC_time_stats *time_stats,
|
||||
decode_abort_t *ab);
|
||||
typedef int32_t(LDPC_encoderfunc_t)(uint8_t **, uint8_t *, encoder_implemparams_t *);
|
||||
|
||||
@@ -80,11 +80,9 @@
|
||||
#include "ldpc_BG2_Zc80_byte.c"
|
||||
#include "ldpc_BG2_Zc72_byte.c"
|
||||
|
||||
static void encode_parity_check_part_optim(uint8_t *cc, uint8_t *d, short BG, short Zc, int simd_size, int ncols, time_stats_t *tinput_memcpy)
|
||||
static void encode_parity_check_part_optim(uint8_t *cc, uint8_t *d, short BG, short Zc, int simd_size, int ncols)
|
||||
{
|
||||
unsigned char c[2 * 22 * Zc * simd_size] __attribute__((aligned(64))); //double size matrix of c
|
||||
if (tinput_memcpy)
|
||||
start_meas(tinput_memcpy);
|
||||
for (int i1 = 0; i1 < ncols; i1++) {
|
||||
memcpy(&c[2 * i1 * Zc], &cc[i1 * Zc], Zc * sizeof(unsigned char));
|
||||
memcpy(&c[(2 * i1 + 1) * Zc], &cc[i1 * Zc], Zc * sizeof(unsigned char));
|
||||
@@ -97,8 +95,6 @@ static void encode_parity_check_part_optim(uint8_t *cc, uint8_t *d, short BG, sh
|
||||
memcpy(&c[(2 * ncols * Zc * i1)], &c[i1], (2 * ncols * Zc * sizeof(unsigned char)) - i1);
|
||||
}
|
||||
}
|
||||
if (tinput_memcpy)
|
||||
stop_meas(tinput_memcpy);
|
||||
if (BG == 1) {
|
||||
switch (Zc) {
|
||||
case 176:
|
||||
|
||||
@@ -169,23 +169,23 @@ int LDPCencoder(uint8_t **input, uint8_t *output, encoder_implemparams_t *impp)
|
||||
|
||||
if(impp->tinput != NULL) stop_meas(impp->tinput);
|
||||
|
||||
if ((BG == 1 && Zc >= 176) || (BG == 2 && Zc >= 72)) {
|
||||
if ((BG==1 && Zc>=176) || (BG==2 && Zc>=72)) {
|
||||
// extend matrix
|
||||
if(impp->tprep != NULL) start_meas(impp->tprep);
|
||||
if(impp->tprep != NULL) stop_meas(impp->tprep);
|
||||
//parity check part
|
||||
if(impp->tparity != NULL) start_meas(impp->tparity);
|
||||
encode_parity_check_part_optim(cc, dd, BG, Zc, simd_size, ncols, impp->tinput_memcpy);
|
||||
encode_parity_check_part_optim(cc, dd, BG, Zc, simd_size, ncols);
|
||||
if(impp->tparity != NULL) stop_meas(impp->tparity);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (encode_parity_check_part_orig(cc, dd, BG, Zc, Kb, block_length)!=0) {
|
||||
printf("Problem with encoder\n");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
if (impp->toutput != NULL)
|
||||
start_meas(impp->toutput);
|
||||
memcpy(output,&cc[2*Zc],(block_length-(2*Zc)));
|
||||
memcpy(output+block_length-(2*Zc),dd,((nrows-no_punctured_columns) * Zc-removed_bit));
|
||||
if (impp->toutput != NULL)
|
||||
stop_meas(impp->toutput);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +119,8 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
|
||||
nr_init_fde(); // Init array for frequency equalization of transform precoding of PUSCH
|
||||
|
||||
int ret_loader = load_nrLDPC_coding_interface(NULL, &gNB->nrLDPC_coding_interface);
|
||||
AssertFatal(ret_loader == 0, "error loading LDPC library\n");
|
||||
|
||||
gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB;
|
||||
init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table);
|
||||
@@ -139,9 +141,6 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
/// Transport init necessary for NR synchro
|
||||
init_nr_transport(gNB);
|
||||
|
||||
int ret_loader = load_nrLDPC_coding_interface(NULL, &gNB->nrLDPC_coding_interface, 16 * gNB->max_nb_pusch);
|
||||
AssertFatal(ret_loader == 0, "error loading LDPC library\n");
|
||||
|
||||
init_DLSCH_struct(gNB);
|
||||
|
||||
/* Do NOT allocate per-antenna rxdataF: the gNB gets a pointer to the
|
||||
|
||||
@@ -329,6 +329,11 @@ void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_HARQ_PROCESSES], int
|
||||
|
||||
for (int j=0; j < 2; j++) {
|
||||
for (int i=0; i<number_of_processes; i++) {
|
||||
|
||||
for (int r=0; r<a_segments; r++) {
|
||||
free_and_zero(harq_list[j][i].c[r]);
|
||||
free_and_zero(harq_list[j][i].d[r]);
|
||||
}
|
||||
free_and_zero(harq_list[j][i].b);
|
||||
free_and_zero(harq_list[j][i].c);
|
||||
free_and_zero(harq_list[j][i].d);
|
||||
@@ -381,9 +386,14 @@ void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_HARQ_PROCESSE
|
||||
init_downlink_harq_status(harq_list[j] + i);
|
||||
|
||||
harq_list[j][i].b = malloc16_clear(a_segments * 1056);
|
||||
harq_list[j][i].c = malloc16(a_segments * sizeof(*harq_list[j][i].c) * 1056);
|
||||
harq_list[j][i].d = malloc16(a_segments * sizeof(*harq_list[j][i].d) * 3 * 8448);
|
||||
harq_list[j][i].c = malloc16(a_segments*sizeof(uint8_t *));
|
||||
harq_list[j][i].d = malloc16(a_segments*sizeof(int16_t *));
|
||||
const int sz=5*8448*sizeof(int16_t);
|
||||
init_abort(&harq_list[j][i].abort_decode);
|
||||
for (int r=0; r<a_segments; r++) {
|
||||
harq_list[j][i].c[r] = malloc16_clear(1056);
|
||||
harq_list[j][i].d[r] = malloc16_clear(sz);
|
||||
}
|
||||
harq_list[j][i].status = 0;
|
||||
harq_list[j][i].DLround = 0;
|
||||
}
|
||||
|
||||
@@ -320,8 +320,8 @@ void fft_shift(const c16_t *in,
|
||||
const int first_carrier_offset = fft_size_out - num_samp_half;
|
||||
for (int s = start_symb; s < start_symb + num_symb; s++) {
|
||||
// Copy negative freq component
|
||||
uint32_t out_offset = s * fft_size_out + first_carrier_offset;
|
||||
uint32_t in_offset = s * in_symb_sz;
|
||||
uint16_t out_offset = s * fft_size_out + first_carrier_offset;
|
||||
uint16_t in_offset = s * in_symb_sz;
|
||||
memcpy(out + out_offset, in + in_offset, num_samp_half * sizeof(int32_t));
|
||||
// Copy positive freq component
|
||||
out_offset = s * fft_size_out;
|
||||
|
||||
@@ -789,11 +789,9 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr
|
||||
{
|
||||
time_stats_t *dlsch_encoding_stats = &gNB->dlsch_encoding_stats;
|
||||
time_stats_t *tinput = &gNB->tinput;
|
||||
time_stats_t *tinput_memcpy = &gNB->tinput_memcpy;
|
||||
time_stats_t *tprep = &gNB->tprep;
|
||||
time_stats_t *tparity = &gNB->tparity;
|
||||
time_stats_t *toutput = &gNB->toutput;
|
||||
time_stats_t *tconcat = &gNB->tconcat;
|
||||
time_stats_t *dlsch_rate_matching_stats = &gNB->dlsch_rate_matching_stats;
|
||||
time_stats_t *dlsch_interleaving_stats = &gNB->dlsch_interleaving_stats;
|
||||
time_stats_t *dlsch_segmentation_stats = &gNB->dlsch_segmentation_stats;
|
||||
@@ -856,11 +854,9 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr
|
||||
slot,
|
||||
output,
|
||||
tinput,
|
||||
tinput_memcpy,
|
||||
tprep,
|
||||
tparity,
|
||||
toutput,
|
||||
tconcat,
|
||||
dlsch_rate_matching_stats,
|
||||
dlsch_interleaving_stats,
|
||||
dlsch_segmentation_stats)
|
||||
|
||||
@@ -20,11 +20,9 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
uint8_t slot,
|
||||
unsigned char *output,
|
||||
time_stats_t *tinput,
|
||||
time_stats_t *tinput_memcpy,
|
||||
time_stats_t *tprep,
|
||||
time_stats_t *tparity,
|
||||
time_stats_t *toutput,
|
||||
time_stats_t *tconcat,
|
||||
time_stats_t *dlsch_rate_matching_stats,
|
||||
time_stats_t *dlsch_interleaving_stats,
|
||||
time_stats_t *dlsch_segmentation_stats);
|
||||
|
||||
@@ -91,11 +91,9 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
uint8_t slot,
|
||||
unsigned char *output,
|
||||
time_stats_t *tinput,
|
||||
time_stats_t *tinput_memcpy,
|
||||
time_stats_t *tprep,
|
||||
time_stats_t *tparity,
|
||||
time_stats_t *toutput,
|
||||
time_stats_t *tconcat,
|
||||
time_stats_t *dlsch_rate_matching_stats,
|
||||
time_stats_t *dlsch_interleaving_stats,
|
||||
time_stats_t *dlsch_segmentation_stats)
|
||||
|
||||
@@ -47,8 +47,13 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL)
|
||||
free_and_zero(ulsch->harq_process->b);
|
||||
ulsch->harq_process->b = NULL;
|
||||
}
|
||||
for (int r = 0; r < a_segments; r++) {
|
||||
free_and_zero(ulsch->harq_process->c[r]);
|
||||
free_and_zero(ulsch->harq_process->d[r]);
|
||||
}
|
||||
free_and_zero(ulsch->harq_process->c);
|
||||
free_and_zero(ulsch->harq_process->d);
|
||||
free_and_zero(ulsch->harq_process->d_to_be_cleared);
|
||||
free_and_zero(ulsch->harq_process);
|
||||
ulsch->harq_process = NULL;
|
||||
}
|
||||
@@ -74,9 +79,14 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
|
||||
init_abort(&harq->abort_decode);
|
||||
ulsch.harq_process = harq;
|
||||
harq->b = malloc16_clear(ulsch_bytes * sizeof(*harq->b));
|
||||
// Allocate one contiguous buffer fr all c/d arrays to simplify addressing for GPU LDPC offload
|
||||
harq->c = malloc16_clear(a_segments * 8448 * sizeof(*harq->c));
|
||||
harq->d = malloc16_clear(a_segments * 68 * 384 * sizeof(*harq->d));
|
||||
harq->c = malloc16_clear(a_segments * sizeof(*harq->c));
|
||||
harq->d = malloc16_clear(a_segments * sizeof(*harq->d));
|
||||
for (int r = 0; r < a_segments; r++) {
|
||||
harq->c[r] = malloc16_clear(8448 * sizeof(*harq->c[r]));
|
||||
harq->d[r] = malloc16_clear(68 * 384 * sizeof(*harq->d[r]));
|
||||
}
|
||||
harq->d_to_be_cleared = calloc(a_segments, sizeof(bool));
|
||||
AssertFatal(harq->d_to_be_cleared != NULL, "out of memory\n");
|
||||
return (ulsch);
|
||||
}
|
||||
|
||||
@@ -213,6 +223,9 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
set_abort(&harq_process->abort_decode, false);
|
||||
}
|
||||
|
||||
nrLDPC_segment_decoding_parameters_t segments[nb_pusch][max_num_segments];
|
||||
memset(segments, 0, sizeof(segments));
|
||||
|
||||
for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) {
|
||||
uint8_t ULSCH_id = ULSCH_ids[pusch_id];
|
||||
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
|
||||
@@ -225,79 +238,66 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
}
|
||||
|
||||
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pusch_id];
|
||||
TB_parameters->segments = segments[pusch_id];
|
||||
|
||||
TB_parameters->llr = ulsch_llr;
|
||||
TB_parameters->d = harq_process->d;
|
||||
TB_parameters->c = harq_process->c;
|
||||
TB_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, 0);
|
||||
TB_parameters->first_rE2 = TB_parameters->C;
|
||||
TB_parameters->E2 = TB_parameters->E;
|
||||
TB_parameters->R = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
|
||||
TB_parameters->E,
|
||||
TB_parameters->BG,
|
||||
TB_parameters->Z,
|
||||
&harq_process->llrLen,
|
||||
harq_process->round);
|
||||
for (int r = 0; r < TB_parameters->C; r++)
|
||||
TB_parameters->decodeSuccess[r] = false;
|
||||
TB_parameters->d_to_be_cleared = harq_process->harq_to_be_cleared;
|
||||
reset_meas(&TB_parameters->ts_deinterleave);
|
||||
reset_meas(&TB_parameters->ts_rate_unmatch);
|
||||
reset_meas(&TB_parameters->ts_seg_prep);
|
||||
reset_meas(&TB_parameters->ts_ldpc_decode);
|
||||
uint32_t r_offset = 0;
|
||||
for (int r = 0; r < TB_parameters->C; r++) {
|
||||
int Etmp = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, r);
|
||||
if (TB_parameters->E != Etmp) {
|
||||
TB_parameters->E2 = Etmp;
|
||||
TB_parameters->R2 = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
|
||||
TB_parameters->E2,
|
||||
TB_parameters->BG,
|
||||
TB_parameters->Z,
|
||||
&harq_process->llrLen,
|
||||
harq_process->round);
|
||||
TB_parameters->first_rE2 = r;
|
||||
break;
|
||||
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
|
||||
segment_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, r);
|
||||
segment_parameters->R = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
|
||||
segment_parameters->E,
|
||||
TB_parameters->BG,
|
||||
TB_parameters->Z,
|
||||
&harq_process->llrLen,
|
||||
harq_process->round);
|
||||
segment_parameters->llr = ulsch_llr + r_offset;
|
||||
segment_parameters->d = harq_process->d[r];
|
||||
segment_parameters->d_to_be_cleared = &harq_process->d_to_be_cleared[r];
|
||||
segment_parameters->c = harq_process->c[r];
|
||||
segment_parameters->decodeSuccess = false;
|
||||
|
||||
reset_meas(&segment_parameters->ts_deinterleave);
|
||||
reset_meas(&segment_parameters->ts_rate_unmatch);
|
||||
reset_meas(&segment_parameters->ts_ldpc_decode);
|
||||
|
||||
r_offset += segment_parameters->E;
|
||||
}
|
||||
if (harq_process->harq_to_be_cleared) {
|
||||
for (int r = 0; r < TB_parameters->C; r++) {
|
||||
harq_process->d_to_be_cleared[r] = true;
|
||||
}
|
||||
harq_process->harq_to_be_cleared = false;
|
||||
}
|
||||
}
|
||||
|
||||
int ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
|
||||
|
||||
// post decode
|
||||
for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) {
|
||||
uint8_t ULSCH_id = ULSCH_ids[pusch_id];
|
||||
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
|
||||
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
|
||||
|
||||
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pusch_id];
|
||||
nrLDPC_TB_decoding_parameters_t TB_parameters = TBs[pusch_id];
|
||||
|
||||
uint32_t offset = 0, r_offset = 0;
|
||||
bool crcok = true;
|
||||
LOG_D(PHY, "C = %d\n", TB_parameters->C);
|
||||
for (int r = 0; r < TB_parameters->C; r++) {
|
||||
LOG_D(PHY, "Segment %d %d\n", r, TB_parameters->decodeSuccess[r]);
|
||||
if (TB_parameters->decodeSuccess[r] == false) {
|
||||
LOG_D(PHY, "Segment %d/%d in error\n", r, TB_parameters->C);
|
||||
crcok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (crcok) {
|
||||
for (int r = 0; r < TB_parameters->C; r++) {
|
||||
// Copy c to b in case of decoding success
|
||||
uint32_t offset = 0;
|
||||
for (int r = 0; r < TB_parameters.C; r++) {
|
||||
nrLDPC_segment_decoding_parameters_t nrLDPC_segment_decoding_parameters = TB_parameters.segments[r];
|
||||
// Copy c to b in case of decoding success
|
||||
if (nrLDPC_segment_decoding_parameters.decodeSuccess) {
|
||||
memcpy(harq_process->b + offset,
|
||||
harq_process->c + r_offset,
|
||||
harq_process->c[r],
|
||||
(harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
offset += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
r_offset += (harq_process->K >> 3);
|
||||
} else {
|
||||
LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C);
|
||||
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
|
||||
}
|
||||
} else {
|
||||
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
|
||||
offset += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
|
||||
merge_meas(&phy_vars_gNB->ts_deinterleave, &nrLDPC_segment_decoding_parameters.ts_deinterleave);
|
||||
merge_meas(&phy_vars_gNB->ts_rate_unmatch, &nrLDPC_segment_decoding_parameters.ts_rate_unmatch);
|
||||
merge_meas(&phy_vars_gNB->ts_ldpc_decode, &nrLDPC_segment_decoding_parameters.ts_ldpc_decode);
|
||||
}
|
||||
merge_meas(&phy_vars_gNB->ts_deinterleave, &TB_parameters->ts_deinterleave);
|
||||
merge_meas(&phy_vars_gNB->ts_rate_unmatch, &TB_parameters->ts_rate_unmatch);
|
||||
merge_meas(&phy_vars_gNB->ts_seg_prep, &TB_parameters->ts_seg_prep);
|
||||
merge_meas(&phy_vars_gNB->ts_ldpc_decode, &TB_parameters->ts_ldpc_decode);
|
||||
harq_process->harq_to_be_cleared = false;
|
||||
}
|
||||
|
||||
return ret_decoder;
|
||||
|
||||
@@ -866,17 +866,14 @@ static void inner_rx(PHY_VARS_gNB *gNB,
|
||||
int output_shift,
|
||||
uint32_t nvar,
|
||||
c16_t *rxFext_slot,
|
||||
c16_t *chFext_slot,
|
||||
time_stats_t *pusch_extr,
|
||||
time_stats_t *pusch_ch_comp,
|
||||
time_stats_t *ulsch_llr)
|
||||
c16_t *chFext_slot)
|
||||
{
|
||||
int nb_layer = rel15_ul->nrOfLayers;
|
||||
int nb_rx_ant = frame_parms->nb_antennas_rx;
|
||||
int dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
|
||||
int buffer_length = ceil_mod(rel15_ul->rb_size * NR_NB_SC_PER_RB, 16);
|
||||
c16_t rxFext[nb_rx_ant][buffer_length] __attribute__((aligned(64)));
|
||||
c16_t chFext[nb_layer][nb_rx_ant][buffer_length] __attribute__((aligned(64)));
|
||||
c16_t rxFext[nb_rx_ant][buffer_length] __attribute__((aligned(32)));
|
||||
c16_t chFext[nb_layer][nb_rx_ant][buffer_length] __attribute__((aligned(32)));
|
||||
|
||||
memset(rxFext, 0, sizeof(rxFext));
|
||||
memset(chFext, 0, sizeof(chFext));
|
||||
@@ -890,7 +887,6 @@ static void inner_rx(PHY_VARS_gNB *gNB,
|
||||
|
||||
for (int aarx = 0; aarx < nb_rx_ant; aarx++) {
|
||||
for (int aatx = 0; aatx < nb_layer; aatx++) {
|
||||
start_meas(pusch_extr);
|
||||
nr_ulsch_extract_rbs(rxF[aarx],
|
||||
(c16_t *)pusch_vars->ul_ch_estimates[aatx * nb_rx_ant + aarx],
|
||||
rxFext[aarx],
|
||||
@@ -900,7 +896,6 @@ static void inner_rx(PHY_VARS_gNB *gNB,
|
||||
dmrs_symbol_flag,
|
||||
rel15_ul,
|
||||
frame_parms);
|
||||
stop_meas(pusch_extr);
|
||||
#if T_TRACER
|
||||
// Data Recording application supports only 1 layer and 1 Tx antenna, so only record the first layer and first Tx antenna
|
||||
if (aatx == 0 && aarx == 0) {
|
||||
@@ -916,11 +911,10 @@ static void inner_rx(PHY_VARS_gNB *gNB,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
start_meas(pusch_ch_comp);
|
||||
c16_t rho[nb_layer][nb_layer][buffer_length] __attribute__((aligned(64)));
|
||||
c16_t rxF_ch_maga[nb_layer][buffer_length] __attribute__((aligned(64)));
|
||||
c16_t rxF_ch_magb[nb_layer][buffer_length] __attribute__((aligned(64)));
|
||||
c16_t rxF_ch_magc[nb_layer][buffer_length] __attribute__((aligned(64)));
|
||||
c16_t rho[nb_layer][nb_layer][buffer_length] __attribute__((aligned(32)));
|
||||
c16_t rxF_ch_maga[nb_layer][buffer_length] __attribute__((aligned(32)));
|
||||
c16_t rxF_ch_magb[nb_layer][buffer_length] __attribute__((aligned(32)));
|
||||
c16_t rxF_ch_magc[nb_layer][buffer_length] __attribute__((aligned(32)));
|
||||
|
||||
memset(rho, 0, sizeof(rho));
|
||||
memset(rxF_ch_maga, 0, sizeof(rxF_ch_maga));
|
||||
@@ -942,7 +936,6 @@ static void inner_rx(PHY_VARS_gNB *gNB,
|
||||
rel15_ul,
|
||||
symbol,
|
||||
output_shift);
|
||||
stop_meas(pusch_ch_comp);
|
||||
|
||||
if (nb_layer == 1 && rel15_ul->transform_precoding == transformPrecoder_enabled && rel15_ul->qam_mod_order <= 6) {
|
||||
if (rel15_ul->qam_mod_order > 2)
|
||||
@@ -965,7 +958,7 @@ static void inner_rx(PHY_VARS_gNB *gNB,
|
||||
buffer_length);
|
||||
pusch_vars->ul_valid_re_per_slot[symbol] -= pusch_vars->ptrs_re_per_slot;
|
||||
}
|
||||
start_meas(ulsch_llr);
|
||||
|
||||
if (nb_layer == 2) {
|
||||
if (rel15_ul->qam_mod_order <= 6) {
|
||||
nr_ulsch_compute_ML_llr((c16_t *)&pusch_vars->rxdataF_comp[0][symbol * buffer_length],
|
||||
@@ -1005,7 +998,6 @@ static void inner_rx(PHY_VARS_gNB *gNB,
|
||||
pusch_vars->ul_valid_re_per_slot[symbol],
|
||||
symbol,
|
||||
rel15_ul->qam_mod_order);
|
||||
stop_meas(ulsch_llr);
|
||||
}
|
||||
|
||||
typedef struct puschSymbolProc_s {
|
||||
@@ -1020,11 +1012,6 @@ typedef struct puschSymbolProc_s {
|
||||
int16_t *scramblingSequence;
|
||||
uint32_t nvar;
|
||||
int beam_nb;
|
||||
time_stats_t pusch_extr;
|
||||
time_stats_t pusch_ch_comp;
|
||||
time_stats_t ulsch_llr;
|
||||
time_stats_t ul_demap;
|
||||
time_stats_t ul_unscram;
|
||||
task_ans_t *ans;
|
||||
c16_t *pusch_ch_est_dmrs_interpl_slot_mem;
|
||||
c16_t *rxFext_slot_mem;
|
||||
@@ -1061,14 +1048,10 @@ static void nr_pusch_symbol_processing(void *arg)
|
||||
pusch_vars->log2_maxh,
|
||||
rdata->nvar,
|
||||
rdata->rxFext_slot_mem,
|
||||
rdata->pusch_ch_est_dmrs_interpl_slot_mem,
|
||||
&rdata->pusch_extr,
|
||||
&rdata->pusch_ch_comp,
|
||||
&rdata->ulsch_llr);
|
||||
rdata->pusch_ch_est_dmrs_interpl_slot_mem);
|
||||
|
||||
int nb_re_pusch = pusch_vars->ul_valid_re_per_slot[symbol];
|
||||
// layer de-mapping
|
||||
start_meas(&rdata->ul_demap);
|
||||
int16_t *llr_ptr = llrs[0];
|
||||
if (rel15_ul->nrOfLayers != 1) {
|
||||
llr_ptr = &rdata->llr[pusch_vars->llr_offset[symbol] * rel15_ul->nrOfLayers];
|
||||
@@ -1078,21 +1061,12 @@ static void nr_pusch_symbol_processing(void *arg)
|
||||
llr_ptr[i * rel15_ul->nrOfLayers * rel15_ul->qam_mod_order + l * rel15_ul->qam_mod_order + m] =
|
||||
llrss[l][i * rel15_ul->qam_mod_order + m];
|
||||
}
|
||||
stop_meas(&rdata->ul_demap);
|
||||
// unscrambling
|
||||
start_meas(&rdata->ul_unscram);
|
||||
int16_t *llr16 = (int16_t*)&rdata->llr[pusch_vars->llr_offset[symbol] * rel15_ul->nrOfLayers];
|
||||
int16_t *s = rdata->scramblingSequence + pusch_vars->llr_offset[symbol] * rel15_ul->nrOfLayers;
|
||||
const int end = nb_re_pusch * rel15_ul->qam_mod_order * rel15_ul->nrOfLayers;
|
||||
int i = 0;
|
||||
for (; (i + 8) <= end; i += 8) {
|
||||
simde__m128i llr128 = simde_mm_loadu_si128((simde__m128i *)&llr_ptr[i]);
|
||||
simde__m128i s128 = simde_mm_loadu_si128((simde__m128i *)&s[i]);
|
||||
simde_mm_storeu_si128(llr16 + i, simde_mm_mullo_epi16(llr128, s128));
|
||||
}
|
||||
for (; i < end; i++)
|
||||
for (int i = 0; i < end; i++)
|
||||
llr16[i] = llr_ptr[i] * s[i];
|
||||
stop_meas(&rdata->ul_unscram);
|
||||
}
|
||||
|
||||
// Task running in // completed
|
||||
@@ -1143,13 +1117,13 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
// int nb_layer (= rel15_ul->nrOfLayers) is limited to 1 for data recording application.
|
||||
|
||||
// Initialize memory for DMRS signals
|
||||
c16_t pusch_dmrs_slot_mem[1 * buffer_length_slot] __attribute__((aligned(64)));
|
||||
c16_t pusch_dmrs_slot_mem[1 * buffer_length_slot] __attribute__((aligned(32)));
|
||||
// Initialize memory for channel estimates based on DMRS positions
|
||||
c16_t pusch_ch_est_dmrs_pos_slot_mem[buffer_length_slot * 1 * 1] __attribute__((aligned(64)));
|
||||
c16_t pusch_ch_est_dmrs_pos_slot_mem[buffer_length_slot * 1 * 1] __attribute__((aligned(32)));
|
||||
// memory to store slot grid with channel coefficients based on DMRS positions after interpolation
|
||||
c16_t pusch_ch_est_dmrs_interpl_slot_mem[buffer_length_slot * 1 * 1] __attribute__((aligned(64)));
|
||||
c16_t pusch_ch_est_dmrs_interpl_slot_mem[buffer_length_slot * 1 * 1] __attribute__((aligned(32)));
|
||||
// memory to store extracted data including PUSCH + DMRS
|
||||
c16_t rxFext_slot_mem[1 * buffer_length_slot] __attribute__((aligned(64)));
|
||||
c16_t rxFext_slot_mem[1 * buffer_length_slot] __attribute__((aligned(32)));
|
||||
|
||||
#if T_TRACER
|
||||
// Initialize memory for DMRS signals
|
||||
@@ -1298,7 +1272,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
*ret_unav_res = unav_res;
|
||||
|
||||
// initialize scrambling sequence //
|
||||
int16_t scramblingSequence[G + 96] __attribute__((aligned(64)));
|
||||
int16_t scramblingSequence[G + 96] __attribute__((aligned(32)));
|
||||
|
||||
nr_codeword_unscrambling_init(scramblingSequence, G, 0, rel15_ul->data_scrambling_id, rel15_ul->rnti);
|
||||
|
||||
@@ -1325,13 +1299,12 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
else // average of channel estimates stored in first symbol
|
||||
dmrs_symbol = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, rel15_ul->start_symbol_index, end_symbol);
|
||||
int size_est = nb_re_pusch * frame_parms->symbols_per_slot;
|
||||
__attribute__((aligned(64))) int ul_ch_estimates_ext[rel15_ul->nrOfLayers * frame_parms->nb_antennas_rx][size_est];
|
||||
__attribute__((aligned(32))) int ul_ch_estimates_ext[rel15_ul->nrOfLayers * frame_parms->nb_antennas_rx][size_est];
|
||||
memset(ul_ch_estimates_ext, 0, sizeof(ul_ch_estimates_ext));
|
||||
int buffer_length = rel15_ul->rb_size * NR_NB_SC_PER_RB;
|
||||
c16_t temp_rxFext[frame_parms->nb_antennas_rx][buffer_length] __attribute__((aligned(64)));
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
|
||||
for (int nl = 0; nl < rel15_ul->nrOfLayers; nl++) {
|
||||
start_meas(&gNB->pusch_extraction_stats);
|
||||
c16_t temp_rxFext[frame_parms->nb_antennas_rx][buffer_length] __attribute__((aligned(32)));
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
|
||||
for (int nl = 0; nl < rel15_ul->nrOfLayers; nl++)
|
||||
nr_ulsch_extract_rbs(gNB->common_vars.rxdataF[beam_nb][aarx],
|
||||
(c16_t *)pusch_vars->ul_ch_estimates[nl * frame_parms->nb_antennas_rx + aarx],
|
||||
temp_rxFext[aarx],
|
||||
@@ -1341,8 +1314,6 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
(rel15_ul->ul_dmrs_symb_pos >> meas_symbol) & 0x01,
|
||||
rel15_ul,
|
||||
frame_parms);
|
||||
stop_meas(&gNB->pusch_extraction_stats);
|
||||
}
|
||||
|
||||
uint8_t shift_ch_ext = rel15_ul->nrOfLayers > 1 ? log2_approx(max_ch >> 11) : 0;
|
||||
|
||||
@@ -1422,11 +1393,6 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
rdata->beam_nb = beam_nb;
|
||||
rdata->rxFext_slot_mem = rxFext_slot_mem;
|
||||
rdata->pusch_ch_est_dmrs_interpl_slot_mem = pusch_ch_est_dmrs_interpl_slot_mem;
|
||||
reset_meas(&rdata->pusch_extr);
|
||||
reset_meas(&rdata->pusch_ch_comp);
|
||||
reset_meas(&rdata->ulsch_llr);
|
||||
reset_meas(&rdata->ul_demap);
|
||||
reset_meas(&rdata->ul_unscram);
|
||||
|
||||
if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
nr_pusch_symbol_processing(rdata);
|
||||
@@ -1467,15 +1433,6 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
#endif
|
||||
|
||||
join_task_ans(&ans);
|
||||
for (int i = 0; i < sz_arr; ++i) {
|
||||
// retrieve measurements
|
||||
puschSymbolProc_t *rdata = &arr[i];
|
||||
merge_meas(&gNB->pusch_extraction_stats, &rdata->pusch_extr);
|
||||
merge_meas(&gNB->pusch_channel_compensation_stats, &rdata->pusch_ch_comp);
|
||||
merge_meas(&gNB->ulsch_llr_stats, &rdata->ulsch_llr);
|
||||
merge_meas(&gNB->ulsch_layer_demapping_stats, &rdata->ul_demap);
|
||||
merge_meas(&gNB->ulsch_unscrambling_stats, &rdata->ul_unscram);
|
||||
}
|
||||
stop_meas(&gNB->rx_pusch_symbol_processing_stats);
|
||||
|
||||
// Copy the data to the scope. This cannot be performed in one call to gNBscopeCopy because the data is not contiguous in the
|
||||
|
||||
@@ -31,7 +31,7 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu
|
||||
{
|
||||
NR_gNB_SRS_job_t srs = {.frame = frame, .slot = slot, .srs_pdu = *srs_pdu};
|
||||
if (gNB->common_vars.beam_id) {
|
||||
const uint8_t l0 = srs_pdu->time_start_position; // L2 already sends the absolute symbol index
|
||||
const uint8_t l0 = gNB->frame_parms.symbols_per_slot - 1 - srs_pdu->time_start_position;
|
||||
int bitmap = SL_to_bitmap(l0, 1 << srs_pdu->num_symbols);
|
||||
int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
|
||||
srs.beam_nb = beam_index_allocation(gNB->enable_analog_das,
|
||||
@@ -57,7 +57,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
|
||||
const uint16_t n_symbols = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot; // number of symbols until this slot
|
||||
const uint8_t l0 = srs_pdu->time_start_position; // starting symbol in this slot (L2 sends absolute symbol index)
|
||||
const uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_pdu->time_start_position; // starting symbol in this slot
|
||||
const uint64_t symbol_offset = (n_symbols + l0) * frame_parms->ofdm_symbol_size;
|
||||
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
|
||||
|
||||
|
||||
@@ -1349,94 +1349,127 @@ void nr_pdsch_ptrs_processing(int nbRx,
|
||||
int nl,
|
||||
c16_t rxdataF_comp[][nl][nbRx][rx_size_symbol],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
|
||||
NR_DL_UE_HARQ_t *dlsch0_harq,
|
||||
NR_DL_UE_HARQ_t *dlsch1_harq,
|
||||
uint8_t nr_slot_rx,
|
||||
unsigned char symbol,
|
||||
int nb_rb,
|
||||
uint16_t rnti,
|
||||
uint16_t *ptrsSymbPos,
|
||||
uint8_t *ptrsSymbIdx)
|
||||
NR_UE_DLSCH_t dlsch[2])
|
||||
{
|
||||
//#define DEBUG_DL_PTRS 1
|
||||
int32_t *ptrs_re_symbol = NULL;
|
||||
int8_t ret = 0;
|
||||
/* harq specific variables */
|
||||
int symbInSlot = dlsch_config->start_symbol + dlsch_config->number_symbols;
|
||||
int startSymbIndex = dlsch_config->start_symbol;
|
||||
int nbSymb = dlsch_config->number_symbols;
|
||||
int L_ptrs = dlsch_config->PTRSTimeDensity;
|
||||
int K_ptrs = dlsch_config->PTRSFreqDensity;
|
||||
int dmrsSymbPos = dlsch_config->dlDmrsSymbPos;
|
||||
int ptrsReOffset = dlsch_config->PTRSReOffset;
|
||||
int nscid = dlsch_config->nscid;
|
||||
uint8_t symbInSlot = 0;
|
||||
uint16_t *startSymbIndex = NULL;
|
||||
uint16_t *nbSymb = NULL;
|
||||
uint8_t *L_ptrs = NULL;
|
||||
uint8_t *K_ptrs = NULL;
|
||||
uint16_t *dmrsSymbPos = NULL;
|
||||
uint16_t *ptrsSymbPos = NULL;
|
||||
uint8_t *ptrsSymbIdx = NULL;
|
||||
uint8_t *ptrsReOffset = NULL;
|
||||
int nscid = 0;
|
||||
|
||||
if(dlsch0_harq->status == NR_ACTIVE) {
|
||||
symbInSlot = dlsch[0].dlsch_config.start_symbol + dlsch[0].dlsch_config.number_symbols;
|
||||
startSymbIndex = &dlsch[0].dlsch_config.start_symbol;
|
||||
nbSymb = &dlsch[0].dlsch_config.number_symbols;
|
||||
L_ptrs = &dlsch[0].dlsch_config.PTRSTimeDensity;
|
||||
K_ptrs = &dlsch[0].dlsch_config.PTRSFreqDensity;
|
||||
dmrsSymbPos = &dlsch[0].dlsch_config.dlDmrsSymbPos;
|
||||
ptrsReOffset = &dlsch[0].dlsch_config.PTRSReOffset;
|
||||
ptrsSymbPos = &dlsch[0].ptrs_symbols;
|
||||
ptrsSymbIdx = &dlsch[0].ptrs_symbol_index;
|
||||
nscid = dlsch[0].dlsch_config.nscid;
|
||||
}
|
||||
if(dlsch1_harq) {
|
||||
symbInSlot = dlsch[1].dlsch_config.start_symbol + dlsch[1].dlsch_config.number_symbols;
|
||||
startSymbIndex = &dlsch[1].dlsch_config.start_symbol;
|
||||
nbSymb = &dlsch[1].dlsch_config.number_symbols;
|
||||
L_ptrs = &dlsch[1].dlsch_config.PTRSTimeDensity;
|
||||
K_ptrs = &dlsch[1].dlsch_config.PTRSFreqDensity;
|
||||
dmrsSymbPos = &dlsch[1].dlsch_config.dlDmrsSymbPos;
|
||||
ptrsReOffset = &dlsch[1].dlsch_config.PTRSReOffset;
|
||||
ptrsSymbPos = &dlsch[1].ptrs_symbols;
|
||||
ptrsSymbIdx = &dlsch[1].ptrs_symbol_index;
|
||||
nscid = dlsch[1].dlsch_config.nscid;
|
||||
}
|
||||
/* loop over antennas */
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
c16_t *phase_per_symbol = (c16_t*)ptrs_phase_per_slot[aarx];
|
||||
ptrs_re_symbol = (int32_t*)ptrs_re_per_slot[aarx];
|
||||
ptrs_re_symbol[symbol] = 0;
|
||||
phase_per_symbol[symbol].i = 0; // Imag
|
||||
/* set DMRS estimates to 0 angle with magnitude 1 */
|
||||
if(is_dmrs_symbol(symbol, dmrsSymbPos)) {
|
||||
if(is_dmrs_symbol(symbol,*dmrsSymbPos)) {
|
||||
/* set DMRS real estimation to 32767 */
|
||||
phase_per_symbol[symbol].r=INT16_MAX; // 32767
|
||||
#ifdef DEBUG_DL_PTRS
|
||||
printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[symbol].r,phase_per_symbol[symbol].i);
|
||||
#endif
|
||||
} else { // real ptrs value is set to 0
|
||||
}
|
||||
else { // real ptrs value is set to 0
|
||||
phase_per_symbol[symbol].r = 0; // Real
|
||||
}
|
||||
|
||||
if (symbol == startSymbIndex) {
|
||||
*ptrsSymbPos = 0;
|
||||
set_ptrs_symb_idx(ptrsSymbPos, nbSymb, startSymbIndex, 1 << L_ptrs, dmrsSymbPos);
|
||||
}
|
||||
/* if not PTRS symbol set current ptrs symbol index to zero*/
|
||||
*ptrsSymbIdx = 0;
|
||||
/* Check if current symbol contains PTRS */
|
||||
if (is_ptrs_symbol(symbol, *ptrsSymbPos)) {
|
||||
*ptrsSymbIdx = symbol;
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 1) Estimate common phase error per PTRS symbol */
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
const uint32_t *gold =
|
||||
if(dlsch0_harq->status == NR_ACTIVE) {
|
||||
if(symbol == *startSymbIndex) {
|
||||
*ptrsSymbPos = 0;
|
||||
set_ptrs_symb_idx(ptrsSymbPos,
|
||||
*nbSymb,
|
||||
*startSymbIndex,
|
||||
1<< *L_ptrs,
|
||||
*dmrsSymbPos);
|
||||
}
|
||||
/* if not PTRS symbol set current ptrs symbol index to zero*/
|
||||
*ptrsSymbIdx = 0;
|
||||
/* Check if current symbol contains PTRS */
|
||||
if(is_ptrs_symbol(symbol, *ptrsSymbPos)) {
|
||||
*ptrsSymbIdx = symbol;
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 1) Estimate common phase error per PTRS symbol */
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
const uint32_t *gold =
|
||||
nr_gold_pdsch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, frame_parms->Nid_cell, nscid, nr_slot_rx, symbol);
|
||||
nr_ptrs_cpe_estimation(K_ptrs,
|
||||
ptrsReOffset,
|
||||
nb_rb,
|
||||
rnti,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
rxdataF_comp[symbol][0][aarx],
|
||||
gold,
|
||||
(int16_t *)&phase_per_symbol[symbol],
|
||||
&ptrs_re_symbol[symbol]);
|
||||
}
|
||||
nr_ptrs_cpe_estimation(*K_ptrs,
|
||||
*ptrsReOffset,
|
||||
nb_rb,
|
||||
rnti,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
rxdataF_comp[symbol][0][aarx],
|
||||
gold,
|
||||
(int16_t *)&phase_per_symbol[symbol],
|
||||
&ptrs_re_symbol[symbol]);
|
||||
}
|
||||
}// HARQ 0
|
||||
|
||||
/* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/
|
||||
if (symbol == (symbInSlot -1)) {
|
||||
if(symbol == (symbInSlot -1)) {
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 2) Interpolate PTRS estimated value in TD */
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* If L-PTRS is > 0 then we need interpolation */
|
||||
if (L_ptrs > 0) {
|
||||
ret = nr_ptrs_process_slot(dmrsSymbPos, *ptrsSymbPos, (int16_t*)phase_per_symbol, startSymbIndex, nbSymb);
|
||||
if(*L_ptrs > 0) {
|
||||
ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, (int16_t*)phase_per_symbol, *startSymbIndex, *nbSymb);
|
||||
if(ret != 0) {
|
||||
LOG_W(PHY,"[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n");
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_DL_PTRS
|
||||
LOG_M("ptrsEst.m","est", ptrs_phase_per_slot[aarx], frame_parms->symbols_per_slot, 1, 1);
|
||||
LOG_M("rxdataF_bf_ptrs_comp.m", "bf_ptrs_cmp", rxdataF_comp[0][aarx] + startSymbIndex * rx_size_symbol, rx_size_symbol * nbSymb, 1, 1);
|
||||
LOG_M("ptrsEst.m","est",ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
|
||||
LOG_M("rxdataF_bf_ptrs_comp.m", "bf_ptrs_cmp", rxdataF_comp[0][aarx] + (*startSymbIndex) * rx_size_symbol, rx_size_symbol * (*nbSymb), 1, 1);
|
||||
#endif
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 3) Compensated DMRS based estimated signal with PTRS estimation */
|
||||
/*--------------------------------------------------------------------------------------------------------*/
|
||||
for(uint8_t i = startSymbIndex; i < symbInSlot; i++) {
|
||||
for(uint8_t i = *startSymbIndex; i < symbInSlot; i++) {
|
||||
/* DMRS Symbol has 0 phase so no need to rotate the respective symbol */
|
||||
/* Skip rotation if the slot processing is wrong */
|
||||
if((!is_dmrs_symbol(i, dmrsSymbPos)) && (ret == 0)) {
|
||||
if((!is_dmrs_symbol(i, *dmrsSymbPos)) && (ret == 0)) {
|
||||
#ifdef DEBUG_DL_PTRS
|
||||
printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r, phase_per_symbol[i].i);
|
||||
printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i);
|
||||
#endif
|
||||
rotate_cpx_vector(rxdataF_comp[i][0][aarx], &phase_per_symbol[i], rxdataF_comp[i][0][aarx], nb_rb * NR_NB_SC_PER_RB, 15);
|
||||
}// if not DMRS Symbol
|
||||
|
||||
@@ -121,13 +121,13 @@ void nr_pdsch_ptrs_processing(int nbRx,
|
||||
int nl,
|
||||
c16_t rxdataF_comp[][nl][nbRx][rx_size_symbol],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
|
||||
NR_DL_UE_HARQ_t *dlsch0_harq,
|
||||
NR_DL_UE_HARQ_t *dlsch1_harq,
|
||||
uint8_t nr_slot_rx,
|
||||
unsigned char symbol,
|
||||
int nb_rb,
|
||||
uint16_t rnti,
|
||||
uint16_t *ptrsSymbPos,
|
||||
uint8_t *ptrsSymbIdx);
|
||||
NR_UE_DLSCH_t dlsch[2]);
|
||||
|
||||
int nr_sl_psbch_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
||||
sl_nr_ue_phy_params_t *sl_phy_params,
|
||||
|
||||
@@ -167,7 +167,7 @@ static void send_ssb_rsrp_meas(PHY_VARS_NR_UE *ue,
|
||||
nr_downlink_indication_t dl_indication = {0};
|
||||
fapi_nr_rx_indication_t rx_ind = {0};
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_MEAS_IND, ue, 0, 0, NULL, 1, proc, &l1_measurements, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_MEAS_IND, ue, NULL, NULL, 1, proc, &l1_measurements, NULL);
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
}
|
||||
|
||||
|
||||
@@ -961,6 +961,6 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
|
||||
nr_downlink_indication_t dl_indication;
|
||||
fapi_nr_rx_indication_t rx_ind = {0};
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_MEAS_IND, ue, 0, 0, NULL, 1, proc, (void *)&l1_measurements, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_MEAS_IND, ue, NULL, NULL, 1, proc, (void *)&l1_measurements, NULL);
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
}
|
||||
|
||||
@@ -43,149 +43,177 @@ void nr_dlsch_unscrambling(int16_t *llr, uint32_t size, uint8_t q, uint32_t Nid,
|
||||
void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
NR_UE_DLSCH_t *dlsch,
|
||||
int cw_idx,
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
|
||||
int16_t *dlsch_llr,
|
||||
uint8_t *b,
|
||||
int16_t **dlsch_llr,
|
||||
uint8_t **b,
|
||||
int *G,
|
||||
int nb_dlsch,
|
||||
int number_rbs,
|
||||
int G)
|
||||
uint8_t *DLSCH_ids)
|
||||
{
|
||||
nrLDPC_TB_decoding_parameters_t TB_parameters = {0};
|
||||
nrLDPC_TB_decoding_parameters_t TBs[nb_dlsch];
|
||||
memset(TBs, 0, sizeof(TBs));
|
||||
nrLDPC_slot_decoding_parameters_t slot_parameters = {
|
||||
.frame = proc->frame_rx,
|
||||
.slot = proc->nr_slot_rx,
|
||||
.nb_TBs = 1,
|
||||
.nb_TBs = nb_dlsch,
|
||||
.threadPool = &get_nrUE_params()->Tpool,
|
||||
.TBs = &TB_parameters
|
||||
.TBs = TBs
|
||||
};
|
||||
|
||||
uint8_t dmrs_Type = dlsch_config->dmrsConfigType;
|
||||
int harq_pid = dlsch_config->harq_process_nbr;
|
||||
AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
|
||||
fapi_nr_dl_cw_info_t *cw_info = &dlsch->cw_info;
|
||||
NR_DL_UE_HARQ_t *harq_process = &phy_vars_ue->dl_harq_processes[cw_idx][dlsch_config->harq_process_nbr];
|
||||
LOG_D(PHY, "Round %d RV idx %d\n", harq_process->DLround, cw_info->rv);
|
||||
uint8_t nb_re_dmrs;
|
||||
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
|
||||
nb_re_dmrs = 6 * dlsch_config->n_dmrs_cdm_groups;
|
||||
else
|
||||
nb_re_dmrs = 4 * dlsch_config->n_dmrs_cdm_groups;
|
||||
uint16_t dmrs_length = get_num_dmrs(dlsch_config->dlDmrsSymbPos);
|
||||
int max_num_segments = 0;
|
||||
|
||||
TB_parameters.harq_unique_pid = 2 * harq_pid + cw_idx;
|
||||
TB_parameters.G = G;
|
||||
TB_parameters.nb_rb = number_rbs;
|
||||
TB_parameters.Qm = cw_info->qamModOrder;
|
||||
TB_parameters.mcs = cw_info->mcs;
|
||||
TB_parameters.nb_layers = cw_info->Nl;
|
||||
TB_parameters.BG = cw_info->ldpcBaseGraph;
|
||||
TB_parameters.A = cw_info->TBS;
|
||||
TB_parameters.processedSegments = &harq_process->processedSegments;
|
||||
for (uint8_t pdsch_id = 0; pdsch_id < nb_dlsch; pdsch_id++) {
|
||||
uint8_t DLSCH_id = DLSCH_ids[pdsch_id];
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[DLSCH_id].dlsch_config;
|
||||
uint8_t dmrs_Type = dlsch_config->dmrsConfigType;
|
||||
int harq_pid = dlsch_config->harq_process_nbr;
|
||||
NR_DL_UE_HARQ_t *harq_process = &phy_vars_ue->dl_harq_processes[DLSCH_id][harq_pid];
|
||||
|
||||
float Coderate = (float)cw_info->targetCodeRate / 10240.0f;
|
||||
AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
|
||||
uint8_t nb_re_dmrs;
|
||||
|
||||
LOG_D(PHY,
|
||||
LOG_D(PHY, "Round %d RV idx %d\n", harq_process->DLround, dlsch->dlsch_config.rv);
|
||||
|
||||
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
|
||||
nb_re_dmrs = 6 * dlsch_config->n_dmrs_cdm_groups;
|
||||
else
|
||||
nb_re_dmrs = 4 * dlsch_config->n_dmrs_cdm_groups;
|
||||
uint16_t dmrs_length = get_num_dmrs(dlsch_config->dlDmrsSymbPos);
|
||||
|
||||
if (!harq_process) {
|
||||
LOG_E(PHY, "dlsch_decoding_slot.c: NULL harq_process pointer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pdsch_id];
|
||||
|
||||
/* Neither harq_pid nor DLSCH_id are unique in the instance
|
||||
* but their combination is.
|
||||
* Since DLSCH_id < 2
|
||||
* then 2 * harq_pid + DLSCH_id is unique.
|
||||
*/
|
||||
TB_parameters->harq_unique_pid = 2 * harq_pid + DLSCH_id;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
TB_parameters->G = G[DLSCH_id];
|
||||
TB_parameters->nb_rb = number_rbs;
|
||||
TB_parameters->Qm = dlsch_config->qamModOrder;
|
||||
TB_parameters->mcs = dlsch_config->mcs;
|
||||
TB_parameters->nb_layers = dlsch[DLSCH_id].Nl;
|
||||
TB_parameters->BG = dlsch_config->ldpcBaseGraph;
|
||||
TB_parameters->A = dlsch_config->TBS;
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
TB_parameters->processedSegments = &harq_process->processedSegments;
|
||||
|
||||
float Coderate = (float)dlsch->dlsch_config.targetCodeRate / 10240.0f;
|
||||
|
||||
LOG_D(
|
||||
PHY,
|
||||
"%d.%d DLSCH %d Decoding, harq_pid %d TBS %d G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d Qm %d "
|
||||
"Coderate %f\n",
|
||||
slot_parameters.frame,
|
||||
slot_parameters.slot,
|
||||
cw_idx,
|
||||
DLSCH_id,
|
||||
harq_pid,
|
||||
cw_info->TBS,
|
||||
G,
|
||||
dlsch_config->TBS,
|
||||
TB_parameters->G,
|
||||
nb_re_dmrs,
|
||||
dmrs_length,
|
||||
TB_parameters.mcs,
|
||||
TB_parameters.nb_layers,
|
||||
TB_parameters->mcs,
|
||||
TB_parameters->nb_layers,
|
||||
dlsch_config->number_symbols,
|
||||
TB_parameters.nb_rb,
|
||||
TB_parameters.Qm,
|
||||
TB_parameters->nb_rb,
|
||||
TB_parameters->Qm,
|
||||
Coderate);
|
||||
|
||||
if (harq_process->first_rx == 1) {
|
||||
// This is a new packet, so compute quantities regarding segmentation
|
||||
nr_segmentation(NULL,
|
||||
NULL,
|
||||
lenWithCrc(1, TB_parameters.A), // We give a max size in case of 1 segment
|
||||
&TB_parameters.C,
|
||||
&TB_parameters.K,
|
||||
&TB_parameters.Z, // [hna] Z is Zc
|
||||
&TB_parameters.F,
|
||||
TB_parameters.BG);
|
||||
harq_process->C = TB_parameters.C;
|
||||
harq_process->K = TB_parameters.K;
|
||||
harq_process->Z = TB_parameters.Z;
|
||||
harq_process->F = TB_parameters.F;
|
||||
if (harq_process->first_rx == 1) {
|
||||
// This is a new packet, so compute quantities regarding segmentation
|
||||
nr_segmentation(NULL,
|
||||
NULL,
|
||||
lenWithCrc(1, TB_parameters->A), // We give a max size in case of 1 segment
|
||||
&TB_parameters->C,
|
||||
&TB_parameters->K,
|
||||
&TB_parameters->Z, // [hna] Z is Zc
|
||||
&TB_parameters->F,
|
||||
TB_parameters->BG);
|
||||
harq_process->C = TB_parameters->C;
|
||||
harq_process->K = TB_parameters->K;
|
||||
harq_process->Z = TB_parameters->Z;
|
||||
harq_process->F = TB_parameters->F;
|
||||
|
||||
if (harq_process->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * TB_parameters.nb_layers) {
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, TB_parameters.A);
|
||||
return;
|
||||
if (harq_process->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * TB_parameters->nb_layers) {
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, TB_parameters->A);
|
||||
return;
|
||||
}
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!slot_parameters.frame % 100))
|
||||
LOG_I(PHY, "K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, TB_parameters->nb_layers);
|
||||
// clear HARQ buffer
|
||||
for (int i = 0; i < harq_process->C; i++)
|
||||
memset(harq_process->d[i], 0, 5 * 8448 * sizeof(int16_t));
|
||||
} else {
|
||||
// This is not a new packet, so retrieve previously computed quantities regarding segmentation
|
||||
TB_parameters->C = harq_process->C;
|
||||
TB_parameters->K = harq_process->K;
|
||||
TB_parameters->Z = harq_process->Z;
|
||||
TB_parameters->F = harq_process->F;
|
||||
}
|
||||
max_num_segments = max(max_num_segments, TB_parameters->C);
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!slot_parameters.frame % 100))
|
||||
LOG_I(PHY, "K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, TB_parameters.nb_layers);
|
||||
} else {
|
||||
// This is not a new packet, so retrieve previously computed quantities regarding segmentation
|
||||
TB_parameters.C = harq_process->C;
|
||||
TB_parameters.K = harq_process->K;
|
||||
TB_parameters.Z = harq_process->Z;
|
||||
TB_parameters.F = harq_process->F;
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
LOG_I(PHY, "Segmentation: C %d, K %d\n", harq_process->C, harq_process->K);
|
||||
|
||||
TB_parameters->max_ldpc_iterations = dlsch[DLSCH_id].max_ldpc_iterations;
|
||||
TB_parameters->rv_index = dlsch_config->rv;
|
||||
TB_parameters->tbslbrm = dlsch_config->tbslbrm;
|
||||
TB_parameters->abort_decode = &harq_process->abort_decode;
|
||||
set_abort(&harq_process->abort_decode, false);
|
||||
}
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
LOG_I(PHY, "Segmentation: C %d, K %d\n", harq_process->C, harq_process->K);
|
||||
nrLDPC_segment_decoding_parameters_t segments[nb_dlsch][max_num_segments];
|
||||
memset(segments, 0, sizeof(segments));
|
||||
bool d_to_be_cleared[nb_dlsch][max_num_segments];
|
||||
memset(d_to_be_cleared, 0, sizeof(d_to_be_cleared));
|
||||
|
||||
TB_parameters.max_ldpc_iterations = dlsch->max_ldpc_iterations;
|
||||
TB_parameters.rv_index = cw_info->rv;
|
||||
TB_parameters.tbslbrm = dlsch_config->tbslbrm;
|
||||
TB_parameters.abort_decode = &harq_process->abort_decode;
|
||||
set_abort(&harq_process->abort_decode, false);
|
||||
for (uint8_t pdsch_id = 0; pdsch_id < nb_dlsch; pdsch_id++) {
|
||||
uint8_t DLSCH_id = DLSCH_ids[pdsch_id];
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[DLSCH_id].dlsch_config;
|
||||
int harq_pid = dlsch_config->harq_process_nbr;
|
||||
NR_DL_UE_HARQ_t *harq_process = &phy_vars_ue->dl_harq_processes[DLSCH_id][harq_pid];
|
||||
|
||||
TB_parameters.llr = dlsch_llr;
|
||||
LOG_D(NR_PHY,
|
||||
"Decoding C %d, Qm %d, TB_parameters.llr %p\n",
|
||||
TB_parameters.C,
|
||||
TB_parameters.Qm,
|
||||
TB_parameters.llr);
|
||||
TB_parameters.c = harq_process->c;
|
||||
TB_parameters.d = harq_process->d;
|
||||
TB_parameters.E = nr_get_E(TB_parameters.G, TB_parameters.C, TB_parameters.Qm, TB_parameters.nb_layers, 0);
|
||||
TB_parameters.E2 = TB_parameters.E;
|
||||
TB_parameters.first_rE2 = TB_parameters.C;
|
||||
for (int r = 1; r < TB_parameters.C; r++) {
|
||||
int Er = nr_get_E(TB_parameters.G, TB_parameters.C, TB_parameters.Qm, TB_parameters.nb_layers, r);
|
||||
if (Er != TB_parameters.E) {
|
||||
TB_parameters.E2 = Er;
|
||||
TB_parameters.first_rE2 = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TB_parameters.R = nr_get_R_ldpc_decoder(TB_parameters.rv_index,
|
||||
TB_parameters.E,
|
||||
TB_parameters.BG,
|
||||
TB_parameters.Z,
|
||||
&harq_process->llrLen,
|
||||
harq_process->DLround);
|
||||
TB_parameters.d_to_be_cleared = harq_process->first_rx == 1;
|
||||
for (int r = 0; r < TB_parameters.C; r++)
|
||||
TB_parameters.decodeSuccess[r] = false;
|
||||
reset_meas(&TB_parameters.ts_deinterleave);
|
||||
reset_meas(&TB_parameters.ts_rate_unmatch);
|
||||
reset_meas(&TB_parameters.ts_seg_prep);
|
||||
reset_meas(&TB_parameters.ts_ldpc_decode);
|
||||
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pdsch_id];
|
||||
TB_parameters->segments = segments[pdsch_id];
|
||||
|
||||
for (int r = 0; r < TB_parameters.C; r++) {
|
||||
int Etmp = nr_get_E(TB_parameters.G, TB_parameters.C, TB_parameters.Qm, TB_parameters.nb_layers, r);
|
||||
if (Etmp != TB_parameters.E) {
|
||||
TB_parameters.E2 = Etmp;
|
||||
TB_parameters.R2 = nr_get_R_ldpc_decoder(TB_parameters.rv_index,
|
||||
TB_parameters.E2,
|
||||
TB_parameters.BG,
|
||||
TB_parameters.Z,
|
||||
&harq_process->llrLen,
|
||||
harq_process->DLround);
|
||||
TB_parameters.first_rE2 = r;
|
||||
break;
|
||||
uint32_t r_offset = 0;
|
||||
for (int r = 0; r < TB_parameters->C; r++) {
|
||||
if (harq_process->first_rx == 1)
|
||||
d_to_be_cleared[pdsch_id][r] = true;
|
||||
else
|
||||
d_to_be_cleared[pdsch_id][r] = false;
|
||||
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
|
||||
segment_parameters->E = nr_get_E(TB_parameters->G,
|
||||
TB_parameters->C,
|
||||
TB_parameters->Qm,
|
||||
TB_parameters->nb_layers,
|
||||
r);
|
||||
segment_parameters->R = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
|
||||
segment_parameters->E,
|
||||
TB_parameters->BG,
|
||||
TB_parameters->Z,
|
||||
&harq_process->llrLen,
|
||||
harq_process->DLround);
|
||||
segment_parameters->llr = dlsch_llr[DLSCH_id] + r_offset;
|
||||
segment_parameters->d = harq_process->d[r];
|
||||
segment_parameters->d_to_be_cleared = &d_to_be_cleared[pdsch_id][r];
|
||||
segment_parameters->c = harq_process->c[r];
|
||||
segment_parameters->decodeSuccess = false;
|
||||
|
||||
reset_meas(&segment_parameters->ts_deinterleave);
|
||||
reset_meas(&segment_parameters->ts_rate_unmatch);
|
||||
reset_meas(&segment_parameters->ts_ldpc_decode);
|
||||
|
||||
r_offset += segment_parameters->E;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,104 +224,114 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t offset = 0, r_offset = 0;
|
||||
bool crcok = true;
|
||||
for (int r = 0; r < TB_parameters.C; r++)
|
||||
if (TB_parameters.decodeSuccess[r] == false) {
|
||||
LOG_D(PHY, "downlink segment error %d/%d\n", r, harq_process->C);
|
||||
crcok = false;
|
||||
break;
|
||||
}
|
||||
if (crcok) {
|
||||
for (int r = 0; r < TB_parameters.C; r++) {
|
||||
memcpy(b + offset,
|
||||
harq_process->c + r_offset,
|
||||
(harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
// post decode
|
||||
for (uint8_t pdsch_id = 0; pdsch_id < nb_dlsch; pdsch_id++) {
|
||||
uint8_t DLSCH_id = DLSCH_ids[pdsch_id];
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[DLSCH_id].dlsch_config;
|
||||
int harq_pid = dlsch_config->harq_process_nbr;
|
||||
NR_DL_UE_HARQ_t *harq_process = &phy_vars_ue->dl_harq_processes[DLSCH_id][harq_pid];
|
||||
|
||||
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pdsch_id];
|
||||
|
||||
uint32_t offset = 0;
|
||||
for (int r = 0; r < TB_parameters->C; r++) {
|
||||
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
|
||||
if (segment_parameters->decodeSuccess) {
|
||||
memcpy(b[DLSCH_id] + offset,
|
||||
harq_process->c[r],
|
||||
(harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
} else {
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[DLSCH_id].dlsch_config;
|
||||
LOG_D(PHY, "frame=%d, slot=%d, first_rx=%d, rv_index=%d\n", proc->frame_rx, proc->nr_slot_rx, harq_process->first_rx, dlsch_config->rv);
|
||||
LOG_D(PHY, "downlink segment error %d/%d\n", r, harq_process->C);
|
||||
LOG_D(PHY, "DLSCH %d in error\n", DLSCH_id);
|
||||
}
|
||||
offset += (harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0);
|
||||
r_offset += (harq_process->K >> 3);
|
||||
|
||||
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_DEINTERLEAVING_STATS], &segment_parameters->ts_deinterleave);
|
||||
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_RATE_UNMATCHING_STATS], &segment_parameters->ts_rate_unmatch);
|
||||
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_LDPC_DECODING_STATS], &segment_parameters->ts_ldpc_decode);
|
||||
|
||||
}
|
||||
} else {
|
||||
LOG_D(PHY, "frame=%d, slot=%d, first_rx=%d, rv_index=%d\n", proc->frame_rx, proc->nr_slot_rx, harq_process->first_rx, cw_info->rv);
|
||||
}
|
||||
|
||||
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_DEINTERLEAVING_STATS], &TB_parameters.ts_deinterleave);
|
||||
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_RATE_UNMATCHING_STATS], &TB_parameters.ts_rate_unmatch);
|
||||
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_LDPC_DECODING_STATS], &TB_parameters.ts_ldpc_decode);
|
||||
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_SEG_PREP_STATS], &TB_parameters.ts_seg_prep);
|
||||
kpiStructure.nb_total++;
|
||||
kpiStructure.blockSize = dlsch_config->TBS;
|
||||
kpiStructure.dl_mcs = dlsch_config->mcs;
|
||||
kpiStructure.nofRBs = number_rbs;
|
||||
|
||||
kpiStructure.nb_total++;
|
||||
kpiStructure.blockSize = cw_info->TBS;
|
||||
kpiStructure.dl_mcs = cw_info->mcs;
|
||||
kpiStructure.nofRBs = number_rbs;
|
||||
harq_process->decodeResult = harq_process->processedSegments == harq_process->C;
|
||||
|
||||
harq_process->decodeResult = harq_process->processedSegments == harq_process->C;
|
||||
|
||||
if (harq_process->decodeResult && harq_process->C > 1) {
|
||||
/* check global CRC */
|
||||
// we have regrouped the transport block
|
||||
if (!check_crc(b, lenWithCrc(1, cw_info->TBS), crcType(1, cw_info->TBS))) {
|
||||
LOG_E(PHY,
|
||||
" Frame %d.%d LDPC global CRC fails, but individual LDPC CRC succeeded. %d segs\n",
|
||||
proc->frame_rx,
|
||||
proc->nr_slot_rx,
|
||||
harq_process->C);
|
||||
harq_process->decodeResult = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (harq_process->decodeResult) {
|
||||
// We search only a reccuring OAI error that propagates all 0 packets with a 0 CRC, so we
|
||||
const int sz = cw_info->TBS / 8;
|
||||
if (b[sz] == 0 && b[sz + 1] == 0) {
|
||||
// do the check only if the 2 first bytes of the CRC are 0 (it can be CRC16 or CRC24)
|
||||
int i = 0;
|
||||
while (b[i] == 0 && i < sz)
|
||||
i++;
|
||||
if (i == sz) {
|
||||
if (harq_process->decodeResult && harq_process->C > 1) {
|
||||
/* check global CRC */
|
||||
int A = dlsch->dlsch_config.TBS;
|
||||
// we have regrouped the transport block
|
||||
if (!check_crc(b[DLSCH_id], lenWithCrc(1, A), crcType(1, A))) {
|
||||
LOG_E(PHY,
|
||||
"received all 0 pdu (TBS %d, mcs %d, C %d, nb_rb %d, decodedSegments %d) consider it false reception, even if the "
|
||||
"TS 38.212 7.2.1 says only we should attach the "
|
||||
"corresponding CRC, and nothing prevents to have a all 0 packet\n",
|
||||
cw_info->TBS,
|
||||
cw_info->mcs,
|
||||
harq_process->C,
|
||||
number_rbs,
|
||||
harq_process->processedSegments);
|
||||
" Frame %d.%d LDPC global CRC fails, but individual LDPC CRC succeeded. %d segs\n",
|
||||
proc->frame_rx,
|
||||
proc->nr_slot_rx,
|
||||
harq_process->C);
|
||||
harq_process->decodeResult = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (harq_process->decodeResult) {
|
||||
// We search only a reccuring OAI error that propagates all 0 packets with a 0 CRC, so we
|
||||
const int sz = dlsch->dlsch_config.TBS / 8;
|
||||
if (b[DLSCH_id][sz] == 0 && b[DLSCH_id][sz + 1] == 0) {
|
||||
// do the check only if the 2 first bytes of the CRC are 0 (it can be CRC16 or CRC24)
|
||||
int i = 0;
|
||||
while (b[DLSCH_id][i] == 0 && i < sz)
|
||||
i++;
|
||||
if (i == sz) {
|
||||
LOG_E(PHY,
|
||||
"received all 0 pdu, consider it false reception, even if the TS 38.212 7.2.1 says only we should attach the "
|
||||
"corresponding CRC, and nothing prevents to have a all 0 packet\n");
|
||||
harq_process->decodeResult = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (harq_process->decodeResult) {
|
||||
LOG_D(PHY, "DLSCH received ok \n");
|
||||
harq_process->status = NR_SCH_IDLE;
|
||||
dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations - 1;
|
||||
} else {
|
||||
LOG_D(PHY, "DLSCH received nok \n");
|
||||
kpiStructure.nb_nack++;
|
||||
dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations;
|
||||
UEdumpScopeData(phy_vars_ue, proc->nr_slot_rx, proc->frame_rx, "DLSCH_NACK");
|
||||
}
|
||||
|
||||
uint8_t dmrs_Type = dlsch_config->dmrsConfigType;
|
||||
uint8_t nb_re_dmrs;
|
||||
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
|
||||
nb_re_dmrs = 6 * dlsch_config->n_dmrs_cdm_groups;
|
||||
else
|
||||
nb_re_dmrs = 4 * dlsch_config->n_dmrs_cdm_groups;
|
||||
uint16_t dmrs_length = get_num_dmrs(dlsch_config->dlDmrsSymbPos);
|
||||
float Coderate = (float)dlsch->dlsch_config.targetCodeRate / 10240.0f;
|
||||
LOG_D(PHY,
|
||||
"%d.%d DLSCH Decoded, harq_pid %d, round %d, result: %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d "
|
||||
"nb_symb_sch %d "
|
||||
"nb_rb %d Qm %d Coderate %f\n",
|
||||
proc->frame_rx,
|
||||
proc->nr_slot_rx,
|
||||
harq_pid,
|
||||
harq_process->DLround,
|
||||
harq_process->decodeResult,
|
||||
dlsch->dlsch_config.TBS,
|
||||
dlsch->dlsch_config.TBS / 8,
|
||||
G[DLSCH_id],
|
||||
nb_re_dmrs,
|
||||
dmrs_length,
|
||||
dlsch->dlsch_config.mcs,
|
||||
dlsch->Nl,
|
||||
dlsch_config->number_symbols,
|
||||
number_rbs,
|
||||
dlsch_config->qamModOrder,
|
||||
Coderate);
|
||||
|
||||
}
|
||||
|
||||
if (harq_process->decodeResult) {
|
||||
LOG_D(PHY, "%d.%d DLSCH received ok \n", proc->frame_rx, proc->nr_slot_rx);
|
||||
harq_process->status = NR_SCH_IDLE;
|
||||
dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations - 1;
|
||||
} else {
|
||||
LOG_D(PHY, "%d.%d DLSCH received nok \n", proc->frame_rx, proc->nr_slot_rx);
|
||||
kpiStructure.nb_nack++;
|
||||
dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations;
|
||||
UEdumpScopeData(phy_vars_ue, proc->nr_slot_rx, proc->frame_rx, "DLSCH_NACK");
|
||||
}
|
||||
|
||||
LOG_D(PHY,
|
||||
"%d.%d DLSCH Decoded, harq_pid %d, cw_idx %d round %d, result: %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d "
|
||||
"nb_symb_sch %d "
|
||||
"nb_rb %d Qm %d Coderate %f\n",
|
||||
proc->frame_rx,
|
||||
proc->nr_slot_rx,
|
||||
harq_pid,
|
||||
cw_idx,
|
||||
harq_process->DLround,
|
||||
harq_process->decodeResult,
|
||||
cw_info->TBS,
|
||||
cw_info->TBS / 8,
|
||||
G,
|
||||
nb_re_dmrs,
|
||||
dmrs_length,
|
||||
cw_info->mcs,
|
||||
cw_info->Nl,
|
||||
dlsch_config->number_symbols,
|
||||
number_rbs,
|
||||
cw_info->qamModOrder,
|
||||
Coderate);
|
||||
}
|
||||
|
||||
@@ -856,12 +856,12 @@ static void nr_dlsch_layer_demapping(const uint8_t Nl,
|
||||
const uint8_t mod_order,
|
||||
const int llrLayerSize,
|
||||
const int16_t llr_layers[NR_SYMBOLS_PER_SLOT][Nl][llrLayerSize],
|
||||
const fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
|
||||
const NR_UE_DLSCH_t *dlsch,
|
||||
const uint32_t re_len[NR_SYMBOLS_PER_SLOT],
|
||||
int16_t *llr)
|
||||
{
|
||||
const int s0 = dlsch_config->start_symbol;
|
||||
const int s1 = dlsch_config->number_symbols;
|
||||
const int s0 = dlsch->dlsch_config.start_symbol;
|
||||
const int s1 = dlsch->dlsch_config.number_symbols;
|
||||
|
||||
int k = 0;
|
||||
switch (Nl) {
|
||||
@@ -901,28 +901,28 @@ static int nr_dlsch_llr(const NR_UE_DLSCH_t *dlsch,
|
||||
const c16_t dl_ch_magb[rx_size_symbol],
|
||||
const c16_t dl_ch_magr[rx_size_symbol],
|
||||
const int nb_antennas_rx,
|
||||
const c16_t rxdataF_comp[dlsch->cw_info.Nl][nb_antennas_rx][rx_size_symbol],
|
||||
const c16_t rxdataF_comp[dlsch->Nl][nb_antennas_rx][rx_size_symbol],
|
||||
const int llrSize,
|
||||
int16_t layer_llr[dlsch->cw_info.Nl][llrSize])
|
||||
int16_t layer_llr[dlsch->Nl][llrSize])
|
||||
{
|
||||
switch (dlsch->cw_info.qamModOrder) {
|
||||
switch (dlsch->dlsch_config.qamModOrder) {
|
||||
case 2 :
|
||||
for (int l = 0; l < dlsch->cw_info.Nl; l++)
|
||||
for (int l = 0; l < dlsch[0].Nl; l++)
|
||||
nr_qpsk_llr(rxdataF_comp[l][0], layer_llr[l], len);
|
||||
break;
|
||||
|
||||
case 4 :
|
||||
for (int l = 0; l < dlsch->cw_info.Nl; l++)
|
||||
for (int l = 0; l < dlsch[0].Nl; l++)
|
||||
nr_16qam_llr(rxdataF_comp[l][0], dl_ch_mag, layer_llr[l], len);
|
||||
break;
|
||||
|
||||
case 6 :
|
||||
for(int l=0; l < dlsch->cw_info.Nl; l++)
|
||||
for(int l=0; l < dlsch[0].Nl; l++)
|
||||
nr_64qam_llr(rxdataF_comp[l][0], dl_ch_mag, dl_ch_magb, layer_llr[l], len);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
for(int l=0; l < dlsch->cw_info.Nl; l++)
|
||||
for(int l=0; l < dlsch[0].Nl; l++)
|
||||
nr_256qam_llr(rxdataF_comp[l][0],
|
||||
dl_ch_mag,
|
||||
dl_ch_magb,
|
||||
@@ -943,32 +943,30 @@ static int nr_dlsch_llr(const NR_UE_DLSCH_t *dlsch,
|
||||
/* Main Function */
|
||||
int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
NR_UE_DLSCH_t *dlsch,
|
||||
NR_UE_DLSCH_t dlsch[2],
|
||||
const freq_alloc_bitmap_t *freq_alloc,
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
|
||||
NR_DL_UE_HARQ_t *dlsch_harq,
|
||||
unsigned char symbol,
|
||||
bool first_symbol_flag,
|
||||
unsigned char harq_pid,
|
||||
uint32_t pdsch_est_size,
|
||||
int32_t dl_ch_estimates[][pdsch_est_size],
|
||||
int16_t *llr,
|
||||
int16_t *llr[2],
|
||||
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
|
||||
int32_t *log2_maxh,
|
||||
int rx_size_symbol,
|
||||
int nbRx,
|
||||
c16_t rxdataF_comp[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_mag[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_magb[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_magr[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
|
||||
c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_mag[][dlsch->Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_magb[][dlsch->Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_magr[][dlsch->Nl][nbRx][rx_size_symbol],
|
||||
c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
|
||||
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
|
||||
uint32_t nvar,
|
||||
pdsch_scope_req_t *scope_req)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
const int nl = dlsch->cw_info.Nl;
|
||||
const int nl = dlsch[0].Nl;
|
||||
const int n_rx = fp->nb_antennas_rx;
|
||||
const int matrixSz = n_rx * nl;
|
||||
__attribute__((aligned(32))) int32_t dl_ch_estimates_ext[matrixSz][rx_size_symbol];
|
||||
@@ -980,8 +978,72 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
const int gNB_id = proc->gNB_id;
|
||||
uint8_t slot = 0;
|
||||
|
||||
int32_t codeword_TB0 = -1;
|
||||
int32_t codeword_TB1 = -1;
|
||||
|
||||
uint32_t nb_re_pdsch = -1;
|
||||
DevAssert(dlsch_harq);
|
||||
|
||||
NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
|
||||
dlsch0_harq = &ue->dl_harq_processes[0][harq_pid];
|
||||
if (NR_MAX_NB_LAYERS > 4)
|
||||
dlsch1_harq = &ue->dl_harq_processes[1][harq_pid];
|
||||
|
||||
if (dlsch0_harq && dlsch1_harq){
|
||||
|
||||
LOG_D(PHY,
|
||||
"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n",
|
||||
frame,
|
||||
nr_slot_rx,
|
||||
symbol,
|
||||
harq_pid,
|
||||
dlsch0_harq->status,
|
||||
dlsch1_harq->status);
|
||||
|
||||
if ((dlsch0_harq->status == NR_ACTIVE) && (dlsch1_harq->status == NR_ACTIVE)){
|
||||
codeword_TB0 = dlsch0_harq->codeword; // SV: where is this set? revisit for DL MIMO.
|
||||
codeword_TB1 = dlsch1_harq->codeword;
|
||||
dlsch0_harq = &ue->dl_harq_processes[codeword_TB0][harq_pid];
|
||||
dlsch1_harq = &ue->dl_harq_processes[codeword_TB1][harq_pid];
|
||||
|
||||
DEBUG_HARQ("[DEMOD] I am assuming both TBs are active, in cw0 %d and cw1 %d \n", codeword_TB0, codeword_TB1);
|
||||
|
||||
} else if ((dlsch0_harq->status == NR_ACTIVE) && (dlsch1_harq->status != NR_ACTIVE) ) {
|
||||
codeword_TB0 = dlsch0_harq->codeword;
|
||||
dlsch0_harq = &ue->dl_harq_processes[codeword_TB0][harq_pid];
|
||||
dlsch1_harq = NULL;
|
||||
|
||||
DEBUG_HARQ("[DEMOD] I am assuming only TB0 is active, in cw %d \n", codeword_TB0);
|
||||
|
||||
} else if ((dlsch0_harq->status != NR_ACTIVE) && (dlsch1_harq->status == NR_ACTIVE)){
|
||||
codeword_TB1 = dlsch1_harq->codeword;
|
||||
dlsch0_harq = NULL;
|
||||
dlsch1_harq = &ue->dl_harq_processes[codeword_TB1][harq_pid];
|
||||
|
||||
DEBUG_HARQ("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", codeword_TB1);
|
||||
LOG_E(PHY, "[DEMOD] slot %d TB0 not active and TB1 active case is not supported\n", nr_slot_rx);
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
LOG_E(PHY, "[DEMOD] slot %d: no active DLSCH (2 layers case)\n", nr_slot_rx);
|
||||
return (-1);
|
||||
}
|
||||
} else if (dlsch0_harq) {
|
||||
if (dlsch0_harq->status == NR_ACTIVE) {
|
||||
codeword_TB0 = dlsch0_harq->codeword;
|
||||
dlsch0_harq = &ue->dl_harq_processes[0][harq_pid];
|
||||
DEBUG_HARQ("[DEMOD] I am assuming only TB0 is active\n");
|
||||
} else {
|
||||
LOG_E(PHY, "[DEMOD] slot %d nr_rx_pdsch no active DLSCH (one layer case)\n", nr_slot_rx);
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
LOG_E(PHY, "[DEMOD] slot %d Inconsistent call to nr_rx_pdsch (no layer 0)\n", nr_slot_rx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG_HARQ("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[0].dlsch_config;
|
||||
DevAssert(dlsch0_harq);
|
||||
|
||||
if (gNB_id > 2) {
|
||||
LOG_E(PHY, "Illegal gNB_id %d\n", gNB_id);
|
||||
@@ -1166,7 +1228,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
fp,
|
||||
symbol,
|
||||
nb_re_pdsch,
|
||||
dlsch->cw_info.qamModOrder,
|
||||
dlsch_config->qamModOrder,
|
||||
nb_rb_pdsch,
|
||||
*log2_maxh); // log2_maxh+I0_shift
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_COMPENSATION_STATS);
|
||||
@@ -1223,7 +1285,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
dl_ch_magb[symbol],
|
||||
dl_ch_magr[symbol],
|
||||
dl_ch_estimates_ext,
|
||||
dlsch->cw_info.qamModOrder,
|
||||
dlsch_config->qamModOrder,
|
||||
*log2_maxh,
|
||||
symbol,
|
||||
nb_re_pdsch,
|
||||
@@ -1249,14 +1311,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
int nbSymb = 0;
|
||||
int pduBitmap = 0;
|
||||
|
||||
if(dlsch_harq->status == NR_ACTIVE) {
|
||||
if(dlsch0_harq->status == NR_ACTIVE) {
|
||||
startSymbIdx = dlsch_config->start_symbol;
|
||||
nbSymb = dlsch_config->number_symbols;
|
||||
pduBitmap = dlsch_config->pduBitmap;
|
||||
}
|
||||
|
||||
/* Check for PTRS bitmap and process it respectively */
|
||||
if((pduBitmap & 0x1) && (dlsch->rnti_type == TYPE_C_RNTI_)) {
|
||||
if((pduBitmap & 0x1) && (dlsch[0].rnti_type == TYPE_C_RNTI_)) {
|
||||
nr_pdsch_ptrs_processing(nbRx,
|
||||
ptrs_phase_per_slot,
|
||||
ptrs_re_per_slot,
|
||||
@@ -1264,13 +1326,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
nl,
|
||||
rxdataF_comp,
|
||||
fp,
|
||||
dlsch_config,
|
||||
dlsch0_harq,
|
||||
dlsch1_harq,
|
||||
nr_slot_rx,
|
||||
symbol,
|
||||
freq_alloc->num_rbs,
|
||||
dlsch->rnti,
|
||||
&dlsch->ptrs_symbols,
|
||||
&dlsch->ptrs_symbol_index);
|
||||
dlsch[0].rnti,
|
||||
dlsch);
|
||||
dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol];
|
||||
}
|
||||
/* at last symbol in a slot calculate LLR's for whole slot */
|
||||
@@ -1278,7 +1340,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
/* create LLR layer buffer */
|
||||
int max_symb_re = 0;
|
||||
GET_ARRAY_MAX(dl_valid_re, NR_SYMBOLS_PER_SLOT, max_symb_re);
|
||||
const int llr_per_symbol = max_symb_re * dlsch->cw_info.qamModOrder;
|
||||
const int llr_per_symbol = max_symb_re * dlsch->dlsch_config.qamModOrder;
|
||||
__attribute__((aligned(32))) int16_t layer_llr[NR_SYMBOLS_PER_SLOT][nl][llr_per_symbol];
|
||||
|
||||
// Generate LLR from PTRS compensated signal
|
||||
@@ -1297,9 +1359,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS);
|
||||
start_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING);
|
||||
nr_dlsch_layer_demapping(nl, dlsch->cw_info.qamModOrder, llr_per_symbol, layer_llr, dlsch_config, dl_valid_re, llr);
|
||||
nr_dlsch_layer_demapping(nl, dlsch_config->qamModOrder, llr_per_symbol, layer_llr, dlsch, dl_valid_re, llr[0]);
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING);
|
||||
|
||||
/*
|
||||
for (int i=0; i < 2; i++){
|
||||
snprintf(filename, 50, "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx);
|
||||
write_output(filename,"llr", &llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0);
|
||||
}
|
||||
*/
|
||||
if (UEScopeHasTryLock(ue)) {
|
||||
metadata mt = {.frame = proc->frame_rx, .slot = proc->nr_slot_rx };
|
||||
int total_valid_res = 0;
|
||||
|
||||
@@ -452,8 +452,7 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
nr_fill_rx_indication(&rx_ind,
|
||||
FAPI_NR_RX_PDU_TYPE_SSB,
|
||||
ue,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
number_pdus,
|
||||
proc,
|
||||
|
||||
@@ -405,7 +405,7 @@ int nr_pbch_decode(PHY_VARS_NR_UE *ue,
|
||||
if (decoderState) {
|
||||
if (ue) { // decoding failed in synced state
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, 0, 0, NULL, number_pdus, proc, NULL, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, NULL, NULL);
|
||||
if (ue->if_inst && ue->if_inst->dl_indication)
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
}
|
||||
@@ -465,7 +465,7 @@ int nr_pbch_decode(PHY_VARS_NR_UE *ue,
|
||||
|
||||
if (ue) {
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, 0, 0, NULL, number_pdus, proc, (void *)result, NULL);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, (void *)result, NULL);
|
||||
|
||||
if (ue->if_inst && ue->if_inst->dl_indication)
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
|
||||
@@ -61,17 +61,19 @@ int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int nb_symb
|
||||
@param[in] dlsch_llr Pointers to LLR values computed by dlsch_demodulation
|
||||
@param[in] b
|
||||
@param[in] G array of Gs
|
||||
@param[in] nb_dlsch number of active downlink shared channels
|
||||
@param[in] DLSCH_ids array of active downlink shared channels
|
||||
@returns 0 on success, 1 on unsuccessful decoding
|
||||
*/
|
||||
void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
NR_UE_DLSCH_t *dlsch,
|
||||
int cw_idx,
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
|
||||
int16_t *dlsch_llr,
|
||||
uint8_t *b,
|
||||
short **dlsch_llr,
|
||||
uint8_t **b,
|
||||
int *G,
|
||||
int nb_dlsch,
|
||||
int number_rbs,
|
||||
int G);
|
||||
uint8_t *DLSCH_ids);
|
||||
|
||||
int nr_ulsch_pre_encoding(PHY_VARS_NR_UE *ue,
|
||||
const NR_UE_ULSCH_t *ulsch,
|
||||
@@ -261,25 +263,23 @@ void nr_sl_rf_card_config_freq(PHY_VARS_NR_UE *ue,
|
||||
*/
|
||||
int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
NR_UE_DLSCH_t *dlsch,
|
||||
NR_UE_DLSCH_t dlsch[2],
|
||||
const freq_alloc_bitmap_t *freq_alloc,
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
|
||||
NR_DL_UE_HARQ_t *dlsch_harq,
|
||||
unsigned char symbol,
|
||||
bool first_symbol_flag,
|
||||
unsigned char harq_pid,
|
||||
uint32_t pdsch_est_size,
|
||||
int32_t dl_ch_estimates[][pdsch_est_size],
|
||||
int16_t *llr,
|
||||
int16_t *llr[2],
|
||||
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
|
||||
int32_t *log2_maxh,
|
||||
int rx_size_symbol,
|
||||
int nbRx,
|
||||
c16_t rxdataF_comp[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_mag[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_magb[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_magr[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
|
||||
c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_mag[][dlsch->Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_magb[][dlsch->Nl][nbRx][rx_size_symbol],
|
||||
c16_t dl_ch_magr[][dlsch->Nl][nbRx][rx_size_symbol],
|
||||
c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
|
||||
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
|
||||
uint32_t nvar,
|
||||
|
||||
@@ -69,11 +69,11 @@ typedef struct {
|
||||
NR_SCH_status_t status;
|
||||
/// Pointer to the payload (38.212 V15.4.0 section 5.1)
|
||||
uint8_t *b;
|
||||
/// Pointer to transport block segments
|
||||
uint8_t *c;
|
||||
/// Pointers to transport block segments
|
||||
uint8_t **c;
|
||||
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||
/// Accumulates the soft bits for each round to increase decoding success (HARQ)
|
||||
int16_t *d;
|
||||
int16_t **d;
|
||||
/// Index of current HARQ round for this DLSCH
|
||||
uint8_t DLround;
|
||||
/// Number of code segments
|
||||
@@ -97,13 +97,16 @@ typedef struct {
|
||||
} NR_DL_UE_HARQ_t;
|
||||
|
||||
typedef struct {
|
||||
fapi_nr_dl_cw_info_t cw_info;
|
||||
/// RNTI
|
||||
uint16_t rnti;
|
||||
/// RNTI type
|
||||
uint8_t rnti_type;
|
||||
/// Active flag for DLSCH demodulation
|
||||
bool active;
|
||||
/// Structure to hold dlsch config from MAC
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config;
|
||||
/// Number of MIMO layers (streams)
|
||||
uint8_t Nl;
|
||||
/// Maximum number of LDPC iterations
|
||||
uint8_t max_ldpc_iterations;
|
||||
/// number of iterations used in last turbo decoding
|
||||
|
||||
@@ -48,19 +48,19 @@ target_link_libraries(benchmark_channel_pipeline PRIVATE UTIL SIMU PHY_COMMON LO
|
||||
add_executable(test_channel_pipeline test_channel_pipeline.cpp test_channel_pipeline_tools.c)
|
||||
target_link_libraries(test_channel_pipeline PRIVATE UTIL SIMU PHY_COMMON LOG CONFIG_LIB shlib_loader m channel_pipeline GTest::gtest thread-pool)
|
||||
|
||||
if (ENABLE_CHANNEL_SIM_CUDA)
|
||||
target_compile_definitions(test_channel_pipeline PRIVATE CHANNEL_SIM_CUDA)
|
||||
if (CUDA_ENABLE)
|
||||
target_compile_definitions(test_channel_pipeline PRIVATE CUDA_ENABLE)
|
||||
add_dependencies(tests test_channel_pipeline)
|
||||
add_test(NAME test_channel_pipeline COMMAND test_channel_pipeline)
|
||||
set_tests_properties(test_channel_pipeline PROPERTIES LABELS "cuda")
|
||||
|
||||
target_compile_definitions(benchmark_channel_pipeline PRIVATE CHANNEL_SIM_CUDA)
|
||||
target_compile_definitions(benchmark_channel_pipeline PRIVATE CUDA_ENABLE)
|
||||
add_dependencies(tests benchmark_channel_pipeline)
|
||||
add_test(NAME benchmark_channel_pipeline COMMAND benchmark_channel_pipeline)
|
||||
set_tests_properties(benchmark_channel_pipeline PROPERTIES LABELS "cuda")
|
||||
endif()
|
||||
|
||||
if (ENABLE_CHANNEL_SIM_CUDA)
|
||||
if(CUDA_ENABLE)
|
||||
add_executable(test_multipath test_multipath.c)
|
||||
target_link_libraries(test_multipath PRIVATE UTIL SIMU LOG CONFIG_LIB shlib_loader m oai_cuda_lib)
|
||||
|
||||
@@ -88,9 +88,9 @@ add_dependencies(tests test_channel_scalability)
|
||||
add_test(NAME test_channel_scalability COMMAND test_channel_scalability)
|
||||
|
||||
if (TARGET oai_cuda_lib)
|
||||
target_compile_definitions(test_multipath PRIVATE CHANNEL_SIM_CUDA)
|
||||
target_compile_definitions(test_noise PRIVATE CHANNEL_SIM_CUDA)
|
||||
target_compile_definitions(test_channel_simulation PRIVATE CHANNEL_SIM_CUDA)
|
||||
target_compile_definitions(test_channel_scalability PRIVATE CHANNEL_SIM_CUDA)
|
||||
target_compile_definitions(test_multipath PRIVATE ENABLE_CUDA)
|
||||
target_compile_definitions(test_noise PRIVATE ENABLE_CUDA)
|
||||
target_compile_definitions(test_channel_simulation PRIVATE ENABLE_CUDA)
|
||||
target_compile_definitions(test_channel_scalability PRIVATE ENABLE_CUDA)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -25,7 +25,7 @@ extern "C" void exit_function(const char *file, const char *function, const int
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifdef CHANNEL_SIM_CUDA
|
||||
#ifdef CUDA_ENABLE
|
||||
static void BM_channel_convolution_gpu(benchmark::State &state)
|
||||
{
|
||||
int nb_rx = state.range(0);
|
||||
@@ -203,7 +203,7 @@ static void BM_channel_convolution_tpool(benchmark::State &state)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CHANNEL_SIM_CUDA
|
||||
#ifdef CUDA_ENABLE
|
||||
BENCHMARK(BM_channel_convolution_gpu)
|
||||
->ArgsProduct({
|
||||
{1, 2, 4, 16, 64}, // nb_rx
|
||||
|
||||
@@ -26,7 +26,7 @@ class ChannelConvolutionTest : public ::testing::TestWithParam<std::tuple<int, i
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
#ifdef CHANNEL_SIM_CUDA
|
||||
#ifdef CUDA_ENABLE
|
||||
gpu_context = cuda_channel_pipeline_init(614400 * 4);
|
||||
#endif
|
||||
tpool = init_tpool(8);
|
||||
@@ -35,7 +35,7 @@ class ChannelConvolutionTest : public ::testing::TestWithParam<std::tuple<int, i
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
#ifdef CHANNEL_SIM_CUDA
|
||||
#ifdef CUDA_ENABLE
|
||||
cuda_channel_pipeline_shutdown(gpu_context);
|
||||
#endif
|
||||
destroy_tpool(tpool);
|
||||
@@ -46,7 +46,7 @@ class ChannelConvolutionTest : public ::testing::TestWithParam<std::tuple<int, i
|
||||
void *tpool = nullptr;
|
||||
};
|
||||
|
||||
#ifdef CHANNEL_SIM_CUDA
|
||||
#ifdef CUDA_ENABLE
|
||||
TEST_P(ChannelConvolutionTest, CompareCpuGpu)
|
||||
{
|
||||
int nb_rx = std::get<0>(GetParam());
|
||||
|
||||
@@ -128,21 +128,25 @@ typedef struct {
|
||||
uint8_t round;
|
||||
bool new_rx;
|
||||
/////////////////////// ulsch decoding ///////////////////////
|
||||
/// flag used to clear d properly
|
||||
/// flag used to clear d properly (together with d_to_be_cleared below)
|
||||
/// set to true in nr_fill_ulsch() when new_data_indicator is received
|
||||
bool harq_to_be_cleared;
|
||||
/// Pointer to the payload (38.212 V15.4.0 section 5.1)
|
||||
uint8_t *b;
|
||||
/// Pointer to aggregated code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
|
||||
uint8_t *c;
|
||||
/// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
|
||||
uint8_t **c;
|
||||
/// Number of bits in each code block (38.212 V15.4.0 section 5.2.2)
|
||||
uint32_t K;
|
||||
/// Number of "Filler" bits added in the code block segmentation (38.212 V15.4.0 section 5.2.2)
|
||||
uint32_t F;
|
||||
/// Number of code blocks after code block segmentation (38.212 V15.4.0 section 5.2.2)
|
||||
uint32_t C;
|
||||
/// Pointers to aggregated code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
|
||||
int16_t *d;
|
||||
/// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
|
||||
int16_t **d;
|
||||
/// flag used to clear d properly (together with harq_to_be_cleared above)
|
||||
/// set to true in nr_ulsch_decoding() when harq_to_be_cleared is true
|
||||
/// when true, clear d in the next call to function nr_rate_matching_ldpc_rx()
|
||||
bool *d_to_be_cleared;
|
||||
/// LDPC lifting size (38.212 V15.4.0 table 5.3.2-1)
|
||||
uint32_t Z;
|
||||
/// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
|
||||
@@ -440,12 +444,10 @@ typedef struct PHY_VARS_gNB_s {
|
||||
time_stats_t dlsch_resource_mapping_stats;
|
||||
time_stats_t dlsch_precoding_stats;
|
||||
time_stats_t tinput;
|
||||
time_stats_t tinput_memcpy;
|
||||
time_stats_t tprep;
|
||||
time_stats_t tparity;
|
||||
time_stats_t toutput;
|
||||
time_stats_t tconcat;
|
||||
|
||||
|
||||
time_stats_t dlsch_rate_matching_stats;
|
||||
time_stats_t dlsch_interleaving_stats;
|
||||
time_stats_t dlsch_segmentation_stats;
|
||||
@@ -460,16 +462,11 @@ typedef struct PHY_VARS_gNB_s {
|
||||
time_stats_t ulsch_decoding_stats;
|
||||
time_stats_t ts_deinterleave;
|
||||
time_stats_t ts_rate_unmatch;
|
||||
time_stats_t ts_seg_prep;
|
||||
time_stats_t ts_ldpc_decode;
|
||||
time_stats_t ulsch_deinterleaving_stats;
|
||||
time_stats_t ulsch_channel_estimation_stats;
|
||||
time_stats_t pusch_channel_estimation_antenna_processing_stats;
|
||||
time_stats_t ulsch_llr_stats;
|
||||
time_stats_t ulsch_layer_demapping_stats;
|
||||
time_stats_t ulsch_unscrambling_stats;
|
||||
time_stats_t pusch_extraction_stats;
|
||||
time_stats_t pusch_channel_compensation_stats;
|
||||
time_stats_t rx_srs_stats;
|
||||
time_stats_t generate_srs_stats;
|
||||
time_stats_t get_srs_signal_stats;
|
||||
@@ -520,7 +517,7 @@ typedef struct LDPCDecode_s {
|
||||
NR_UL_gNB_HARQ_t *ulsch_harq;
|
||||
t_nrLDPC_dec_params decoderParms;
|
||||
NR_gNB_ULSCH_t *ulsch;
|
||||
int16_t *ulsch_llr;
|
||||
short* ulsch_llr;
|
||||
int ulsch_id;
|
||||
int harq_pid;
|
||||
int rv_index;
|
||||
|
||||
@@ -521,9 +521,8 @@ typedef struct nr_phy_data_tx_s {
|
||||
|
||||
typedef struct nr_phy_data_s {
|
||||
NR_UE_PDCCH_CONFIG phy_pdcch_config;
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config;
|
||||
NR_UE_DLSCH_t dlsch[2];
|
||||
int n_dlsch_codewords;
|
||||
|
||||
// Sidelink Rx action decided by MAC
|
||||
sl_nr_rx_config_type_enum_t sl_rx_action;
|
||||
NR_UE_CSI_RS csirs_vars;
|
||||
@@ -536,7 +535,7 @@ enum stream_status_e { STREAM_STATUS_UNSYNC, STREAM_STATUS_SYNCING, STREAM_STATU
|
||||
*/
|
||||
typedef struct nr_rxtx_thread_data_s {
|
||||
UE_nr_rxtx_proc_t proc;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
int writeBlockSize;
|
||||
nr_phy_data_t phy_data;
|
||||
dynamic_barrier_t* next_barrier;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user